# Copyright (c) 2025, JINGROW and contributors
# For license information, please see license.txt

"""
提供对云端数据库的增删改查操作，并支持本地钩子函数
"""

from fastapi import APIRouter, HTTPException, Request, Depends
from fastapi.responses import JSONResponse
from typing import Dict, List, Any, Optional
import logging
import json
import jingrow
import requests
from jingrow.config import Config
from jingrow.utils.auth import get_jingrow_api_headers
from jingrow.services.queue import init_queue
from jingrow.services.local_job_manager import local_job_manager
from jingrow.services.hook_executor import create_hook_task, execute_hook_sync
from jingrow.utils.jingrow_api import get_record_list, get_record, create_record, update_record, delete_record, get_single_pagetype
import uuid

logger = logging.getLogger(__name__)

router = APIRouter()

# 初始化队列
init_queue()


def execute_hooks(pagetype: str, name: str, hook_name: str, data: Dict[str, Any] = None):
    """执行钩子函数"""
    return execute_hook_sync(pagetype, name, hook_name, data)

def execute_hooks_async(pagetype: str, name: str, hook_name: str, data: Dict[str, Any] = None):
    """异步执行钩子函数"""
    return create_hook_task(pagetype, name, hook_name, data)


@router.get("/api/data/{pagetype}")
async def get_records(
    request: Request,
    pagetype: str,
    fields: Optional[str] = None,
    filters: Optional[str] = None,
    order_by: str = "modified desc",
    limit_start: int = 0,
    limit_page_length: int = 20
):
    """获取记录列表"""
    try:
        fields_list = json.loads(fields) if fields else []
        filters_list = json.loads(filters) if filters else []
        
        if limit_page_length == 0:
            limit = None
        else:
            limit = limit_start + limit_page_length
        
        result = get_record_list(
            pagetype=pagetype,
            filters=filters_list,
            fields=fields_list,
            limit=limit
        )
        
        if result.get('success'):
            data = result.get('data', [])
            
            if limit_page_length > 0:
                if limit_start > 0:
                    data = data[limit_start:]
                data = data[:limit_page_length]
            
            estimated_total = limit_start + len(data)
            if limit_page_length > 0 and len(data) < limit_page_length:
                estimated_total = limit_start + len(data)
            elif limit_page_length > 0:
                estimated_total = limit_start + limit_page_length + 1
                
            return JSONResponse(content={
                "data": data,
                "total": estimated_total
            })
        else:
            raise HTTPException(status_code=400, detail=result.get('error', '获取记录列表失败'))
            
    except Exception as e:
        logger.error(f"获取记录列表失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@router.get("/api/data/{pagetype}/{name}")
async def get_record_api(request: Request, pagetype: str, name: str):
    """获取单个记录"""
    try:
        result = get_record(pagetype, name)
        
        if result.get('success'):
            return JSONResponse(content={"data": result.get('data')})
        else:
            raise HTTPException(status_code=404, detail=result.get('error', '记录不存在'))
            
    except Exception as e:
        logger.error(f"获取记录失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@router.post("/api/data/{pagetype}")
async def create_record_api(request: Request, pagetype: str, data: Dict[str, Any]):
    """创建记录"""
    try:
        result = create_record(pagetype, data)
        
        if not result.get('success'):
            error_msg = result.get('error', '创建记录失败')
            logger.error(f"创建记录失败: {error_msg}")
            raise HTTPException(status_code=400, detail=error_msg)
        
        created_data = result.get('data', {})
        record_name = created_data.get('name') or data.get('name')
        
        if record_name:
            try:
                execute_hooks_async(pagetype, record_name, "after_insert", created_data)
            except Exception as hook_error:
                logger.error(f"执行钩子函数失败: {hook_error}")
        
        return JSONResponse(content={
            "message": "Created successfully",
            "data": created_data
        })
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"创建记录失败: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=str(e))

@router.put("/api/data/{pagetype}/{name}")
async def update_record_api(request: Request, pagetype: str, name: str, data: Dict[str, Any]):
    """更新记录"""
    try:
        execute_hooks(pagetype, name, "before_save", data)
        
        result = update_record(pagetype, name, data)
        
        if not result.get('success'):
            raise HTTPException(status_code=400, detail=result.get('error', '更新记录失败'))
        
        execute_hooks_async(pagetype, name, "on_update", data)
        
        return JSONResponse(content={
            "message": "Updated successfully",
            "data": result.get('data', {})
        })
        
    except Exception as e:
        logger.error(f"更新记录失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@router.delete("/api/data/{pagetype}/{name}")
async def delete_record_api(request: Request, pagetype: str, name: str):
    """删除记录"""
    try:
        execute_hooks(pagetype, name, "on_trash")
        
        result = delete_record(pagetype, name)
        
        if not result.get('success'):
            raise HTTPException(status_code=400, detail=result.get('error', '删除记录失败'))
        
        return JSONResponse(content={
            "message": "Deleted successfully"
        })
        
    except Exception as e:
        logger.error(f"删除记录失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@router.post("/api/action/jingrow.client.delete")
async def batch_delete_records(request: Request, data: Dict[str, Any]):
    """批量删除记录"""
    try:
        pagetype = data.get('pagetype')
        name = data.get('name')
        
        if not pagetype or not name:
            raise HTTPException(status_code=400, detail="缺少必要参数")
        
        return await delete_record_api(request, pagetype, name)
        
    except Exception as e:
        logger.error(f"批量删除记录失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@router.post("/api/action/jingrow.client.get_count")
async def get_record_count(request: Request, pagetype: str):
    """获取记录总数（估算）"""
    try:
        # 获取少量数据来估算总数
        result = get_record_list(pagetype=pagetype, limit=100)
        
        if result.get('success'):
            data = result.get('data', [])
            # 如果返回的数据少于100条，说明总数就是实际数量
            if len(data) < 100:
                estimated_count = len(data)
            else:
                # 如果返回了100条，可能还有更多，返回一个估算值
                estimated_count = len(data) + 1
                
            return JSONResponse(content={"message": estimated_count})
        else:
            raise HTTPException(status_code=400, detail=result.get('error', '获取记录总数失败'))
            
    except Exception as e:
        logger.error(f"获取记录总数失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/api/single/{pagetype}")
async def get_single(request: Request, pagetype: str):
    """获取single类型pagetype记录"""
    try:
        result = get_single_pagetype(pagetype)
        
        if result.get('success'):
            return JSONResponse(content={"data": result.get('config', {})})
        else:
            raise HTTPException(status_code=404, detail=result.get('error', '配置不存在'))
            
    except Exception as e:
        logger.error(f"获取single配置失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@router.post("/api/hooks/execute")
async def execute_hook_task(request: Request, data: Dict[str, Any]):
    """执行钩子任务"""
    try:
        pagetype = data.get('pagetype')
        name = data.get('name')
        hook_name = data.get('hook_name')
        
        if not all([pagetype, name, hook_name]):
            raise HTTPException(status_code=400, detail="缺少必要参数")
        
        success = execute_hooks(pagetype, name, hook_name, data.get('data'))
        
        return JSONResponse(content={
            "success": success,
            "message": f"钩子 {hook_name} 执行{'成功' if success else '失败'}"
        })
        
    except Exception as e:
        logger.error(f"执行钩子任务失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))
