import 'api_client.dart';

class ContractCompany {
  final String name;
  final String? email;
  final String? phone;
  final String? address;

  const ContractCompany(
      {required this.name, this.email, this.phone, this.address});

  factory ContractCompany.fromJson(Map<String, dynamic> j) {
    final parts = <String>[];
    final addr = j['address'];
    if (addr is String && addr.trim().isNotEmpty) parts.add(addr.trim());
    if (addr is Map) {
      for (final v in addr.values) {
        if (v is String && v.trim().isNotEmpty) parts.add(v.trim());
      }
    }
    if (j['city'] is String) parts.add(j['city'] as String);
    if (j['country'] is String) parts.add(j['country'] as String);
    return ContractCompany(
      name: (j['legalName'] as String?)?.isNotEmpty == true
          ? j['legalName'] as String
          : j['name'] as String,
      email: j['email'] as String?,
      phone: j['phone'] as String?,
      address: parts.isEmpty ? null : parts.join(', '),
    );
  }
}

class ContractDriver {
  final String firstName;
  final String lastName;
  final String email;
  final String? phone;
  final String? driverLicense;
  final String? licenseCountry;
  final String? licenseExpiry;
  final String? nationality;

  const ContractDriver({
    required this.firstName,
    required this.lastName,
    required this.email,
    this.phone,
    this.driverLicense,
    this.licenseCountry,
    this.licenseExpiry,
    this.nationality,
  });

  String get fullName => '$firstName $lastName';

  factory ContractDriver.fromJson(Map<String, dynamic> j) => ContractDriver(
        firstName: j['firstName'] as String,
        lastName: j['lastName'] as String,
        email: j['email'] as String,
        phone: j['phone'] as String?,
        driverLicense: j['driverLicense'] as String?,
        licenseCountry: j['licenseCountry'] as String?,
        licenseExpiry: j['licenseExpiry'] as String?,
        nationality: j['nationality'] as String?,
      );
}

class ContractVehicle {
  final String make;
  final String model;
  final int year;
  final String? color;
  final String licensePlate;
  final String? vin;
  final String category;

  const ContractVehicle({
    required this.make,
    required this.model,
    required this.year,
    this.color,
    required this.licensePlate,
    this.vin,
    required this.category,
  });

  String get displayName => '$year $make $model';

  factory ContractVehicle.fromJson(Map<String, dynamic> j) => ContractVehicle(
        make: j['make'] as String,
        model: j['model'] as String,
        year: j['year'] as int,
        color: j['color'] as String?,
        licensePlate: j['licensePlate'] as String,
        vin: j['vin'] as String?,
        category: j['category'] as String,
      );
}

class ContractLineItem {
  final String description;
  final int qty;
  final int unitPrice;
  final int total;

  const ContractLineItem({
    required this.description,
    required this.qty,
    required this.unitPrice,
    required this.total,
  });

  factory ContractLineItem.fromJson(Map<String, dynamic> j) => ContractLineItem(
        description: j['description'] as String,
        qty: (j['qty'] as num).toInt(),
        unitPrice: (j['unitPrice'] as num).toInt(),
        total: (j['total'] as num).toInt(),
      );
}

class ContractPayment {
  final String id;
  final int amount;
  final String currency;
  final String type;
  final String status;
  final String? paymentMethod;
  final DateTime? paidAt;

  const ContractPayment({
    required this.id,
    required this.amount,
    required this.currency,
    required this.type,
    required this.status,
    this.paymentMethod,
    this.paidAt,
  });

  factory ContractPayment.fromJson(Map<String, dynamic> j) => ContractPayment(
        id: j['id'] as String,
        amount: (j['amount'] as num).toInt(),
        currency: j['currency'] as String? ?? 'USD',
        type: j['type'] as String,
        status: j['status'] as String,
        paymentMethod: j['paymentMethod'] as String?,
        paidAt: j['paidAt'] != null
            ? DateTime.tryParse(j['paidAt'] as String)
            : null,
      );
}

class ContractInspection {
  final int? mileage;
  final String? fuelLevel;
  final String? generalCondition;
  final String? employeeNotes;

  const ContractInspection(
      {this.mileage, this.fuelLevel, this.generalCondition, this.employeeNotes});

  factory ContractInspection.fromJson(Map<String, dynamic> j) =>
      ContractInspection(
        mileage: j['mileage'] as int?,
        fuelLevel: j['fuelLevel'] as String?,
        generalCondition: j['generalCondition'] as String?,
        employeeNotes: j['employeeNotes'] as String?,
      );
}

