import type {
  AccidentRecord,
  AssetOwnership,
  BiMileageRecord,
  HydrogenFeeRecord,
  LeaseDetailStatus,
  LeaseLedgerFilters,
  LeaseLedgerRow,
  LeaseKpiSummary,
  ListViewMode,
  MaintenanceOrder,
} from '../types';

/** 原型：车牌主数据（导入/新增时按车牌自动匹配品牌型号） */
export const PLATE_VEHICLE_MAP: Record<string, { brand: string; model: string }> = {
  沪A32896F: { brand: '苏龙', model: '18T' },
  沪A61121F: { brand: '苏龙', model: '18T' },
  沪A69695F: { brand: '苏龙', model: '18T' },
  粤AGF4535: { brand: '现代', model: '4.5T/交投' },
  沪A65889F: { brand: '苏龙', model: '18T' },
  浙F08991F: { brand: '飞驰', model: '18T' },
  浙F05580F: { brand: '苏龙', model: '18T' },
  沪A50990F: { brand: '苏龙', model: '18T' },
};

/** 原型：按车牌匹配客户与项目 */
export const PLATE_CONTRACT_MAP: Record<string, { customerName: string; projectName: string }> = {
  沪A32896F: { customerName: '安徽驰远供应链管理有限公司', projectName: '安徽驰远供应链管租赁项目' },
  沪A61121F: { customerName: '安徽驰远供应链管理有限公司', projectName: '安徽驰远供应链管租赁项目' },
  沪A69695F: { customerName: '安徽驰远供应链管理有限公司', projectName: '安徽驰远供应链管租赁项目' },
  粤AGF4535: { customerName: '嘉兴港区韵达快递有限公司', projectName: '嘉兴港区韵达租赁项目' },
  沪A65889F: { customerName: '嘉兴港区韵达快递有限公司', projectName: '嘉兴港区韵达租赁项目' },
  浙F08991F: { customerName: '上海利合供应链管理有限公司', projectName: '上海利合供应链租赁项目' },
  浙F05580F: { customerName: '上海朔宇物流有限公司', projectName: '上海朔宇物流租赁项目' },
  沪A50990F: { customerName: '苏州望亭远方物流有限公司', projectName: '苏州望亭远方物流租赁项目' },
};

/** 原型：租赁合同甲方（签约公司） */
export const PLATE_SIGNING_COMPANY: Record<string, string> = {
  沪A32896F: '浙江羚牛氢能科技有限公司',
  沪A61121F: '浙江羚牛氢能科技有限公司',
  沪A69695F: '浙江羚牛氢能科技有限公司',
  粤AGF4535: '浙江羚牛氢能科技有限公司',
  沪A65889F: '浙江羚牛氢能科技有限公司',
  浙F08991F: '浙江羚牛氢能科技有限公司',
  浙F05580F: '浙江羚牛氢能科技有限公司',
  沪A50990F: '浙江羚牛氢能科技有限公司',
};

/** 原型：资产实际归属公司 */
export const PLATE_ASSET_OWNER: Record<string, string> = {
  沪A32896F: '安吉天地物流科技有限公司',
  沪A61121F: '安吉天地物流科技有限公司',
  沪A69695F: '安吉天地物流科技有限公司',
  粤AGF4535: '广州开发区交投氢能运营管理有限公司',
  沪A65889F: '羚牛新能源科技（上海）有限公司',
  浙F08991F: '浙江羚牛氢能科技有限公司',
  浙F05580F: '上海宇速物流有限公司',
  沪A50990F: '上海宇速物流有限公司',
};

/** 原型：车型标准成本（固定成本） */
export const PLATE_STANDARD_COST: Record<string, number> = {
  沪A32896F: 3900,
  沪A61121F: 3900,
  沪A69695F: 3900,
  粤AGF4535: 1500,
  沪A65889F: 3900,
  浙F08991F: 3000,
  浙F05580F: 3900,
  沪A50990F: 3900,
};

export const HYDROGEN_FEE_HEADER_TIP = '仅显示签订合同时氢费承担方式为「我司承担」的氢费在该账单期内的总和，取自车辆氢费明细所有状态的数据（包含未对账和已对账）';

