import csv
import datetime
from django.http import HttpResponse
from django.utils.encoding import escape_uri_path

def export_to_csv(modeladmin, request, queryset):
    """
    通用导出 CSV 的 Admin Action
    支持中文编码（UTF-8 BOM），可直接用 Excel 打开
    """
    opts = modeladmin.model._meta
    # 设置文件名，使用模型的 verbose_name
    filename = f"{opts.verbose_name}_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
    
    response = HttpResponse(content_type='text/csv; charset=utf-8-sig')
    response['Content-Disposition'] = f'attachment; filename={escape_uri_path(filename)}'
    
    writer = csv.writer(response)
    
    # 获取所有非多对多字段和非反向关联字段
    fields = [field for field in opts.get_fields() if not field.many_to_many and not field.one_to_many]
    
    # 写入表头 (使用字段的 verbose_name)
    writer.writerow([field.verbose_name for field in fields])
    
    # 写入数据
    for obj in queryset:
        data_row = []
        for field in fields:
            value = getattr(obj, field.name)
            
            # 处理 Choice 字段，显示可读的标签
            if hasattr(obj, f'get_{field.name}_display'):
                value = getattr(obj, f'get_{field.name}_display')()
            
            # 处理关联对象（ForeignKey）
            if field.is_relation and value:
                 value = str(value)

            # 处理日期时间
            if isinstance(value, datetime.datetime):
                value = value.strftime('%Y-%m-%d %H:%M:%S')
            elif isinstance(value, datetime.date):
                value = value.strftime('%Y-%m-%d')
            
            # 处理 None
            if value is None:
                value = ""
                
            data_row.append(str(value))
        writer.writerow(data_row)
        
    return response

export_to_csv.short_description = "导出选中项为 CSV"

def export_to_excel(modeladmin, request, queryset):
    """
    导出为 Excel (需要安装 openpyxl)
    """
    try:
        from openpyxl import Workbook
    except ImportError:
        modeladmin.message_user(request, "请先安装 openpyxl 库以使用 Excel 导出功能: pip install openpyxl", level='error')
        return

    opts = modeladmin.model._meta
    filename = f"{opts.verbose_name}_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
    
    response = HttpResponse(
        content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    )
    response['Content-Disposition'] = f'attachment; filename={escape_uri_path(filename)}'
    
    wb = Workbook()
    ws = wb.active
    # Sheet name limit is 31 chars
    ws.title = str(opts.verbose_name)[:31]
    
    fields = [field for field in opts.get_fields() if not field.many_to_many and not field.one_to_many]
    
    # 写入表头
    ws.append([str(field.verbose_name) for field in fields])
    
    # 写入数据
    for obj in queryset:
        row = []
        for field in fields:
            value = getattr(obj, field.name)
            
            if hasattr(obj, f'get_{field.name}_display'):
                value = getattr(obj, f'get_{field.name}_display')()
            
            # 处理关联对象（ForeignKey）
            if field.is_relation and value:
                 value = str(value)

            if isinstance(value, (datetime.datetime, datetime.date)):
                # openpyxl 可以直接处理 datetime 格式，Excel 会自动识别
                # 但为了避免时区问题，通常转为无时区时间或字符串
                if isinstance(value, datetime.datetime):
                     value = value.replace(tzinfo=None)
            
            row.append(value)
        ws.append(row)
        
    wb.save(response)
    return response

export_to_excel.short_description = "导出选中项为 Excel"
