import { m } from '@/i18n/messages'
import { flagReason as flagReasonLabels } from '@/i18n/i18n-enum.gen'
import { useLocale, getLocale } from '@/i18n/config'
import { asI18n } from '@pikku/react'
import {
  Alert,
  Group,
  Progress,
  Stack,
  Stepper,
  Text,
} from '@pikku/mantine/core'
import { AlertTriangle, Clock } from 'lucide-react'
import { fmtDate } from '../lib/dates'
import type { BookingStatus } from '../lib/status'

// ─── Types ────────────────────────────────────────────────────────────────

type DepositInvoice = {
  invoiceId: string
  kind: string
  dueOn: Date | null
  paidOn: Date | null
  status: string
}

type BookingMilestones = {
  bookingId: string
  status: BookingStatus
  startDate: Date | null
  enquiryAt: Date
  reservedAt: Date | null
  confirmedAt: Date | null
  endedAt: Date | null
  cancelledAt: Date | null
  contractSentAt: Date | null
  contractResponse: string | null
  contractResponseAt: Date | null
  depositReminderSentAt: Date | null
  flaggedAt: Date | null
  flagReason: string | null
}

// ─── Helpers ──────────────────────────────────────────────────────────────

function berlinToday(): string {
  return new Date().toLocaleDateString('sv-SE', { timeZone: 'Europe/Berlin' })
}

function berlinDateStr(d: Date): string {
  return d.toLocaleDateString('sv-SE', { timeZone: 'Europe/Berlin' })
}

function daysBetween(from: Date, toYmd: string): number {
  return Math.round((Date.parse(toYmd) - from.getTime()) / 86_400_000)
}

function addDaysToDate(d: Date, n: number): Date {
  const result = new Date(d)
  result.setUTCDate(result.getUTCDate() + n)
  return result
}

type NextAction =
  | { kind: 'flagged'; reason: string }
  | { kind: 'awaiting_1yr' }
  | { kind: 'awaiting_signature' }
  | { kind: 'awaiting_deposit'; dueOn: Date | null }
  | { kind: 'contract_declined' }
  | null

function nextAction(booking: BookingMilestones, deposit: DepositInvoice | null): NextAction {
  const { status, flaggedAt, flagReason, contractSentAt, contractResponse } = booking
  if (status === 'cancelled' || status === 'ended' || status === 'confirmed' || status === 'enquiry') return null
  if (flaggedAt && flagReason === 'contract_declined') return { kind: 'contract_declined' }
  if (flaggedAt) return { kind: 'flagged', reason: flagReason ?? '' }
  if (status === 'reserved') {
    if (!contractSentAt) return { kind: 'awaiting_1yr' }
    if (!contractResponse) return { kind: 'awaiting_signature' }
    if (contractResponse === 'approved' && !deposit?.paidOn) return { kind: 'awaiting_deposit', dueOn: deposit?.dueOn ?? null }
  }
  return null
}

// ─── Sub-components ───────────────────────────────────────────────────────

function DepositProgress({ contractSentAt, deposit, lng }: {
  contractSentAt: Date
  deposit: DepositInvoice | null
  lng: string
}) {
  useLocale()
  const today = berlinToday()
  const daysSent = daysBetween(contractSentAt, today)
  const pct = Math.min(100, Math.round((daysSent / 14) * 100))
  const color = daysSent >= 14 ? 'red' : daysSent >= 7 ? 'yellow' : 'plum'
  const dueDate = deposit?.dueOn ?? addDaysToDate(contractSentAt, 14)
  const dueDateStr = berlinDateStr(dueDate)
  const overdue = !deposit?.paidOn && dueDateStr < today

  return (
    <Stack gap={4}>
      <Group justify="space-between">
        <Text size="xs" fw={500}>
          {deposit?.paidOn
            ? m.common__pages__admin_booking__status__milestones__deposit_paid()
            : overdue
              ? m.common__pages__admin_booking__status__deposit_overdue()
              : m.common__pages__admin_booking__status__deposit_window({ day: daysSent })}
        </Text>
        {deposit?.paidOn ? null : (
          <Text size="xs" c="dimmed">
            {m.common__pages__admin_booking__status__due_on({ date: fmtDate(dueDate, lng) })}
          </Text>
        )}
      </Group>
      {!deposit?.paidOn && (
        <Progress value={pct} color={color} size="sm" radius="xl" />
      )}
    </Stack>
  )
}

// ─── Main component ───────────────────────────────────────────────────────

