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_model.dart';

final overtimeApiProvider = Provider<OvertimeApi>(
  (ref) => OvertimeApi(ref.read(apiClientProvider)),
);

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

  OvertimeApi(this._client);

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

  /// 加班申请列表（分页）
  Future<PaginatedData<OvertimeModel>> 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!, OvertimeModel.fromJson);
  }

  /// 加班申请详情（主表+明细）
  Future<OvertimeModel> fetchDetail(String billNo) async {
    final response = await _client.get<Map<String, dynamic>>(
      '/OA/GetOTApplyDetail',
      queryParameters: {'billNo': billNo},
    );
    return OvertimeModel.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': 'OT',
        '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<Map<String, dynamic>> getBillStatus(String billNo) async {
    final response = await _client.get<Map<String, dynamic>>(
      '/OA/GetBillStatus',
      queryParameters: {'billId': 'OT', 'billNo': billNo},
    );
    return response.data!;
  }
}
