import '../../shared/models/approval_status.dart';

/// 费用申请主表，对应 [ExpenseApply] 表。
class ExpenseApplyModel {
  final String id;
  final String expenseApplyNo;
  final DateTime? expenseApplyDate;
  final String applicantId;
  final String applicantName;
  final String deptId;
  final String deptName;
  final double estimatedAmount;
  final String urgency;
  final String purpose;
  final String remark;
  final DateTime? effectiveDate;
  final String auditorId;
  final String status;
  final String usageStatus;
  final DateTime? validUntil;
  final String referenceNo;
  final String approvalInstanceId;
  final String previousInstanceIds;
  final int version;
  final DateTime createTime;
  final DateTime updateTime;
  final bool isDeleted;
  final int isTransferred;
  final bool isAuditApproved;

  // ── 瞬态字段（API 从 ERP 实时查询，非存储） ──
  final String currentApproverId;
  final List<String> approvalChain;
  final List<ApprovalRecord> approvalRecords;

  // ── 子表 ──
  final List<ExpenseApplyDetailModel> details;
  final List<String> attachments;

  const ExpenseApplyModel({
    required this.id,
    required this.expenseApplyNo,
    this.expenseApplyDate,
    this.applicantId = '',
    this.applicantName = '',
    this.deptId = '',
    this.deptName = '',
    this.estimatedAmount = 0.0,
    this.urgency = 'normal',
    this.purpose = '',
    this.remark = '',
    this.effectiveDate,
    this.auditorId = '',
    this.status = 'draft',
    this.usageStatus = 'unused',
    this.validUntil,
    this.referenceNo = '',
    this.approvalInstanceId = '',
    this.previousInstanceIds = '',
    this.version = 1,
    required this.createTime,
    required this.updateTime,
    this.isDeleted = false,
    this.isTransferred = 0,
    this.isAuditApproved = false,
    this.currentApproverId = '',
    this.approvalChain = const [],
    this.approvalRecords = const [],
    this.details = const [],
    this.attachments = const [],
  });

  factory ExpenseApplyModel.fromJson(Map<String, dynamic> json) {
    return ExpenseApplyModel(
      id: json['id'] as String? ?? '',
      expenseApplyNo: json['applyNo'] as String? ?? '',
      expenseApplyDate: json['applyDate'] != null
          ? DateTime.parse(json['applyDate'] as String)
          : null,
      applicantId: json['usr'] as String? ?? '',
      applicantName: json['applicantName'] as String? ?? json['usr'] as String? ?? '',
      deptId: json['dept'] as String? ?? '',
      deptName: json['deptName'] as String? ?? json['dep'] as String? ?? '',
      estimatedAmount: (json['estimatedAmount'] as num?)?.toDouble() ?? 0.0,
      urgency: json['urgency'] as String? ?? json['priority'] as String? ?? 'normal',
      purpose: json['reason'] as String? ?? json['purpose'] as String? ?? '',
      remark: json['rem'] as String? ?? '',
      effectiveDate: json['effDd'] != null
          ? DateTime.parse(json['effDd'] as String)
          : null,
      auditorId: json['chkMan'] as String? ?? '',
      status: json['clsDate'] != null ? 'closed' : (json['status'] as String? ?? 'draft'),
      usageStatus: json['usageStatus'] as String? ?? 'unused',
      validUntil: json['validUntil'] != null
          ? DateTime.parse(json['validUntil'] as String)
          : null,
      referenceNo: json['referenceNo'] as String? ?? '',
      approvalInstanceId: json['approvalInstanceId'] as String? ?? '',
      previousInstanceIds: json['previousInstanceIds'] as String? ?? '',
      version: json['version'] as int? ?? 1,
      createTime: json['createTime'] != null
          ? DateTime.parse(json['createTime'] as String)
          : DateTime.now(),
      updateTime: json['updateTime'] != null
          ? DateTime.parse(json['updateTime'] as String)
          : DateTime.now(),
      isDeleted: json['isDeleted'] as bool? ?? false,
      isTransferred: json['isTransferred'] as int? ?? 0,
      isAuditApproved: (json['isAuditApproved'] as int?) == 1,
      currentApproverId: json['currentApproverId'] as String? ?? '',
      approvalChain:
          (json['approvalChain'] as List<dynamic>?)
              ?.map((e) => e as String)
              .toList() ??
          [],
      approvalRecords:
          (json['approvalRecords'] as List<dynamic>?)
              ?.map((e) => ApprovalRecord.fromJson(e as Map<String, dynamic>))
              .toList() ??
          [],
      details:
          (json['details'] as List<dynamic>?)
              ?.map(
                (e) =>
                    ExpenseApplyDetailModel.fromJson(e as Map<String, dynamic>),
              )
              .toList() ??
          [],
      attachments:
          (json['attachments'] as List<dynamic>?)
              ?.map((e) => e as String)
              .toList() ??
          [],
    );
  }

