import vehicles from '../../vehicle-management/data/vehicles.json';
import customers from '../../customer-management/data/customers.json';
import seedRows from '../data/rows.json';
import type { LeaseBusinessDetailRow } from '../types';

export interface VehicleRef {
  plateNo: string;
  brand: string;
  model: string;
  brandModel: string;
  registeredOwnership: string;
  deliveryDate: string;
  returnDate: string;
}

export interface ContractRef {
  businessDept: string;
  salesperson: string;
  customerName: string;
  deposit: number;
  contractRent: number;
  settlementMonths: number;
  paymentTiming: 'pre' | 'post';
  signingCompany: string;
  pickupDate: string;
  returnDate: string;
}

type VehicleSeed = {
  plateNo?: string;
  brand?: string;
  model?: string;
  ownership?: string;
  lastDeliveryTime?: string;
  lastReturnTime?: string;
};

const plateRegistry = new Map<string, VehicleRef>();
const contractByPlateCustomer = new Map<string, ContractRef>();
const customerNameSet = new Set<string>();

function parseBrandModel(vehicleType: string): { brand: string; model: string } {
  const raw = String(vehicleType || '').trim();
  if (!raw) return { brand: '', model: '' };
  const slash = raw.indexOf('/');
  if (slash >= 0) {
    return { brand: raw.slice(0, slash).trim(), model: raw.slice(slash + 1).trim() };
  }
  const digit = raw.search(/\d/);
  if (digit > 0) {
    return { brand: raw.slice(0, digit).trim(), model: raw.slice(digit).trim() };
  }
  return { brand: raw, model: '' };
}

function formatBrandModel(brand: string, model: string): string {
  if (brand && model) return `${brand}·${model}`;
  return brand || model || '';
}

function normalizeDate(value: unknown): string {
  const raw = String(value ?? '').trim();
  if (!raw || raw === '-') return '';
  return raw.slice(0, 10);
}

function parsePaymentTiming(method: string): 'pre' | 'post' {
  return method.includes('后付') ? 'post' : 'pre';
}

function parseSettlementMonths(method: string): number {
  if (method.includes('年度') || method.includes('一年')) return 12;
  if (method.includes('半年')) return 6;
  if (method.includes('季度')) return 3;
  return 1;
}

function contractKey(plateNo: string, customerName: string): string {
  return `${plateNo}::${customerName}`;
}

function registerVehicle(ref: VehicleRef): void {
  plateRegistry.set(ref.plateNo, ref);
}

function registerContract(plateNo: string, customerName: string, row: Partial<LeaseBusinessDetailRow>): void {
  if (!plateNo || !customerName) return;
  const key = contractKey(plateNo, customerName);
  if (contractByPlateCustomer.has(key)) return;
  contractByPlateCustomer.set(key, {
    businessDept: row.businessDept ?? '',
    salesperson: row.salesperson ?? '',
    customerName,
    deposit: typeof row.deposit === 'number' ? row.deposit : 0,
    contractRent: row.contractRent ?? 0,
    settlementMonths: parseSettlementMonths(row.paymentMethod ?? ''),
    paymentTiming: parsePaymentTiming(row.paymentMethod ?? ''),
    signingCompany: row.signingCompany ?? '',
    pickupDate: normalizeDate(row.pickupDate),
    returnDate: normalizeDate(row.returnDate),
  });
}

function bootstrap(): void {
  (customers as { name?: string }[]).forEach((c) => {
    if (c.name) customerNameSet.add(c.name.trim());
  });

  (vehicles as VehicleSeed[]).forEach((v) => {
    if (!v.plateNo) return;
    registerVehicle({
      plateNo: v.plateNo,
      brand: v.brand ?? '',
      model: v.model ?? '',
      brandModel: formatBrandModel(v.brand ?? '', v.model ?? ''),
      registeredOwnership: v.ownership ?? '',
      deliveryDate: normalizeDate(v.lastDeliveryTime),
      returnDate: normalizeDate(v.lastReturnTime),
    });
  });

  (seedRows as LeaseBusinessDetailRow[]).forEach((row) => {
    if (!row.plateNo) return;
    const parsed = parseBrandModel(row.vehicleType);
    const existing = plateRegistry.get(row.plateNo);
    if (!existing) {
      registerVehicle({
        plateNo: row.plateNo,
        brand: parsed.brand,
        model: parsed.model,
        brandModel: formatBrandModel(parsed.brand, parsed.model) || row.vehicleType,
        registeredOwnership: row.assetOwner ?? '',
        deliveryDate: normalizeDate(row.pickupDate),
        returnDate: normalizeDate(row.returnDate),
      });
    } else if (!existing.brandModel && row.vehicleType) {
      existing.brandModel = row.vehicleType;
    }
    if (row.customerName) customerNameSet.add(row.customerName.trim());
    registerContract(row.plateNo, row.customerName, row);
  });
}

bootstrap();

export function isPlateInVehicleSystem(plateNo: string): boolean {
  return Boolean(plateNo && plateRegistry.has(plateNo.trim()));
}

export function getVehicleRef(plateNo: string): VehicleRef | undefined {
  return plateRegistry.get(plateNo.trim());
}

export function getContractRef(plateNo: string, customerName: string): ContractRef | undefined {
  return contractByPlateCustomer.get(contractKey(plateNo.trim(), customerName.trim()));
}

export function resolveExpectedCustomer(
  plateNo: string,
  pickupDate: string,
  returnDate: string,
): string {
  const vehicle = getVehicleRef(plateNo);
  const pickup = normalizeDate(pickupDate);
  const ret = normalizeDate(returnDate);
  let best = '';
  contractByPlateCustomer.forEach((contract, key) => {
    if (!key.startsWith(`${plateNo.trim()}::`)) return;
    if (pickup && contract.pickupDate && contract.pickupDate !== pickup) return;
    if (ret && contract.returnDate && contract.returnDate !== ret) return;
    best = contract.customerName;
  });
  if (best) return best;
  return vehicle ? '' : '';
}

export function isKnownCustomerName(name: string): boolean {
  const trimmed = name.trim();
  if (!trimmed) return false;
  if (customerNameSet.has(trimmed)) return true;
  return Array.from(customerNameSet).some((c) => c.includes(trimmed) || trimmed.includes(c));
}

export function formatPaymentMethodLabel(months: number, timing: 'pre' | 'post'): string {
  const period =
    months === 12 ? '年度'
      : months === 6 ? '半年'
        : months === 3 ? '季度'
          : months === 1 ? '月度'
            : `${months}个月`;
  return `${period}${timing === 'post' ? '后付' : '预付'}`;
}

export function resolvePaymentMethodLabel(row: LeaseBusinessDetailRow): string {
  const contract = getContractRef(row.plateNo, row.customerName);
  if (contract) {
    return formatPaymentMethodLabel(contract.settlementMonths, contract.paymentTiming);
  }
  return row.paymentMethod;
}

export function resolveSettlementMonths(row: LeaseBusinessDetailRow): number {
  const contract = getContractRef(row.plateNo, row.customerName);
  return contract?.settlementMonths ?? parseSettlementMonths(row.paymentMethod);
}