class ContractPayload {
  final String reservationId;
  final String? contractNumber;
  final String? invoiceNumber;
  final String status;
  final String paymentStatus;
  final String? notes;
  final DateTime generatedAt;
  final ContractCompany company;
  final ContractDriver driver;
  final ContractVehicle vehicle;
  final DateTime startDate;
  final DateTime endDate;
  final int totalDays;
  final String? pickupLocation;
  final String? returnLocation;
  final List<ContractLineItem> lineItems;
  final int subtotal;
  final int taxTotal;
  final int total;
  final int amountPaid;
  final int balanceDue;
  final String currency;
  final List<ContractPayment> payments;
  final ContractInspection? checkIn;
  final ContractInspection? checkOut;
  final String? terms;
  final String? fuelPolicy;
  final String? depositPolicy;

  const ContractPayload({
    required this.reservationId,
    this.contractNumber,
    this.invoiceNumber,
    required this.status,
    required this.paymentStatus,
    this.notes,
    required this.generatedAt,
    required this.company,
    required this.driver,
    required this.vehicle,
    required this.startDate,
    required this.endDate,
    required this.totalDays,
    this.pickupLocation,
    this.returnLocation,
    required this.lineItems,
    required this.subtotal,
    required this.taxTotal,
    required this.total,
    required this.amountPaid,
    required this.balanceDue,
    required this.currency,
    required this.payments,
    this.checkIn,
    this.checkOut,
    this.terms,
    this.fuelPolicy,
    this.depositPolicy,
  });

  factory ContractPayload.fromJson(Map<String, dynamic> j) {
    final period = j['rentalPeriod'] as Map<String, dynamic>;
    final invoice = j['invoice'] as Map<String, dynamic>;
    final inspections =
        j['inspections'] as Map<String, dynamic>? ?? {};
    final termsData = j['terms'] as Map<String, dynamic>? ?? {};

    return ContractPayload(
      reservationId: j['reservationId'] as String,
      contractNumber: j['contractNumber'] as String?,
      invoiceNumber: j['invoiceNumber'] as String?,
      status: j['status'] as String,
      paymentStatus: j['paymentStatus'] as String,
      notes: j['notes'] as String?,
      generatedAt: DateTime.parse(j['generatedAt'] as String),
      company:
          ContractCompany.fromJson(j['company'] as Map<String, dynamic>),
      driver:
          ContractDriver.fromJson(j['driver'] as Map<String, dynamic>),
      vehicle:
          ContractVehicle.fromJson(j['vehicle'] as Map<String, dynamic>),
      startDate: DateTime.parse(period['startDate'] as String),
      endDate: DateTime.parse(period['endDate'] as String),
      totalDays: (period['totalDays'] as num).toInt(),
      pickupLocation: period['pickupLocation'] as String?,
      returnLocation: period['returnLocation'] as String?,
      lineItems: (invoice['lineItems'] as List<dynamic>? ?? [])
          .map((e) => ContractLineItem.fromJson(e as Map<String, dynamic>))
          .toList(),
      subtotal: (invoice['subtotal'] as num).toInt(),
      taxTotal: (invoice['taxTotal'] as num).toInt(),
      total: (invoice['total'] as num).toInt(),
      amountPaid: (invoice['amountPaid'] as num).toInt(),
      balanceDue: (invoice['balanceDue'] as num).toInt(),
      currency: invoice['currency'] as String? ?? 'USD',
      payments: (invoice['payments'] as List<dynamic>? ?? [])
          .map((e) => ContractPayment.fromJson(e as Map<String, dynamic>))
          .toList(),
      checkIn: inspections['checkIn'] != null
          ? ContractInspection.fromJson(
              inspections['checkIn'] as Map<String, dynamic>)
          : null,
      checkOut: inspections['checkOut'] != null
          ? ContractInspection.fromJson(
              inspections['checkOut'] as Map<String, dynamic>)
          : null,
      terms: termsData['terms'] as String?,
      fuelPolicy: termsData['fuelPolicy'] as String?,
      depositPolicy: termsData['depositPolicy'] as String?,
    );
  }
}

class ContractService {
  final _client = ApiClient.instance;

  Future<ContractPayload> getContract(String reservationId) async {
    final res = await _client.get('/reservations/$reservationId/contract');
    return ContractPayload.fromJson(res.data as Map<String, dynamic>);
  }
}
