import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../core/network/api_client.dart';
import '../../app.dart';
import '../../shared/models/pagination_model.dart';
import '../../shared/models/bill_attachment.dart';
import 'expense_apply_model.dart';

final expenseApplyApiProvider = Provider<ExpenseApplyApi>(
  (ref) => ExpenseApplyApi(ref.read(apiClientProvider)),
);

// ═══ 参考数据模型（API 返回） ═══

class CostTypeItem {
  final String typeNo;
  final String typeName;
  final String accNo;
  final String accName;
  const CostTypeItem({required this.typeNo, required this.typeName, required this.accNo, required this.accName});
  factory CostTypeItem.fromJson(Map<String, dynamic> json) => CostTypeItem(
    typeNo: json['typeNo'] as String? ?? '',
    typeName: json['typeName'] as String? ?? '',
    accNo: json['accNo'] as String? ?? '',
    accName: json['accName'] as String? ?? '',
  );
}

class ProjectCodeItem {
  final String objNo;
  final String name;
  const ProjectCodeItem({required this.objNo, required this.name});
  factory ProjectCodeItem.fromJson(Map<String, dynamic> json) => ProjectCodeItem(
    objNo: json['objNo'] as String? ?? '',
    name: json['name'] as String? ?? '',
  );
}

class DepartmentItem {
  final String dep;
  final String name;
  const DepartmentItem({required this.dep, required this.name});
  factory DepartmentItem.fromJson(Map<String, dynamic> json) => DepartmentItem(
    dep: json['dep'] as String? ?? '',
    name: json['name'] as String? ?? '',
  );
}

class ExpenseApplyApi {
  final ApiClient _client;
  ExpenseApplyApi(this._client);

  /// 费用申请列表（分页）
  Future<PaginatedData<ExpenseApplyModel>> fetchList({
    String status = '',
    String keyword = '',
    String startDate = '',
    String endDate = '',
    String usr = '',
    String sortDir = 'DESC',
    int page = 1,
    int size = 20,
  }) async {
    final response = await _client.get<Map<String, dynamic>>(
      '/OA/GetExpenseApplies',
      queryParameters: {
        'status': status,
        'keyword': keyword,
        'startDate': startDate,
        'endDate': endDate,
        'usr': usr,
        'sortDir': sortDir,
        'page': page,
        'size': size,
      },
    );
    return PaginatedData.fromJson(response.data!, ExpenseApplyModel.fromJson);
  }

  /// 费用申请详情（主表+明细）
  Future<ExpenseApplyModel> fetchDetail(String billNo) async {
    final response = await _client.get<Map<String, dynamic>>(
      '/OA/GetExpenseApplyDetail',
      queryParameters: {'billNo': billNo},
    );
    return ExpenseApplyModel.fromJson(response.data!);
  }

  /// 费用类别字典
  Future<List<CostTypeItem>> getCostTypes({String keyword = '', String accNo = ''}) async {
    final response = await _client.get<Map<String, dynamic>>(
      '/OA/GetCostTypes',
      queryParameters: {'keyword': keyword, 'accNo': accNo, 'page': 1, 'size': 100},
    );
    final list = (response.data?['list'] as List<dynamic>?) ?? [];
    return list.map((e) => CostTypeItem.fromJson(e as Map<String, dynamic>)).toList();
  }

  /// 项目代号
  Future<List<ProjectCodeItem>> getProjectCodes({String keyword = '', String billDate = ''}) async {
    final response = await _client.get<Map<String, dynamic>>(
      '/OA/GetProjectCodes',
      queryParameters: {'keyword': keyword, 'billDate': billDate, 'page': 1, 'size': 100},
    );
    final list = (response.data?['list'] as List<dynamic>?) ?? [];
    return list.map((e) => ProjectCodeItem.fromJson(e as Map<String, dynamic>)).toList();
  }

  /// 部门
  Future<List<DepartmentItem>> getDepartments({String keyword = '', bool onlyActive = true}) async {
    final response = await _client.get<Map<String, dynamic>>(
      '/OA/GetDepartments',
      queryParameters: {'keyword': keyword, 'onlyActive': onlyActive, 'page': 1, 'size': 100},
    );
    final list = (response.data?['list'] as List<dynamic>?) ?? [];
    return list.map((e) => DepartmentItem.fromJson(e as Map<String, dynamic>)).toList();
  }

