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;

  // ── 瞬态字段（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.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['expenseApplyNo'] as String? ?? '',
      expenseApplyDate: json['expenseApplyDate'] != null
          ? DateTime.parse(json['expenseApplyDate'] as String)
          : null,
      applicantId: json['applicantId'] as String? ?? '',
      applicantName: json['applicantName'] as String? ?? '',
      deptId: json['deptId'] as String? ?? '',
      deptName: json['deptName'] as String? ?? '',
      estimatedAmount: (json['estimatedAmount'] as num?)?.toDouble() ?? 0.0,
      urgency: json['urgency'] as String? ?? 'normal',
      purpose: json['purpose'] as String? ?? '',
      remark: json['remark'] as String? ?? '',
      effectiveDate: json['effectiveDate'] != null
          ? DateTime.parse(json['effectiveDate'] as String)
          : null,
      auditorId: json['auditorId'] as String? ?? '',
      status: 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: DateTime.parse(json['createTime'] as String),
      updateTime: DateTime.parse(json['updateTime'] as String),
      isDeleted: json['isDeleted'] as bool? ?? false,
      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,
    '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,
    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,
      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 purpose;
  final String projectId;
  final String projectName;
  final String costDeptId;
  final String costDeptName;
  final String acctSubjectId;
  final String acctSubjectName;
  final DateTime? estimatedStartDate;
  final DateTime? estimatedEndDate;
  final double estimatedAmount;
  final String remark;
  final int sortOrder;
  final DateTime createTime;
  final DateTime updateTime;
  final bool isDeleted;

  const ExpenseApplyDetailModel({
    required this.id,
    this.expenseApplyId = '',
    this.expenseCategory = '',
    this.purpose = '',
    this.projectId = '',
    this.projectName = '',
    this.costDeptId = '',
    this.costDeptName = '',
    this.acctSubjectId = '',
    this.acctSubjectName = '',
    this.estimatedStartDate,
    this.estimatedEndDate,
    this.estimatedAmount = 0.0,
    this.remark = '',
    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['expenseApplyId'] as String? ?? '',
      expenseCategory: json['expenseCategory'] as String? ?? '',
      purpose: json['purpose'] as String? ?? '',
      projectId: json['projectId'] as String? ?? '',
      projectName: json['projectName'] as String? ?? '',
      costDeptId: json['costDeptId'] as String? ?? '',
      costDeptName: json['costDeptName'] as String? ?? '',
      acctSubjectId: json['acctSubjectId'] as String? ?? '',
      acctSubjectName: json['acctSubjectName'] as String? ?? '',
      estimatedStartDate: json['estimatedStartDate'] != null
          ? DateTime.parse(json['estimatedStartDate'] as String)
          : null,
      estimatedEndDate: json['estimatedEndDate'] != null
          ? DateTime.parse(json['estimatedEndDate'] as String)
          : null,
      estimatedAmount: (json['estimatedAmount'] as num?)?.toDouble() ?? 0.0,
      remark: json['remark'] as String? ?? '',
      sortOrder: json['sortOrder'] as int? ?? 1,
      createTime: DateTime.parse(json['createTime'] as String),
      updateTime: DateTime.parse(json['updateTime'] as String),
      isDeleted: json['isDeleted'] as bool? ?? false,
    );
  }

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