/** 资产归属类型（内部） */
export const PLATE_ASSET_OWNERSHIP: Record<string, AssetOwnership> = {
  沪A32896F: '租赁',
  沪A61121F: '租赁',
  沪A69695F: '租赁',
  粤AGF4535: '租赁',
  沪A65889F: '自有',
  浙F08991F: '自有',
  浙F05580F: '挂靠',
  沪A50990F: '自有',
};

export const IS_SUPERVISOR = false;
export const CURRENT_STAFF_USER = '刘念念';

export const LOAD_BATCH_SIZE = 20;

export function formatMoney(value: number): string {
  return value.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}

/** 表格/卡片空值：不展示占位横杠 */
export function isBlankDisplayValue(value: unknown): boolean {
  return value === null
    || value === undefined
    || value === ''
    || value === '—'
    || value === '-'
    || value === '/';
}

export function displayText(value: unknown): string {
  if (isBlankDisplayValue(value)) return '';
  return String(value);
}

export function displayMoney(value: number | null | undefined, treatZeroAsEmpty = false): string {
  if (value === null || value === undefined) return '';
  if (treatZeroAsEmpty && value === 0) return '';
  return formatMoney(value);
}

export function calcUnreceived(row: Pick<LeaseLedgerRow, 'receivableTotal' | 'receivedAmount'>): number {
  return Math.round((row.receivableTotal - row.receivedAmount) * 100) / 100;
}

export function isUnpaidRow(row: LeaseLedgerRow): boolean {
  return row.status !== '已收款';
}

export function resolvePaymentMethod(cycleMonths: number): string {
  const map: Record<number, string> = {
    1: '月度预付',
    3: '季度预付',
    6: '半年预付',
    12: '年度预付',
  };
  return map[cycleMonths] ?? `每${cycleMonths}个月预付`;
}

export function calcMonthlyRent(contractRent: number): number {
  return contractRent;
}

export function calcReceivableRent(contractRent: number, cycleMonths: number): number {
  return Math.round(contractRent * cycleMonths * 100) / 100;
}

export function resolveStatusAfterReceipt(
  receivableTotal: number,
  receivedAmount: number,
): LeaseDetailStatus {
  if (receivedAmount >= receivableTotal) return '已收款';
  if (receivedAmount > 0) return '部分收款';
  return '已确认';
}

export function filterRecordsByRole(rows: LeaseLedgerRow[]): LeaseLedgerRow[] {
  if (IS_SUPERVISOR) return rows;
  return rows.filter((row) => row.maintainerName === CURRENT_STAFF_USER);
}

export function calcVehicleActualCost(standardCost: number, actualDays: number): number {
  return Math.round(standardCost * (actualDays / 30) * 100) / 100;
}

export function lookupBiMileage(
  plateNo: string,
  year: number,
  month: number,
  records: BiMileageRecord[],
): string {
  const hit = records.find((item) => item.plateNo === plateNo && item.year === year && item.month === month);
  return hit ? String(hit.mileageKm) : '';
}

export function sumHydrogenFeeForBill(
  row: Pick<LeaseLedgerRow, 'plateNo' | 'year' | 'month' | 'hydrogenBorneBy'>,
  records: HydrogenFeeRecord[],
): number {
  if (row.hydrogenBorneBy !== '我司承担') return 0;
  return records
    .filter((item) => item.plateNo === row.plateNo && item.year === row.year && item.month === row.month)
    .reduce((sum, item) => sum + item.amount, 0);
}

export function calcReceivedAmountFromReceipts(
  linkedIds: string[],
  receipts: { id: string; amount: number }[],
  receivableTotal: number,
): number {
  const total = receipts
    .filter((item) => linkedIds.includes(item.id))
    .reduce((sum, item) => sum + item.amount, 0);
  return Math.min(Math.round(total * 100) / 100, receivableTotal);
}

export function calcMaintenanceIncome(row: Pick<LeaseLedgerRow, 'maintenancePackageEnabled' | 'maintenanceUnitPricePerKm' | 'mileage'>): number {
  if (!row.maintenancePackageEnabled) return 0;
  return Math.round(row.maintenanceUnitPricePerKm * row.mileage * 100) / 100;
}

