# -*- coding: utf-8 -*-

import io
from fastapi import UploadFile
import pandas as pd

from app.core.base_schema import BatchSetAvailable
from app.core.exceptions import CustomException
from app.utils.excel_util import ExcelUtil
from app.core.logger import log
from app.api.v1.module_system.auth.schema import AuthSchema
from .schema import {{ class_name }}CreateSchema, {{ class_name }}UpdateSchema, {{ class_name }}OutSchema, {{ class_name }}QueryParam
from .crud import {{ class_name }}CRUD


class {{ class_name }}Service:
    """
    {{ function_name }}服务层
    """
    
    @classmethod
    async def detail_{{ business_name }}_service(cls, auth: AuthSchema, id: int) -> dict:
        """详情"""
        obj = await {{ class_name }}CRUD(auth).get_by_id_{{ business_name }}_crud(id=id)
        if not obj:
            raise CustomException(msg="该数据不存在")
        return {{ class_name }}OutSchema.model_validate(obj).model_dump()
    
    @classmethod
    async def list_{{ business_name }}_service(cls, auth: AuthSchema, search: {{ class_name }}QueryParam | None = None, order_by: list[dict] | None = None) -> list[dict]:
        """列表查询"""
        search_dict = search.__dict__ if search else None
        obj_list = await {{ class_name }}CRUD(auth).list_{{ business_name }}_crud(search=search_dict, order_by=order_by)
        return [{{ class_name }}OutSchema.model_validate(obj).model_dump() for obj in obj_list]

    @classmethod
    async def page_{{ business_name }}_service(cls, auth: AuthSchema, page_no: int, page_size: int, search: {{ class_name }}QueryParam | None = None, order_by: list[dict] | None = None) -> dict:
        """分页查询（数据库分页）"""
        search_dict = search.__dict__ if search else {}
        order_by_list = order_by or [{'id': 'asc'}]
        offset = (page_no - 1) * page_size
        result = await {{ class_name }}CRUD(auth).page_{{ business_name }}_crud(
            offset=offset,
            limit=page_size,
            order_by=order_by_list,
            search=search_dict
        )
        return result
    
    @classmethod
    async def create_{{ business_name }}_service(cls, auth: AuthSchema, data: {{ class_name }}CreateSchema) -> dict:
        """创建"""
        # 检查唯一性约束
        {% for column in columns %}
        {% if column.is_unique == '1' %}
        obj = await {{ class_name }}CRUD(auth).get({{ column.column_name }}=data.{{ column.column_name }})
        if obj:
            raise CustomException(msg='创建失败，{{ column.column_comment }}已存在')
        {% endif %}
        {% endfor %}
        obj = await {{ class_name }}CRUD(auth).create_{{ business_name }}_crud(data=data)
        return {{ class_name }}OutSchema.model_validate(obj).model_dump()
    
    @classmethod
    async def update_{{ business_name }}_service(cls, auth: AuthSchema, id: int, data: {{ class_name }}UpdateSchema) -> dict:
        """更新"""
        # 检查数据是否存在
        obj = await {{ class_name }}CRUD(auth).get_by_id_{{ business_name }}_crud(id=id)
        if not obj:
            raise CustomException(msg='更新失败，该数据不存在')
        
        # 检查唯一性约束
        {% for column in columns %}
        {% if column.is_unique == '1' %}
        exist_obj = await {{ class_name }}CRUD(auth).get({{ column.column_name }}=data.{{ column.column_name }})
        if exist_obj and exist_obj.id != id:
            raise CustomException(msg='更新失败，{{ column.column_comment }}重复')
        {% endif %}
        {% endfor %}
            
        obj = await {{ class_name }}CRUD(auth).update_{{ business_name }}_crud(id=id, data=data)
        return {{ class_name }}OutSchema.model_validate(obj).model_dump()
    
    @classmethod
    async def delete_{{ business_name }}_service(cls, auth: AuthSchema, ids: list[int]) -> None:
        """删除"""
        if len(ids) < 1:
            raise CustomException(msg='删除失败，删除对象不能为空')
        for id in ids:
            obj = await {{ class_name }}CRUD(auth).get_by_id_{{ business_name }}_crud(id=id)
            if not obj:
                raise CustomException(msg=f'删除失败，ID为{id}的数据不存在')
        await {{ class_name }}CRUD(auth).delete_{{ business_name }}_crud(ids=ids)
    
    @classmethod
    async def set_available_{{ business_name }}_service(cls, auth: AuthSchema, data: BatchSetAvailable) -> None:
        """批量设置状态"""
        await {{ class_name }}CRUD(auth).set_available_{{ business_name }}_crud(ids=data.ids, status=data.status)
    
    @classmethod
    async def batch_export_{{ business_name }}_service(cls, obj_list: list[dict]) -> bytes:
        """批量导出"""
        mapping_dict = {
            {% for column in columns %}
            '{{ column.column_name }}': '{{ column.column_comment }}',
            {% endfor %}
            'updated_id': '更新者ID',
        }

        data = obj_list.copy()
        for item in data:
            # 状态转换
            if 'status' in item:
                item['status'] = '启用' if item.get('status') == '0' else '停用'
            # 创建者转换
            creator_info = item.get('creator')
            if isinstance(creator_info, dict):
                item['creator'] = creator_info.get('name', '未知')
            elif creator_info is None:
                item['creator'] = '未知'

        return ExcelUtil.export_list2excel(list_data=data, mapping_dict=mapping_dict)

    @classmethod
    async def batch_import_{{ business_name }}_service(cls, auth: AuthSchema, file: UploadFile, update_support: bool = False) -> str:
        """批量导入"""
        header_dict = {
            {% for column in columns %}
            '{{ column.column_comment }}': '{{ column.column_name }}',
            {% endfor %}
        }

        try:
            contents = await file.read()
            df = pd.read_excel(io.BytesIO(contents))
            await file.close()
            
            if df.empty:
                raise CustomException(msg="导入文件为空")
            
            missing_headers = [header for header in header_dict.keys() if header not in df.columns]
            if missing_headers:
                raise CustomException(msg=f"导入文件缺少必要的列: {', '.join(missing_headers)}")
            
            df.rename(columns=header_dict, inplace=True)
            
            # 验证必填字段
            {% for column in columns %}
            {% if column.required == '1' %}
            errors = []
            missing_rows = df[df['{{ column.column_name }}'].isnull()].index.tolist()
            if missing_rows:
                field_name = [k for k,v in header_dict.items() if v == field][0]
                rows_str = "、".join([str(i+1) for i in missing_rows])
                errors.append(f"{field_name}不能为空，第{rows_str}行")
            if errors:
                raise CustomException(msg=f"导入失败，以下行缺少必要字段：\n{'; '.join(errors)}")
            {% endif %}
            {% endfor %}
            
            error_msgs = []
            success_count = 0
            count = 0
            
            for index, row in df.iterrows():
                count += 1
                try:
                    data = {
                        {% for column in columns %}
                        "{{ column.column_name }}": row['{{ column.column_name }}'],
                        {% endfor %}
                    }
                    # 使用CreateSchema做校验后入库
                    create_schema = {{ class_name }}CreateSchema.model_validate(data)
                    
                    # 检查唯一性约束
                    {% for column in columns %}
                    {% if column.is_unique == '1' %}
                    exists_obj = await {{ class_name }}CRUD(auth).get({{ column.column_name }}=create_schema.{{ column.column_name }})
                    if exists_obj:
                        if update_support:
                            await {{ class_name }}CRUD(auth).update(id=exists_obj.id, data=create_schema)
                            success_count += 1
                        else:
                            error_msgs.append(f"第{count}行: {{ column.column_comment }} {create_schema.{{ column.column_name }}} 已存在")
                        continue
                    {% endif %}
                    {% endfor %}
                    
                    await {{ class_name }}CRUD(auth).create_{{ business_name }}_crud(data=create_schema)
                    success_count += 1
                except Exception as e:
                    error_msgs.append(f"第{count}行: {str(e)}")
                    continue

            result = f"成功导入 {success_count} 条数据"
            if error_msgs:
                result += "\n错误信息:\n" + "\n".join(error_msgs)
            return result
            
        except Exception as e:
            log.error(f"批量导入失败: {str(e)}")
            raise CustomException(msg=f"导入失败: {str(e)}")
    
    @classmethod
    async def import_template_download_{{ business_name }}_service(cls) -> bytes:
        """下载导入模板"""
        header_list = [
            {% for column in columns %}
            '{{ column.column_comment }}',
            {% endfor %}
        ]
        selector_header_list = []
        option_list = []
        
        # 添加下拉选项
        {% for column in columns %}
        {% if column.html_type == 'select' and column.dict_type %}
        selector_header_list.append('{{ column.column_comment }}')
        option_list.append({'{{ column.column_comment }}': []})
        {% endif %}
        {% endfor %}
        
        return ExcelUtil.get_excel_template(
            header_list=header_list,
            selector_header_list=selector_header_list,
            option_list=option_list
        )