  Map<String, dynamic> toJson() => {
    'id': id,
    'expenseApplyNo': expenseApplyNo,
    'expenseApplyDate': expenseApplyDate?.toIso8601String(),
    'applicantId': applicantId,
    'applicantName': applicantName,
    'deptId': deptId,
    'deptName': deptName,
    'estimatedAmount': estimatedAmount,
    'urgency': urgency,
    'purpose': purpose,
    'remark': remark,
    'effectiveDate': effectiveDate?.toIso8601String(),
    'auditorId': auditorId,
    'status': status,
    'usageStatus': usageStatus,
    'validUntil': validUntil?.toIso8601String(),
    'referenceNo': referenceNo,
    'approvalInstanceId': approvalInstanceId,
    'previousInstanceIds': previousInstanceIds,
    'version': version,
    'createTime': createTime.toIso8601String(),
    'updateTime': updateTime.toIso8601String(),
    'isDeleted': isDeleted,
    'isTransferred': isTransferred,
    'isAuditApproved': isAuditApproved ? 1 : 0,
    'currentApproverId': currentApproverId,
    'approvalChain': approvalChain,
    'approvalRecords': approvalRecords.map((r) => r.toJson()).toList(),
    'details': details.map((d) => d.toJson()).toList(),
    'attachments': attachments,
  };

  ExpenseApplyModel copyWith({
    String? id,
    String? expenseApplyNo,
    DateTime? expenseApplyDate,
    String? applicantId,
    String? applicantName,
    String? deptId,
    String? deptName,
    double? estimatedAmount,
    String? urgency,
    String? purpose,
    String? remark,
    DateTime? effectiveDate,
    String? auditorId,
    String? status,
    String? usageStatus,
    DateTime? validUntil,
    String? referenceNo,
    String? approvalInstanceId,
    String? previousInstanceIds,
    int? version,
    DateTime? createTime,
    DateTime? updateTime,
    bool? isDeleted,
    int? isTransferred,
    bool? isAuditApproved,
    String? currentApproverId,
    List<String>? approvalChain,
    List<ApprovalRecord>? approvalRecords,
    List<ExpenseApplyDetailModel>? details,
    List<String>? attachments,
  }) {
    return ExpenseApplyModel(
      id: id ?? this.id,
      expenseApplyNo: expenseApplyNo ?? this.expenseApplyNo,
      expenseApplyDate: expenseApplyDate ?? this.expenseApplyDate,
      applicantId: applicantId ?? this.applicantId,
      applicantName: applicantName ?? this.applicantName,
      deptId: deptId ?? this.deptId,
      deptName: deptName ?? this.deptName,
      estimatedAmount: estimatedAmount ?? this.estimatedAmount,
      urgency: urgency ?? this.urgency,
      purpose: purpose ?? this.purpose,
      remark: remark ?? this.remark,
      effectiveDate: effectiveDate ?? this.effectiveDate,
      auditorId: auditorId ?? this.auditorId,
      status: status ?? this.status,
      usageStatus: usageStatus ?? this.usageStatus,
      validUntil: validUntil ?? this.validUntil,
      referenceNo: referenceNo ?? this.referenceNo,
      approvalInstanceId: approvalInstanceId ?? this.approvalInstanceId,
      previousInstanceIds: previousInstanceIds ?? this.previousInstanceIds,
      version: version ?? this.version,
      createTime: createTime ?? this.createTime,
      updateTime: updateTime ?? this.updateTime,
      isDeleted: isDeleted ?? this.isDeleted,
      isTransferred: isTransferred ?? this.isTransferred,
      isAuditApproved: isAuditApproved ?? this.isAuditApproved,
      currentApproverId: currentApproverId ?? this.currentApproverId,
      approvalChain: approvalChain ?? this.approvalChain,
      approvalRecords: approvalRecords ?? this.approvalRecords,
      details: details ?? this.details,
      attachments: attachments ?? this.attachments,
    );
  }
}