export function calcMonthlyIncome(
  row: Pick<LeaseLedgerRow, 'monthlyRent' | 'serviceFee' | 'mileageDeduction' | 'otherDeduction'>,
): number {
  return Math.round((row.monthlyRent + row.serviceFee - row.mileageDeduction - row.otherDeduction) * 100) / 100;
}

export function sumLinkedMaintenanceAmount(
  linkedIds: string[],
  orders: MaintenanceOrder[],
): number {
  return orders
    .filter((item) => linkedIds.includes(item.id) && item.bearBy === '客户承担')
    .reduce((sum, item) => sum + item.amount, 0);
}

export function sumLinkedAccidentSurcharge(
  linkedIds: string[],
  accidents: AccidentRecord[],
): number {
  return accidents
    .filter((item) => linkedIds.includes(item.id))
    .reduce((sum, item) => sum + item.insuranceSurcharge, 0);
}

export function needsMaintenanceLinkWarning(
  row: LeaseLedgerRow,
  orders: MaintenanceOrder[],
): boolean {
  if (!row.isLatestBill || !row.customerBearsMaintenance) return false;
  if (row.linkedMaintenanceIds.length > 0) return false;
  return orders.some((item) => item.plateNo === row.plateNo && item.bearBy === '客户承担');
}

export function needsAccidentLinkWarning(
  row: LeaseLedgerRow,
  accidents: AccidentRecord[],
): boolean {
  if (!row.isLatestBill) return false;
  if (row.linkedAccidentIds.length > 0) return false;
  return accidents.some((item) => item.plateNo === row.plateNo);
}

export function enrichLeaseRow(
  row: LeaseLedgerRow,
  options?: {
    maintenanceOrders?: MaintenanceOrder[];
    accidentRecords?: AccidentRecord[];
    biMileage?: BiMileageRecord[];
    hydrogenFees?: HydrogenFeeRecord[];
  },
): LeaseLedgerRow {
  const vehicle = PLATE_VEHICLE_MAP[row.plateNo];
  const contract = PLATE_CONTRACT_MAP[row.plateNo];
  const typeLine = row.vehicleType || '';
  let brand = row.vehicleBrand;
  let model = row.vehicleModel;
  if (!brand && typeLine) {
    const m = typeLine.match(/^([^\d/]+)(.*)$/);
    if (m?.[2]) {
      brand = m[1];
      model = m[2];
    } else {
      brand = typeLine;
      model = typeLine;
    }
  }

  const cycleMonths = row.paymentCycleMonths || 1;
  const contractRent = row.contractRent;
  const monthlyRent = calcMonthlyRent(contractRent);
  const receivableRent = calcReceivableRent(contractRent, cycleMonths);
  const hasReceipt = row.receivedAmount > 0 && row.actualPaymentDate;
  const maintenanceOrders = options?.maintenanceOrders ?? [];
  const accidentRecords = options?.accidentRecords ?? [];
  const biMileage = options?.biMileage ?? [];
  const hydrogenFees = options?.hydrogenFees ?? [];
  const linkedMaintenanceIds = row.linkedMaintenanceIds ?? [];
  const linkedAccidentIds = row.linkedAccidentIds ?? [];
  const linkedReceiptIds = row.linkedReceiptIds ?? [];
  const maintenanceIncome = calcMaintenanceIncome(row);
  const opsFeeIncome = sumLinkedMaintenanceAmount(linkedMaintenanceIds, maintenanceOrders);
  const opsFeeCost = opsFeeIncome;
  const insuranceSurcharge = linkedAccidentIds.length > 0
    ? sumLinkedAccidentSurcharge(linkedAccidentIds, accidentRecords)
    : row.insuranceSurcharge;
  const serviceFee = row.serviceFee ?? 0;
  const monthlyIncome = calcMonthlyIncome({
    monthlyRent,
    serviceFee,
    mileageDeduction: row.mileageDeduction,
    otherDeduction: row.otherDeduction,
  });
  const vehicleStandardCost = PLATE_STANDARD_COST[row.plateNo] ?? row.vehicleStandardCost;
  const vehicleActualCost = calcVehicleActualCost(vehicleStandardCost, row.avgDays || 30);
  const gpsMileage = lookupBiMileage(row.plateNo, row.year, row.month, biMileage) || row.gpsMileage;
  const hydrogenFeeSum = sumHydrogenFeeForBill(row, hydrogenFees);
  const hydrogenFee = row.hydrogenBorneBy === '我司承担' ? hydrogenFeeSum : row.hydrogenFee;
  const signingCompany = PLATE_SIGNING_COMPANY[row.plateNo] || row.signingCompany;
  const assetOwner = PLATE_ASSET_OWNER[row.plateNo] || row.assetOwner || '';

  return {
    ...row,
    vehicleBrand: brand || vehicle?.brand || '',
    vehicleModel: model || vehicle?.model || '',
    customerName: row.customerName || contract?.customerName || '',
    projectName: row.projectName || contract?.projectName || '',
    paymentCycleMonths: cycleMonths,
    paymentMethod: resolvePaymentMethod(cycleMonths),
    monthlyRent,
    receivableRent,
    serviceFee,
    linkedMaintenanceIds,
    linkedAccidentIds,
    linkedReceiptIds,
    maintenanceIncome,
    opsFeeIncome,
    opsFeeCost,
    insuranceSurcharge,
    monthlyIncome,
    vehicleStandardCost,
    vehicleActualCost,
    gpsMileage,
    hydrogenFee,
    signingCompany,
    assetOwner,
    assetOwnership: row.assetOwnership || PLATE_ASSET_OWNERSHIP[row.plateNo] || '自有',
    actualPaymentDate: hasReceipt ? row.actualPaymentDate : '',
  };
}