  /// 提交审批，返回申请单号（提取失败时返回 null，不影响主流程）
  /// BillSave 返回格式: { callok:true, resultData:{ BIL_NO:"AE20267020005", ... } }
  Future<String?> submit(Map<String, dynamic> data) async {
    final response = await _client.post<Map<String, dynamic>>('/OA/BillSave', data: {
      'erpCategory': 'MasterService',
      'billId': 'AE',
      'procId': '',
      'data': data,
    });
    final resData = response.data;
    if (resData == null) return null;

    // 从 resultData 中取（BillSave 实际返回的嵌套格式）
    final resultData = resData['resultData'];
    if (resultData is Map<String, dynamic>) {
      // BIL_NO 是 BillSave 返回的通用单号字段（不区分 AE/BX）
      final bilNo = resultData['BIL_NO'] as String?;
      if (bilNo != null && bilNo.isNotEmpty) return bilNo;
    }
    // resultData 可能是 JSON 字符串
    if (resultData is String && resultData.isNotEmpty) {
      try {
        final parsed = json.decode(resultData) as Map<String, dynamic>;
        final bilNo = parsed['BIL_NO'] as String?;
        if (bilNo != null && bilNo.isNotEmpty) return bilNo;
      } catch (_) {}
    }
    // 兜底: resData 根级 BIL_NO
    final rootBilNo = resData['BIL_NO'] as String?;
    if (rootBilNo != null && rootBilNo.isNotEmpty) return rootBilNo;

    return null;
  }

  /// 检测附件服务是否可用
  Future<bool> checkAttachHealth() async {
    try {
      final response = await _client.get<Map<String, dynamic>>('/OA/CheckAttachHealth');
      return response.data?['available'] as bool? ?? false;
    } catch (_) {
      return false;
    }
  }

  /// 审批进度
  Future<Map<String, dynamic>> fetchApprovalTimeline(String bilId, String bilNo, {int bilItm = 0}) async {
    final response = await _client.get<Map<String, dynamic>>(
      '/OA/GetApprovalTimeline',
      queryParameters: {'bilId': bilId, 'bilNo': bilNo, 'bilItm': bilItm},
    );
    return response.data!;
  }

  /// 获取单据附件列表
  Future<List<BillAttachment>> getAttachments(String bilId, String bilNo, {int? srcItm}) async {
    final params = <String, dynamic>{
      'bilId': bilId,
      'bilNo': bilNo,
    };
    if (srcItm != null) params['srcItm'] = srcItm;
    final response = await _client.get<Map<String, dynamic>>(
      '/OA/GetAttachments',
      queryParameters: params,
    );
    final data = response.data;
    final list = (data?['Result']?['list'] as List<dynamic>?) ??
        (data?['list'] as List<dynamic>?) ??
        [];
    return list.map((e) => BillAttachment.fromJson(e as Map<String, dynamic>)).toList();
  }

  /// 上传附件
  Future<Map<String, dynamic>> uploadAttachment(
    String filePath,
    Map<String, dynamic> metadata,
  ) async {
    final fileName = (metadata['FILENAME'] as String?) ?? filePath.split('/').last;
    final response = await _client.uploadMultipart<Map<String, dynamic>>(
      '/OA/UploadAttachment',
      files: [await MultipartFile.fromFile(filePath, filename: fileName)],
      extraFields: {'metadata': json.encode(metadata)},
    );
    return response.data ?? {};
  }

  /// 审核执行（通过/驳回/反审核）
  Future<Map<String, dynamic>> executeApproval({
    required String bilId, required String bilNo, int bilItm = 0,
    required String action, String rem = '', String effDd = '',
    String reason = '', bool isPreToStart = false, int nodeIndex = -1,
    String dataBx = '',
  }) async {
    final response = await _client.post<Map<String, dynamic>>(
      '/OA/ExecuteApproval',
      data: {
        'bilId': bilId, 'bilNo': bilNo, 'bilItm': bilItm,
        'action': action, 'rem': rem, 'effDd': effDd,
        'reason': reason, 'isPreToStart': isPreToStart,
        'nodeIndex': nodeIndex, 'dataBx': dataBx,
      },
    );
    return response.data!;
  }
}
