import type { LeaseBusinessDetailRow } from '../types';
import {
  getContractRef,
  getVehicleRef,
  isKnownCustomerName,
  isPlateInVehicleSystem,
  resolveExpectedCustomer,
  resolveSettlementMonths,
} from './system-ref';

export type FieldCheckStatus = 'none' | 'ok' | 'warn';

export interface FieldCheckInfo {
  status: FieldCheckStatus;
  title?: string;
  details?: string[];
  replaceAction?: Partial<LeaseBusinessDetailRow>;
}

function roundMoney(value: number): number {
  return Math.round(value * 100) / 100;
}

function moneyEqual(a: number, b: number): boolean {
  return Math.abs(a - b) < 0.005;
}

function ok(details: string[]): FieldCheckInfo {
  return { status: 'ok', title: '与系统一致', details };
}

function warn(title: string, details: string[], replaceAction?: Partial<LeaseBusinessDetailRow>): FieldCheckInfo {
  return { status: 'warn', title, details, replaceAction };
}

function none(): FieldCheckInfo {
  return { status: 'none' };
}

export function checkPlateExists(row: LeaseBusinessDetailRow): FieldCheckInfo {
  if (!row.plateNo) return none();
  if (isPlateInVehicleSystem(row.plateNo)) return ok(['车牌已在车辆管理中登记']);
  return warn('车牌不存在', ['该车牌号码未在系统「车辆管理」中登记，无法导入']);
}

export function checkCustomerName(row: LeaseBusinessDetailRow): FieldCheckInfo {
  if (!row.plateNo || !row.customerName) return none();
  const contract = getContractRef(row.plateNo, row.customerName);
  const expected = resolveExpectedCustomer(row.plateNo, row.pickupDate, row.returnDate) || contract?.customerName || '';
  if (expected && row.customerName.trim() === expected.trim()) {
    return ok(['客户名称与系统登记一致']);
  }
  if (contract && row.customerName.trim() === contract.customerName.trim()) {
    return ok(['客户名称与租赁合同一致']);
  }
  if (expected && row.customerName.trim() !== expected.trim()) {
    return warn(
      '客户名称与系统不对应',
      ['客户名称与系统「客户管理」不对应', `建议客户：${expected}`],
      { customerName: expected },
    );
  }
  if (isKnownCustomerName(row.customerName)) {
    return ok(['客户名称已在客户管理中登记']);
  }
  return warn(
    '客户名称与系统不对应',
    ['客户名称与系统「客户管理」不对应', '请核对提车日期与退车日期'],
  );
}

export function checkPickupDate(row: LeaseBusinessDetailRow): FieldCheckInfo {
  const vehicle = getVehicleRef(row.plateNo);
  if (!vehicle || !row.pickupDate) return none();
  const systemDate = vehicle.deliveryDate;
  if (!systemDate) return none();
  if (row.pickupDate.slice(0, 10) === systemDate) return ok(['提车日期与交车管理一致']);
  return warn('提车日期不一致', [`交车管理提车日期：${systemDate}`], { pickupDate: systemDate });
}

export function checkReturnDate(row: LeaseBusinessDetailRow): FieldCheckInfo {
  const vehicle = getVehicleRef(row.plateNo);
  if (!vehicle || !row.returnDate) return none();
  const systemDate = vehicle.returnDate;
  if (!systemDate) return none();
  if (row.returnDate.slice(0, 10) === systemDate) return ok(['退车日期与还车记录一致']);
  return warn('退车日期不一致', [`还车记录日期：${systemDate}`], { returnDate: systemDate });
}

export function checkDeposit(row: LeaseBusinessDetailRow): FieldCheckInfo {
  const contract = getContractRef(row.plateNo, row.customerName);
  if (!contract || typeof row.deposit !== 'number') return none();
  if (moneyEqual(row.deposit, contract.deposit)) return ok(['押金与合同保证金一致']);
  return warn('押金不一致', [`合同保证金：${contract.deposit.toFixed(2)}`], { deposit: contract.deposit });
}

export function checkContractRent(row: LeaseBusinessDetailRow): FieldCheckInfo {
  const contract = getContractRef(row.plateNo, row.customerName);
  if (!contract || !row.contractRent) return none();
  if (moneyEqual(row.contractRent, contract.contractRent)) return ok(['租金与合同一致']);
  return warn('租金不一致', [`合同租金：${contract.contractRent.toFixed(2)}`], { contractRent: contract.contractRent });
}

export function checkReceivableRent(row: LeaseBusinessDetailRow): FieldCheckInfo {
  const months = resolveSettlementMonths(row);
  const expected = roundMoney(row.contractRent * months);
  if (!expected && !row.receivableRent) return none();
  if (moneyEqual(row.receivableRent, expected)) return ok([`应收租金 = 合同标的租金 × ${months} 个月`]);
  return warn('应收租金不一致', [`正确金额：${expected.toFixed(2)}`], { receivableRent: expected });
}

export function checkMileageDeduction(row: LeaseBusinessDetailRow): FieldCheckInfo {
  if (row.mileageDeduction === 0) return none();
  if (row.mileageDeduction < 0) return ok(['里程减免以负数显示']);
  return warn('里程减免金额应为负数', ['请录入负值，例如 -500']);
}

export function checkOtherDeduction(row: LeaseBusinessDetailRow): FieldCheckInfo {
  if (row.otherDeduction === 0) return none();
  if (row.otherDeduction < 0) return ok(['其他减免以负数显示']);
  return warn('其他减免金额应为负数', ['请录入负值']);
}

export function checkAssetOwner(row: LeaseBusinessDetailRow): FieldCheckInfo {
  const vehicle = getVehicleRef(row.plateNo);
  if (!vehicle || !row.assetOwner) return none();
  const expected = vehicle.registeredOwnership;
  if (!expected) return none();
  if (row.assetOwner.trim() === expected.trim()) return ok(['与车辆登记所有权一致']);
  return warn('资产归属不一致', [`登记所有权：${expected}`], { assetOwner: expected });
}

export function getFieldCheck(
  row: LeaseBusinessDetailRow,
  field:
    | 'plateNo'
    | 'customerName'
    | 'pickupDate'
    | 'returnDate'
    | 'deposit'
    | 'contractRent'
    | 'receivableRent'
    | 'mileageDeduction'
    | 'otherDeduction'
    | 'assetOwner',
): FieldCheckInfo {
  switch (field) {
    case 'plateNo': return checkPlateExists(row);
    case 'customerName': return checkCustomerName(row);
    case 'pickupDate': return checkPickupDate(row);
    case 'returnDate': return checkReturnDate(row);
    case 'deposit': return checkDeposit(row);
    case 'contractRent': return checkContractRent(row);
    case 'receivableRent': return checkReceivableRent(row);
    case 'mileageDeduction': return checkMileageDeduction(row);
    case 'otherDeduction': return checkOtherDeduction(row);
    case 'assetOwner': return checkAssetOwner(row);
    default: return none();
  }
}

export function displayDeductionAmount(value: number): string {
  if (value === 0) return '';
  const abs = Math.abs(value);
  const text = abs.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  return value > 0 ? `-${text}` : `-${text}`;
}

export function normalizeDeductionForDisplay(value: number): number {
  if (value === 0) return 0;
  return value > 0 ? -Math.abs(value) : value;
}
