import type { Permit, Trip, WarningKind, WarningSeverity } from '@/types/db'

export interface ComputedWarning {
  kind: WarningKind
  severity: WarningSeverity
  message: string
  permitId?: string
}

const EXPIRY_SOON_DAYS = 3

function fmtIn(inches: number): string {
  const ft = Math.floor(inches / 12)
  const rem = inches % 12
  return `${ft}'${rem}"`
}

/**
 * Compare load dimensions against a permit's allowed dimensions and validity
 * dates. Mirrors the checks Nash demoed ("dimensions warning — in one state
 * you have the wrong dimensions") and the analysis doc §5.
 */
type SiblingPermit = Pick<Permit, 'id' | 'state_code' | 'effective_date' | 'expiration_date'>

export function computePermitWarnings(
  trip: Pick<Trip, 'load_length_in' | 'load_width_in' | 'load_height_in' | 'load_weight_lbs'> &
    Partial<
      Pick<
        Trip,
        'overall_length_in' | 'overall_width_in' | 'overall_height_in' | 'overall_weight_lbs'
      >
    >,
  permit: Pick<
    Permit,
    | 'id'
    | 'state_code'
    | 'permit_length_in'
    | 'permit_width_in'
    | 'permit_height_in'
    | 'permit_weight_lbs'
    | 'effective_date'
    | 'expiration_date'
  >,
  today: Date = new Date(),
  // Nash's multiple-permits rule: an expired permit raises no alert when
  // ANOTHER still-valid permit exists for the same state on this trip.
  allPermits?: SiblingPermit[],
): ComputedWarning[] {
  const warnings: ComputedWarning[] = []
  const state = permit.state_code || 'permit'

  // Permits are checked against the OVERALL (truck + trailer) dimensions;
  // when overall values are not set yet, fall back to the load dimensions.
  const dims: Array<[string, number | null, number | null, (v: number) => string]> = [
    ['width', trip.overall_width_in ?? trip.load_width_in, permit.permit_width_in, fmtIn],
    ['height', trip.overall_height_in ?? trip.load_height_in, permit.permit_height_in, fmtIn],
    ['length', trip.overall_length_in ?? trip.load_length_in, permit.permit_length_in, fmtIn],
    [
      'weight',
      trip.overall_weight_lbs ?? trip.load_weight_lbs,
      permit.permit_weight_lbs,
      (v) => `${v.toLocaleString()} lbs`,
    ],
  ]

  const hasOverall =
    trip.overall_width_in != null ||
    trip.overall_height_in != null ||
    trip.overall_length_in != null ||
    trip.overall_weight_lbs != null
  const against = hasOverall ? 'overall' : 'load'

  for (const [label, tripValue, permitValue, fmt] of dims) {
    if (tripValue != null && permitValue != null && permitValue < tripValue) {
      warnings.push({
        kind: 'dimension_mismatch',
        severity: 'danger',
        permitId: permit.id,
        message: `${state}: permit ${label} ${fmt(permitValue)} is smaller than ${against} ${label} ${fmt(tripValue)}. Review before movement.`,
      })
    }
  }

  // Nash (2026-09-04): a duplicate permit for the same state that is still
  // valid suppresses the expiration alert on the expired one.
  const otherValidSameState =
    !!permit.state_code &&
    (allPermits ?? []).some(
      (p) =>
        p.id !== permit.id &&
        p.state_code === permit.state_code &&
        (!p.effective_date || new Date(p.effective_date + 'T00:00:00') <= today) &&
        (!p.expiration_date || new Date(p.expiration_date + 'T23:59:59') >= today),
    )

  if (permit.expiration_date && !otherValidSameState) {
    const exp = new Date(permit.expiration_date + 'T23:59:59')
    const msLeft = exp.getTime() - today.getTime()
    if (msLeft < 0) {
      warnings.push({
        kind: 'expired',
        severity: 'danger',
        permitId: permit.id,
        message: `${state}: permit appears expired (${permit.expiration_date}). Do not rely on it without verification.`,
      })
    } else if (msLeft < EXPIRY_SOON_DAYS * 24 * 3600 * 1000) {
      warnings.push({
        kind: 'expiring',
        severity: 'warning',
        permitId: permit.id,
        message: `${state}: permit expires soon (${permit.expiration_date}).`,
      })
    }
  }

  // Nash (2026-09-04): NO "not effective yet" alerts — "this is not a very
  // important alert." Removed permanently.
  //
  // TODO(backend) — the ONLY valid effective-dates alert, location-aware:
  // fire when (a) the permit's state is the driver's CURRENT state or a
  // FUTURE state on the path, AND (b) that permit is expired, AND (c) no
  // other still-valid permit exists for the SAME state on this trip
  // (rule (c) is applied above already). Passed states never alert. Needs
  // real driver location (geolocation backend).

  return warnings
}