export function BookingStatusPanel({
  booking,
  invoices,
}: {
  booking: BookingMilestones
  invoices: DepositInvoice[]
}) {
  useLocale()
  const lng = getLocale()

  const deposit = invoices.find(inv => inv.kind === 'deposit') ?? null

  const action = nextAction(booking, deposit)

  // ── Stepper steps ──
  const steps = [
    {
      key: 'enquiry',
      label: m.common__pages__admin_booking__status__milestones__enquiry(),
      description: fmtDate(booking.enquiryAt, lng),
      done: true,
    },
    {
      key: 'reserved',
      label: m.common__pages__admin_booking__status__milestones__reserved(),
      description: booking.reservedAt ? fmtDate(booking.reservedAt, lng) : null,
      done: ['reserved', 'confirmed', 'ended'].includes(booking.status),
    },
    {
      key: 'contractSent',
      label: m.common__pages__admin_booking__status__milestones__contract_sent(),
      description: booking.contractSentAt ? fmtDate(booking.contractSentAt, lng) : null,
      done: !!booking.contractSentAt,
    },
    {
      key: 'contractSigned',
      label: m.common__pages__admin_booking__status__milestones__contract_signed(),
      description: booking.contractResponseAt && booking.contractResponse === 'approved'
        ? fmtDate(booking.contractResponseAt, lng) : null,
      done: booking.contractResponse === 'approved',
    },
    {
      key: 'depositPaid',
      label: m.common__pages__admin_booking__status__milestones__deposit_paid(),
      description: deposit?.paidOn ? fmtDate(deposit.paidOn, lng) : null,
      done: !!deposit?.paidOn,
    },
    {
      key: 'confirmed',
      label: m.common__pages__admin_booking__status__milestones__confirmed(),
      description: booking.confirmedAt ? fmtDate(booking.confirmedAt, lng) : null,
      done: ['confirmed', 'ended'].includes(booking.status),
    },
    {
      key: 'ended',
      label: m.common__pages__admin_booking__status__milestones__ended(),
      description: booking.endedAt ? fmtDate(booking.endedAt, lng) : null,
      done: booking.status === 'ended',
    },
  ]

  const activeStep = (() => {
    switch (booking.status) {
      case 'ended': return steps.length              // all steps get checkmarks
      case 'confirmed': return steps.length - 1      // "ended" step is current
      case 'cancelled': return steps.reduce((acc, s, i) => (s.done ? i : acc), -1)
      default: return steps.findIndex(s => !s.done)  // enquiry/reserved: use milestone data
    }
  })()

  return (
    <Stack gap="md">
      {/* Flagged alert */}
      {booking.flaggedAt && booking.flagReason && (
        <Alert color="red" icon={<AlertTriangle size={16} />} title={m.common__pages__admin_booking__status__flagged()}>
          {booking.flagReason in flagReasonLabels
            ? flagReasonLabels[booking.flagReason as keyof typeof flagReasonLabels]()
            : asI18n(booking.flagReason)}
        </Alert>
      )}

        {/* ── Horizontal stepper ── */}
        <Stepper
          active={activeStep}
          color={booking.status === 'cancelled' ? 'red' : 'plum'}
          size="xs"
          styles={{ stepLabel: { fontSize: 'var(--mantine-font-size-xs)' }, stepDescription: { fontSize: 'var(--mantine-font-size-xs)' } }}
        >
          {steps.map((step) => (
            <Stepper.Step
              key={step.key}
              label={step.label}
              description={asI18n(step.description ?? 'N/A')}
            />
          ))}
          {booking.status === 'cancelled' && (
            <Stepper.Step
              key="cancelled"
              color="red"
              label={m.common__pages__admin_booking__status__milestones__cancelled()}
              description={booking.cancelledAt ? asI18n(fmtDate(booking.cancelledAt, lng)) : undefined}
            />
          )}
        </Stepper>

        {/* Deposit progress bar (when contract sent but deposit not yet paid) */}
        {booking.contractSentAt && !deposit?.paidOn && (
          <DepositProgress contractSentAt={booking.contractSentAt} deposit={deposit} lng={lng} />
        )}

        {/* ── Next action alert (informational; controls live in BookingActions) ── */}
        {action && (
          <Alert
            color={
              action.kind === 'flagged' || action.kind === 'contract_declined' ? 'red'
                : action.kind === 'awaiting_deposit' ? 'orange'
                  : 'blue'
            }
            icon={<Clock size={16} />}
          >
            {action.kind === 'flagged' &&
              (action.reason in flagReasonLabels
                ? flagReasonLabels[action.reason as keyof typeof flagReasonLabels]()
                : asI18n(action.reason))}
            {action.kind === 'awaiting_1yr' && m.common__pages__admin_booking__status__contract_not_sent_yet({
              date: booking.startDate ? fmtDate(addDaysToDate(booking.startDate, -365), lng) : '—',
            })}
            {action.kind === 'awaiting_signature' && m.common__pages__admin_booking__status__awaiting_signature()}
            {action.kind === 'awaiting_deposit' && (
              <>
                {m.common__pages__admin_booking__status__awaiting_deposit()}
                {action.dueOn && (
                  <Text size="xs" mt={2}>
                    {m.common__pages__admin_booking__status__due_on({ date: fmtDate(action.dueOn, lng) })}
                  </Text>
                )}
              </>
            )}
            {action.kind === 'contract_declined' && flagReasonLabels.contract_declined()}
          </Alert>
        )}
    </Stack>
  )
}
