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

def flatten_json(y):
    """
    Flatten a nested json object
    """
    out = {}

    def flatten(x, name=''):
        if type(x) is dict:
            for a in x:
                flatten(x[a], name + a + '_')
        elif type(x) is list:
            i = 0
            for a in x:
                flatten(a, name + str(i) + '_')
                i += 1
        else:
            out[name[:-1]] = x

    flatten(y)
    return out

def get_signup_info_keys(queryset):
    """
    Collect all unique keys from the signup_info JSON across the queryset
    """
    keys = set()
    for obj in queryset:
        if obj.signup_info and isinstance(obj.signup_info, dict):
            # Flatten the dictionary first to get all nested keys
            flat_info = flatten_json(obj.signup_info)
            keys.update(flat_info.keys())
    return sorted(list(keys))

def export_signups_csv(modeladmin, request, queryset):
    """
    Export selected signups to CSV, including flattened JSON fields
    """
    opts = modeladmin.model._meta
    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)
    
    # Base fields to export
    base_headers = ['ID', '活动标题', '用户昵称', '用户ID', '报名时间', '状态', '关联订单ID']
    
    # Get dynamic JSON keys
    json_keys = get_signup_info_keys(queryset)
    
    # Write header
    writer.writerow(base_headers + json_keys)
    
    # Write data
    for obj in queryset:
        row = [
            str(obj.id),
            obj.activity.title,
            obj.user.nickname if obj.user else 'Unknown',
            str(obj.user.id) if obj.user else '',
            obj.signup_time.strftime('%Y-%m-%d %H:%M:%S'),
            obj.get_status_display(),
            str(obj.order.id) if obj.order else ''
        ]
        
        # Add JSON data
        flat_info = {}
        if obj.signup_info and isinstance(obj.signup_info, dict):
            flat_info = flatten_json(obj.signup_info)
            
        for key in json_keys:
            val = flat_info.get(key, '')
            if val is None:
                val = ''
            row.append(str(val))
            
        writer.writerow(row)
        
    return response

export_signups_csv.short_description = "导出选中报名记录为 CSV (含详细信息)"

def export_signups_excel(modeladmin, request, queryset):
    """
    Export selected signups to Excel, including flattened JSON fields
    """
    try:
        from openpyxl import Workbook
    except ImportError:
        modeladmin.message_user(request, "请先安装 openpyxl 库以使用 Excel 导出功能", 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
    ws.title = str(opts.verbose_name)[:31]  # Sheet name limit is 31 chars
    
    # Base fields to export
    base_headers = ['ID', '活动标题', '用户昵称', '用户ID', '报名时间', '状态', '关联订单ID']
    
    # Get dynamic JSON keys
    json_keys = get_signup_info_keys(queryset)
    
    # Write header
    ws.append(base_headers + json_keys)
    
    # Write data
    for obj in queryset:
        row = [
            obj.id,
            obj.activity.title,
            obj.user.nickname if obj.user else 'Unknown',
            obj.user.id if obj.user else '',
            obj.signup_time.replace(tzinfo=None) if obj.signup_time else '', # Remove tz for Excel
            obj.get_status_display(),
            obj.order.id if obj.order else ''
        ]
        
        # Add JSON data
        flat_info = {}
        if obj.signup_info and isinstance(obj.signup_info, dict):
            flat_info = flatten_json(obj.signup_info)
            
        for key in json_keys:
            val = flat_info.get(key, '')
            if val is None:
                val = ''
            row.append(str(val)) # Ensure string for simplicity, or handle types
            
        ws.append(row)
        
    wb.save(response)
    return response

export_signups_excel.short_description = "导出选中报名记录为 Excel (含详细信息)"
