// ---------------- ExpenseDetailModel ----------------
class ExpenseDetailModel {
  final String id;
  final Project project;
  final ExpensesType expensesType; 
  final PaymentMode paymentMode;
  final Person paidBy;
  final Person createdBy;
  final Person? reviewedBy;
  final Person? approvedBy;
  final Person? processedBy;
  final String transactionDate;
  final String createdAt;
  final String supplerName;
  final double amount;
  final double? baseAmount;
  final double? taxAmount;
  final double? tdsPercentage;
  final ExpenseStatus status;
  final List nextStatus;
  final bool preApproved;
  final String transactionId;
  final String description;
  final String location;
  final Currency? currency;
  final List<ExpenseDocument> documents;
  final List<ExpenseLog> expenseLogs;

  final String? gstNumber;
  final int? noOfPersons;
  final bool isActive;
  final dynamic expensesReimburse;
  final String? expenseUId;
  final String? paymentRequestUID;

  ExpenseDetailModel({
    required this.id,
    required this.project,
    required this.expensesType,
    required this.paymentMode,
    required this.paidBy,
    required this.createdBy,
    this.reviewedBy,
    this.approvedBy,
    this.processedBy,
    required this.transactionDate,
    required this.createdAt,
    required this.supplerName,
    required this.amount,
    this.baseAmount,
    this.taxAmount,
    this.tdsPercentage,
    required this.status,
    required this.nextStatus,
    required this.preApproved,
    required this.transactionId,
    required this.description,
    required this.location,
    this.currency,
    required this.documents,
    required this.expenseLogs,
    this.gstNumber,
    this.noOfPersons,
    required this.isActive,
    this.expensesReimburse,
    this.expenseUId,
    this.paymentRequestUID,
  });

  factory ExpenseDetailModel.fromJson(Map<String, dynamic> json) {
    return ExpenseDetailModel(
      id: json['id'] ?? '',
      project: json['project'] != null
          ? Project.fromJson(json['project'])
          : Project.empty(),
      expensesType: json['expenseCategory'] != null
          ? ExpensesType.fromJson(json['expenseCategory'])
          : ExpensesType.empty(),
      paymentMode: json['paymentMode'] != null
          ? PaymentMode.fromJson(json['paymentMode'])
          : PaymentMode.empty(),
      paidBy: json['paidBy'] != null
          ? Person.fromJson(json['paidBy'])
          : Person.empty(),
      createdBy: json['createdBy'] != null
          ? Person.fromJson(json['createdBy'])
          : Person.empty(),
      reviewedBy: json['reviewedBy'] != null
          ? Person.fromJson(json['reviewedBy'])
          : null,
      approvedBy: json['approvedBy'] != null
          ? Person.fromJson(json['approvedBy'])
          : null,
      processedBy: json['processedBy'] != null
          ? Person.fromJson(json['processedBy'])
          : null,
      transactionDate: json['transactionDate'] ?? '',
      createdAt: json['createdAt'] ?? '',
      supplerName: json['supplerName'] ?? '',
      amount: (json['amount'] as num?)?.toDouble() ?? 0.0,
      baseAmount: (json['baseAmount'] as num?)?.toDouble(),
      taxAmount: (json['taxAmount'] as num?)?.toDouble(),
      tdsPercentage: (json['tdsPercentage'] as num?)?.toDouble(),
      status: json['status'] != null
          ? ExpenseStatus.fromJson(json['status'])
          : ExpenseStatus.empty(),
      nextStatus: (json['nextStatus'] as List?)
              ?.map((e) => ExpenseStatus.fromJson(e))
              .toList() ??
          [],
      preApproved: json['preApproved'] ?? false,
      transactionId: json['transactionId'] ?? '',
      description: json['description'] ?? '',
      location: json['location'] ?? '',
      currency:
          json['currency'] != null ? Currency.fromJson(json['currency']) : null,
      documents: (json['documents'] as List?)
              ?.map((e) => ExpenseDocument.fromJson(e))
              .toList() ??
          [],
      expenseLogs: (json['expenseLogs'] as List?)
              ?.map((e) => ExpenseLog.fromJson(e))
              .toList() ??
          [],
      gstNumber: json['gstNumber']?.toString(),
      noOfPersons: json['noOfPersons'] != null ? json['noOfPersons'] : null,
      isActive: json['isActive'] ?? true,
      expensesReimburse: json['expensesReimburse'],
      expenseUId: json['expenseUId']?.toString(),
      paymentRequestUID: json['paymentRequestUID']?.toString(),
    );
  }
}

// ---------------- Project ----------------
class Project {
  final String id;
  final String name;
  final String shortName;
  final String? projectAddress;
  final String? contactPerson;
  final String? startDate;
  final String? endDate;
  final String projectStatusId;

  Project({
    required this.id,
    required this.name,
    required this.shortName,
    this.projectAddress,
    this.contactPerson,
    this.startDate,
    this.endDate,
    required this.projectStatusId,
  });

  factory Project.fromJson(Map<String, dynamic> json) {
    return Project(
      id: json['id'] ?? '',
      name: json['name'] ?? '',
      shortName: json['shortName'] ?? '',
      projectAddress: json['projectAddress'],
      contactPerson: json['contactPerson'],
      startDate: json['startDate'],
      endDate: json['endDate'],
      projectStatusId: json['projectStatusId'] ?? '',
    );
  }

  factory Project.empty() => Project(
        id: '',
        name: '',
        shortName: '',
        projectStatusId: '',
      );
}