/// 费用申请预估明细，对应 [ExpenseApplyDetail] 表。
class ExpenseApplyDetailModel {
  final String id;
  final String expenseApplyId;
  final String expenseCategory;
  final String categoryName;
  final String purpose;
  final String projectId;
  final String projectName;
  final String costDeptId;
  final String costDeptName;
  final String acctSubjectId;
  final String acctSubjectName;
  final String sqMan;
  final String sqName;
  final DateTime? estimatedStartDate;
  final DateTime? estimatedEndDate;
  final double estimatedAmount;
  final String bxNo;
  final String remark;
  final int? preItm;
  final int sortOrder;
  final DateTime createTime;
  final DateTime updateTime;
  final bool isDeleted;

  const ExpenseApplyDetailModel({
    required this.id,
    this.expenseApplyId = '',
    this.expenseCategory = '',
    this.categoryName = '',
    this.purpose = '',
    this.projectId = '',
    this.projectName = '',
    this.costDeptId = '',
    this.costDeptName = '',
    this.acctSubjectId = '',
    this.acctSubjectName = '',
    this.sqMan = '',
    this.sqName = '',
    this.estimatedStartDate,
    this.estimatedEndDate,
    this.estimatedAmount = 0.0,
    this.bxNo = '',
    this.remark = '',
    this.preItm,
    this.sortOrder = 1,
    required this.createTime,
    required this.updateTime,
    this.isDeleted = false,
  });

  factory ExpenseApplyDetailModel.fromJson(Map<String, dynamic> json) {
    return ExpenseApplyDetailModel(
      id: json['id'] as String? ?? '',
      expenseApplyId: json['aeNo'] as String? ?? '',
      expenseCategory: json['typeNo'] as String? ?? '',
      categoryName: json['typeName'] as String? ?? '',
      purpose: json['purpose'] as String? ?? '',
      projectId: json['objNo'] as String? ?? '',
      projectName: json['objName'] as String? ?? json['projectName'] as String? ?? '',
      costDeptId: json['dep'] as String? ?? '',
      costDeptName: json['depName'] as String? ?? json['dep'] as String? ?? '',
      acctSubjectId: json['accNo'] as String? ?? '',
      acctSubjectName: json['accName'] as String? ?? '',
      estimatedStartDate: json['startDd'] != null
          ? DateTime.parse(json['startDd'] as String)
          : null,
      estimatedEndDate: json['endDd'] != null
          ? DateTime.parse(json['endDd'] as String)
          : null,
      estimatedAmount: (json['amtnYj'] as num?)?.toDouble() ?? 0.0,
      bxNo: json['bxNo'] as String? ?? '',
      remark: json['rem'] as String? ?? '',
      preItm: json['preItm'] as int?,
      sqMan: json['sqMan'] as String? ?? '',
      sqName: json['sqName'] as String? ?? '',
      sortOrder: json['itm'] as int? ?? 1,
      createTime: json['createTime'] != null
          ? DateTime.parse(json['createTime'] as String)
          : DateTime.now(),
      updateTime: json['updateTime'] != null
          ? DateTime.parse(json['updateTime'] as String)
          : DateTime.now(),
      isDeleted: json['isDeleted'] as bool? ?? false,
    );
  }

  Map<String, dynamic> toJson() => {
    'id': id,
    'expenseApplyId': expenseApplyId,
    'expenseCategory': expenseCategory,
    'categoryName': categoryName,
    'purpose': purpose,
    'projectId': projectId,
    'projectName': projectName,
    'costDeptId': costDeptId,
    'costDeptName': costDeptName,
    'acctSubjectId': acctSubjectId,
    'acctSubjectName': acctSubjectName,
    'sqMan': sqMan,
    'sqName': sqName,
    'estimatedStartDate': estimatedStartDate?.toIso8601String(),
    'estimatedEndDate': estimatedEndDate?.toIso8601String(),
    'estimatedAmount': estimatedAmount,
    'bxNo': bxNo,
    'remark': remark,
    'preItm': preItm,
    'sortOrder': sortOrder,
    'createTime': createTime.toIso8601String(),
    'updateTime': updateTime.toIso8601String(),
    'isDeleted': isDeleted,
  };
}
