import json

from fastapi import APIRouter, BackgroundTasks, UploadFile, File, Form, HTTPException, Query
from services.token_service import TokenService
from services.file_service import FileService
from services.statement_service import StatementService
from utils.error_simulator import ErrorSimulator
from typing import List, Optional

# 创建路由器
router = APIRouter()

# 初始化服务实例
token_service = TokenService()
file_service = FileService()
statement_service = StatementService(file_service=file_service)


def _parse_log_ids(log_ids: str) -> List[int]:
    """兼容逗号分隔和 JSON 数组两种 logIds 传参格式。"""
    raw_value = log_ids.strip()
    if not raw_value:
        raise HTTPException(status_code=422, detail="logIds 不能为空")

    try:
        if raw_value.startswith("["):
            parsed = json.loads(raw_value)
            if not isinstance(parsed, list):
                raise ValueError
            values = parsed
        else:
            values = [item.strip() for item in raw_value.split(",") if item.strip()]

        if not values:
            raise ValueError

        return [int(item) for item in values]
    except (TypeError, ValueError, json.JSONDecodeError) as exc:
        raise HTTPException(
            status_code=422,
            detail="logIds 必须是逗号分隔的数字字符串或 JSON 数组"
        ) from exc


# ==================== 接口1：获取Token ====================
@router.post("/account/common/getToken")
async def get_token(
    projectNo: str = Form(..., description="项目编号，格式：902000_当前时间戳"),
    entityName: str = Form(..., description="项目名称"),
    userId: str = Form(..., description="操作人员编号，固定值"),
    userName: str = Form(..., description="操作人员姓名，固定值"),
    appId: str = Form("remote_app", description="应用ID，固定值"),
    appSecretCode: str = Form(..., description="安全码"),
    role: str = Form("VIEWER", description="角色，固定值"),
    orgCode: str = Form(..., description="行社机构号，固定值"),
    entityId: Optional[str] = Form(None, description="企业统信码或个人身份证号"),
    xdRelatedPersons: Optional[str] = Form(None, description="信贷关联人信息"),
    jzDataDateId: str = Form("0", description="拉取指定日期推送过来的金综链流水"),
    innerBSStartDateId: str = Form("0", description="拉取行内流水开始日期"),
    innerBSEndDateId: str = Form("0", description="拉取行内流水结束日期"),
    analysisType: str = Form("-1", description="分析类型，固定值"),
    departmentCode: str = Form(..., description="客户经理所属营业部/分理处的机构编码"),
):
    """创建项目并获取访问Token

    如果 projectNo 包含 error_XXXX 标记，将返回对应的错误响应
    """
    # 检测错误标记
    error_code = ErrorSimulator.detect_error_marker(projectNo)
    if error_code:
        return ErrorSimulator.build_error_response(error_code)

    # 构建请求数据字典
    request_data = {
        "projectNo": projectNo,
        "entityName": entityName,
        "userId": userId,
        "userName": userName,
        "appId": appId,
        "appSecretCode": appSecretCode,
        "role": role,
        "orgCode": orgCode,
        "entityId": entityId,
        "xdRelatedPersons": xdRelatedPersons,
        "jzDataDateId": jzDataDateId,
        "innerBSStartDateId": innerBSStartDateId,
        "innerBSEndDateId": innerBSEndDateId,
        "analysisType": analysisType,
        "departmentCode": departmentCode,
    }

    # 正常流程
    return token_service.create_token(request_data)


# ==================== 接口2：上传文件 ====================
@router.post("/watson/api/project/remoteUploadSplitFile")
async def upload_file(
    background_tasks: BackgroundTasks,
    groupId: int = Form(..., description="项目ID"),
    files: UploadFile = File(..., description="流水文件"),
):
    """上传流水文件

    文件将立即返回，并在后台延迟4秒完成解析
    """
    return await file_service.upload_file(groupId, files, background_tasks)


# ==================== 接口3：拉取行内流水 ====================
@router.post("/watson/api/project/getJZFileOrZjrcuFile")
async def fetch_inner_flow(
    groupId: int = Form(..., description="项目id"),
    customerNo: str = Form(..., description="客户身份证号"),
    dataChannelCode: str = Form(..., description="校验码"),
    requestDateId: int = Form(..., description="发起请求的时间"),
    dataStartDateId: int = Form(..., description="拉取开始日期"),
    dataEndDateId: int = Form(..., description="拉取结束日期"),
    uploadUserId: int = Form(..., description="柜员号"),
):
    """拉取行内流水

    如果 customerNo 包含 error_XXXX 标记，将返回对应的错误响应
    """
    # 检测错误标记
    error_code = ErrorSimulator.detect_error_marker(customerNo)
    if error_code:
        return ErrorSimulator.build_error_response(error_code)

    # 构建请求字典
    request_data = {
        "groupId": groupId,
        "customerNo": customerNo,
        "dataChannelCode": dataChannelCode,
        "requestDateId": requestDateId,
        "dataStartDateId": dataStartDateId,
        "dataEndDateId": dataEndDateId,
        "uploadUserId": uploadUserId,
    }

    # 正常流程
    return file_service.fetch_inner_flow(request_data)


# ==================== 接口4：检查文件解析状态 ====================
@router.post("/watson/api/project/upload/getpendings")
async def check_parse_status(
    groupId: int = Form(..., description="项目id"),
    inprogressList: str = Form(..., description="文件id列表，逗号分隔"),
):
    """检查文件解析状态

    返回文件是否还在解析中（parsing字段）
    """
    return file_service.check_parse_status(groupId, inprogressList)


# ==================== 接口5：获取文件上传状态 ====================
@router.get("/watson/api/project/bs/upload")
async def get_upload_status(
    groupId: int = Query(..., description="项目id"),
    logId: Optional[int] = Query(None, description="文件id"),
):
    """获取单个文件上传后的状态

    如果不提供 logId，返回该项目的所有文件状态
    """
    return file_service.get_upload_status(groupId, logId)


# ==================== 接口6：删除文件 ====================
@router.post("/watson/api/project/batchDeleteUploadFile")
async def delete_files(
    groupId: int = Form(..., description="项目id"),
    logIds: str = Form(..., description="文件id数组，支持 10001,10002 或 [10001,10002]"),
    userId: int = Form(..., description="用户柜员号"),
):
    """批量删除上传的文件

    根据logIds列表删除对应的文件记录
    """
    log_id_list = _parse_log_ids(logIds)
    return file_service.delete_files(groupId, log_id_list, userId)


# ==================== 接口6：获取银行流水 ====================
@router.post("/watson/api/project/getBSByLogId")
async def get_bank_statement(
    groupId: int = Form(..., description="项目id"),
    logId: int = Form(..., description="文件id"),
    pageNow: int = Form(..., description="当前页码"),
    pageSize: int = Form(..., description="查询条数"),
):
    """获取银行流水列表

    支持分页查询（pageNow, pageSize）
    """
    # 构建请求字典
    request_data = {
        "groupId": groupId,
        "logId": logId,
        "pageNow": pageNow,
        "pageSize": pageSize,
    }
    return statement_service.get_bank_statement(request_data)