// ---------------- ExpensesType ----------------
class ExpensesType {
  final String id;
  final String name;
  final bool noOfPersonsRequired;
  final bool isAttachmentRequried;
  final String description;

  ExpensesType({
    required this.id,
    required this.name,
    required this.noOfPersonsRequired,
    required this.isAttachmentRequried,
    required this.description,
  });

  factory ExpensesType.fromJson(Map<String, dynamic> json) {
    return ExpensesType(
      id: json['id'] ?? '',
      name: json['name'] ?? '',
      noOfPersonsRequired: json['noOfPersonsRequired'] ?? false,
      isAttachmentRequried: json['isAttachmentRequried'] ?? false,
      description: json['description'] ?? '',
    );
  }

  factory ExpensesType.empty() => ExpensesType(
        id: '',
        name: '',
        noOfPersonsRequired: false,
        isAttachmentRequried: false,
        description: '',
      );
}

// ---------------- PaymentMode ----------------
class PaymentMode {
  final String id;
  final String name;
  final String description;

  PaymentMode({
    required this.id,
    required this.name,
    required this.description,
  });

  factory PaymentMode.fromJson(Map<String, dynamic> json) {
    return PaymentMode(
      id: json['id'] ?? '',
      name: json['name'] ?? '',
      description: json['description'] ?? '',
    );
  }

  factory PaymentMode.empty() => PaymentMode(
        id: '',
        name: '',
        description: '',
      );
}

// ---------------- Person ----------------
class Person {
  final String id;
  final String firstName;
  final String lastName;
  final String? email;
  final String photo;
  final String jobRoleId;
  final String jobRoleName;

  Person({
    required this.id,
    required this.firstName,
    required this.lastName,
    this.email,
    required this.photo,
    required this.jobRoleId,
    required this.jobRoleName,
  });

  factory Person.fromJson(Map<String, dynamic> json) {
    return Person(
      id: json['id'] ?? '',
      firstName: json['firstName'] ?? '',
      lastName: json['lastName'] ?? '',
      email: json['email'],
      photo: json['photo'] ?? '',
      jobRoleId: json['jobRoleId'] ?? '',
      jobRoleName: json['jobRoleName'] ?? '',
    );
  }

  factory Person.empty() => Person(
        id: '',
        firstName: '',
        lastName: '',
        email: null,
        photo: '',
        jobRoleId: '',
        jobRoleName: '',
      );
}

// ---------------- ExpenseStatus ----------------
class ExpenseStatus {
  final String id;
  final String name;
  final String displayName;
  final String description;
  final String? permissionIds;
  final String color;
  final bool isSystem;

  ExpenseStatus({
    required this.id,
    required this.name,
    required this.displayName,
    required this.description,
    this.permissionIds,
    required this.color,
    required this.isSystem,
  });

  factory ExpenseStatus.fromJson(Map<String, dynamic> json) {
    return ExpenseStatus(
      id: json['id'] ?? '',
      name: json['name'] ?? '',
      displayName: json['displayName'] ?? '',
      description: json['description'] ?? '',
      permissionIds: json['permissionIds']?.toString(),
      color: json['color'] ?? '',
      isSystem: json['isSystem'] ?? false,
    );
  }

  factory ExpenseStatus.empty() => ExpenseStatus(
        id: '',
        name: '',
        displayName: '',
        description: '',
        permissionIds: null,
        color: '',
        isSystem: false,
      );
}

// ---------------- ExpenseDocument ----------------
class ExpenseDocument {
  final String documentId;
  final String fileName;
  final String contentType;
  final String preSignedUrl;
  final String thumbPreSignedUrl;

  ExpenseDocument({
    required this.documentId,
    required this.fileName,
    required this.contentType,
    required this.preSignedUrl,
    required this.thumbPreSignedUrl,
  });

  factory ExpenseDocument.fromJson(Map<String, dynamic> json) {
    return ExpenseDocument(
      documentId: json['documentId'] ?? '',
      fileName: json['fileName'] ?? '',
      contentType: json['contentType'] ?? '',
      preSignedUrl: json['preSignedUrl'] ?? '',
      thumbPreSignedUrl: json['thumbPreSignedUrl'] ?? '',
    );
  }
}

// ---------------- ExpenseLog ----------------
class ExpenseLog {
  final String id;
  final Person updatedBy;
  final String action;
  final String updateAt;
  final String comment;

  ExpenseLog({
    required this.id,
    required this.updatedBy,
    required this.action,
    required this.updateAt,
    required this.comment,
  });

  factory ExpenseLog.fromJson(Map<String, dynamic> json) {
    return ExpenseLog(
      id: json['id'] ?? '',
      updatedBy: json['updatedBy'] != null
          ? Person.fromJson(json['updatedBy'])
          : Person.empty(),
      action: json['action'] ?? '',
      updateAt: json['updateAt'] ?? '',
      comment: json['comment'] ?? '',
    );
  }
}

// ---------------- Currency ----------------
class Currency {
  final String id;
  final String currencyCode;
  final String currencyName;
  final String symbol;
  final bool isActive;

  Currency({
    required this.id,
    required this.currencyCode,
    required this.currencyName,
    required this.symbol,
    required this.isActive,
  });

  factory Currency.fromJson(Map<String, dynamic> json) {
    return Currency(
      id: json['id'] ?? '',
      currencyCode: json['currencyCode'] ?? '',
      currencyName: json['currencyName'] ?? '',
      symbol: json['symbol'] ?? '',
      isActive: json['isActive'] ?? true,
    );
  }
}
