import 'dart:convert';

import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../../app.dart';
import '../../core/data/api_cache.dart';
import '../../core/navigation/host_app_channel.dart';
import '../../core/network/api_client.dart';
import '../../shared/models/pagination_model.dart';
import '../expense_apply/expense_apply_api.dart';
import 'overtime_apply_model.dart';
import 'ot_report_model.dart';

final overtimeApplyApiProvider = Provider<OvertimeApplyApi>(
  (ref) => OvertimeApplyApi(ref.read(apiClientProvider)),
);

class OvertimeApplyApi {
  final ApiClient _client;
  final _cache = ApiCache(
    keyPrefix:
        '${HostAppChannel.sn}_${HostAppChannel.compNo}_${HostAppChannel.usr}',
  );

  OvertimeApplyApi(this._client);

  /// 清除所有基础资料缓存（picker 下拉刷新时调用）。
  void clearRefCache() => _cache.clear();

  /// 加班申请列表（分页）
  Future<PaginatedData<OvertimeApplyModel>> 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/GetOTApplyList',
      queryParameters: {
        'status': status,
        'keyword': keyword,
        'startDate': startDate,
        'endDate': endDate,
        'usr': usr,
        'sortDir': sortDir,
        'page': page,
        'size': size,
      },
    );
    return PaginatedData.fromJson(response.data!, OvertimeApplyModel.fromJson);
  }

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

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

  /// 员工查询
  Future<List<EmployeeItem>> getEmployees({
    String keyword = '',
    String salNo = '',
    int page = 1,
    int size = 100,
  }) async {
    final cacheKey = 'getEmployees_${keyword}_${salNo}_$page';
    return _cache.getOrFetch(cacheKey, () async {
      final response = await _client.get<Map<String, dynamic>>(
        '/OA/GetEmployees',
        queryParameters: {
          'keyword': keyword,
          'salNo': salNo,
          'page': page,
          'size': size,
        },
      );
      final list = (response.data?['list'] as List<dynamic>?) ?? [];
      return list
          .map((e) => EmployeeItem.fromJson(e as Map<String, dynamic>))
          .toList();
    });
  }

  /// 提交审批，返回申请单号（提取失败时返回 null）
  Future<String?> submit(Map<String, dynamic> data) async {
    final response = await _client.post<Map<String, dynamic>>(
      '/OA/BillSave',
      data: {
        'erpCategory': 'MasterService',
        'billId': 'JB',
        'procId': '',
        'data': data,
      },
    );
    final resData = response.data;
    if (resData == null) return null;

    // 从 resultData 中取
    final resultData = resData['resultData'];
    if (resultData is Map<String, dynamic>) {
      final bilNo = resultData['BIL_NO'] as String?;
      if (bilNo != null && bilNo.isNotEmpty) return bilNo;
    }
    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 (_) {}
    }
    // 兜底
    final rootBilNo = resData['BIL_NO'] as String?;
    if (rootBilNo != null && rootBilNo.isNotEmpty) return rootBilNo;

    return null;
  }

  /// 提交审核流
  Future<bool> shSubmit({
    required String bilNo,
    required String bilDd,
    String dep = '',
    String rem = '',
    String usr = '',
    bool isCancel = false,
  }) async {
    try {
      final response = await _client.post<Map<String, dynamic>>(
        '/OA/SHSubmit',
        data: {
          'erpCategory': 'MasterService',
          'bilId': 'JB',
          'bilNo': bilNo,
          'bilDd': bilDd,
          'dep': dep,
          'rem': rem,
          'usr': usr,
          'isCancel': isCancel,
        },
      );
      return response.data?['code'] == 0;
    } catch (_) {
      return false;
    }
  }

  /// 获取单据状态
  Future<Map<String, dynamic>> getBillStatus(String billNo) async {
    final response = await _client.get<Map<String, dynamic>>(
      '/OA/GetBillStatus',
      queryParameters: {'billId': 'JB', 'billNo': billNo},
    );
    return response.data!;
  }

  /// 加班报表汇总+月度数据
  Future<OTReportData> getOTReport({
    String startDate = '',
    String endDate = '',
  }) async {
    final response = await _client.get<Map<String, dynamic>>(
      '/OA/GetOTReport',
      queryParameters: {
        if (startDate.isNotEmpty) 'startDate': startDate,
        if (endDate.isNotEmpty) 'endDate': endDate,
      },
    );
    return OTReportData.fromJson(response.data!);
  }

  /// 加班报表下属对比
  Future<List<OTSubordinateItem>> getOTSubordinateReport({
    String startDate = '',
    String endDate = '',
  }) async {
    final response = await _client.get<dynamic>(
      '/OA/GetOTSubordinateReport',
      queryParameters: {
        if (startDate.isNotEmpty) 'startDate': startDate,
        if (endDate.isNotEmpty) 'endDate': endDate,
      },
    );
    final list =
        (response.data as List<dynamic>?)
            ?.map((e) => OTSubordinateItem.fromJson(e as Map<String, dynamic>))
            .toList() ??
        [];
    return list;
  }

  /// 加班报表明细（分页）
  Future<Map<String, dynamic>> getOTReportDetail({
    String startDate = '',
    String endDate = '',
    int page = 1,
    int size = 20,
  }) async {
    final response = await _client.get<Map<String, dynamic>>(
      '/OA/GetOTReportDetail',
      queryParameters: {
        if (startDate.isNotEmpty) 'startDate': startDate,
        if (endDate.isNotEmpty) 'endDate': endDate,
        'page': page,
        'size': size,
      },
    );
    return response.data!;
  }

  /// 加班报表表身明细（分页）
  Future<Map<String, dynamic>> getOTBodyReport({
    String startDate = '',
    String endDate = '',
    int page = 1,
    int size = 20,
  }) async {
    final response = await _client.get<Map<String, dynamic>>(
      '/OA/GetOTBodyReport',
      queryParameters: {
        if (startDate.isNotEmpty) 'startDate': startDate,
        if (endDate.isNotEmpty) 'endDate': endDate,
        'page': page,
        'size': size,
      },
    );
    return response.data!;
  }
}