export function canStaffEditRow(row: LeaseLedgerRow): boolean {
  if (row.status === '草稿') return true;
  return IS_SUPERVISOR;
}

export function canStaffDeleteRow(row: LeaseLedgerRow): boolean {
  return canStaffEditRow(row);
}

export function sumLeaseKpi(rows: LeaseLedgerRow[]): LeaseKpiSummary {
  return rows.reduce(
    (acc, row) => ({
      count: acc.count + 1,
      receivableTotal: acc.receivableTotal + row.receivableTotal,
      receivedAmount: acc.receivedAmount + row.receivedAmount,
      unreceived: acc.unreceived + calcUnreceived(row),
      totalCost: acc.totalCost + row.totalCost,
      profitLoss: acc.profitLoss + row.profitLoss,
    }),
    { count: 0, receivableTotal: 0, receivedAmount: 0, unreceived: 0, totalCost: 0, profitLoss: 0 },
  );
}

export function applyLeaseFilters(rows: LeaseLedgerRow[], filters: LeaseLedgerFilters): LeaseLedgerRow[] {
  return rows.filter((row) => {
    if (filters.year && String(row.year) !== filters.year) return false;
    if (filters.month && String(row.month) !== filters.month) return false;
    if (filters.dept && row.dept !== filters.dept) return false;
    if (filters.salesman && row.salesman !== filters.salesman) return false;
    if (filters.plateNo && row.plateNo !== filters.plateNo) return false;
    if (filters.status && row.status !== filters.status) return false;
    if (filters.customerName && !row.customerName.includes(filters.customerName)) return false;
    if (filters.paymentFrom && row.paymentDate < filters.paymentFrom) return false;
    if (filters.paymentTo && row.paymentDate > filters.paymentTo) return false;
    return true;
  });
}

export function applyListViewFilter(
  rows: LeaseLedgerRow[],
  options: { showUnpaidOnly: boolean; listViewMode: ListViewMode },
): LeaseLedgerRow[] {
  if (!options.showUnpaidOnly && options.listViewMode === 'all') return rows;
  return rows.filter(isUnpaidRow);
}

export function buildLeaseOptions(rows: LeaseLedgerRow[], key: keyof LeaseLedgerRow): string[] {
  const set = new Set<string>();
  rows.forEach((row) => {
    const value = row[key];
    if (typeof value === 'string' && value.trim()) set.add(value);
    if (typeof value === 'number') set.add(String(value));
  });
  return Array.from(set).sort((a, b) => a.localeCompare(b, 'zh-CN'));
}

export function extractReceiptPaymentDate(arrivalTime: string): string {
  return arrivalTime.split(' ')[0] || '';
}

export function latestReceiptPaymentDate(arrivalTimes: string[]): string {
  const dates = arrivalTimes.map(extractReceiptPaymentDate).filter(Boolean).sort();
  return dates[dates.length - 1] ?? '';
}
