'use client';

import { useState } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { LogIn, ListCollapse, Trash2, Printer, Package } from 'lucide-react';
import { Download } from 'lucide-react';
import DataTable from '@/components/ui/DataTable';
import Badge from '@/components/ui/Badge';
import ActionButton from '@/components/ui/ActionButton';
import ConfirmDialog from '@/components/ui/ConfirmDialog';
import Modal from '@/components/ui/Modal';
import Image from 'next/image';
import { ticketsApi, apiClient, stationsApi, excessBaggageApi, bookingsApi } from '@/lib/api';
import Pagination from '@/components/ui/Pagination';
import { formatDateTime, formatCurrency, formatDateTimeShort } from '@/lib/utils';
import { useAuthStore } from '@/lib/auth-store';

export default function TicketsPage() {
  const [filters, setFilters] = useState({ search: '', status: '', originStationId: '', destinationStationId: '', departureDate: '', arrivalDate: '', dateFrom: '', dateTo: '', coachId: '' });
  const [ticketPage, setTicketPage] = useState(1);
  const resetTicketPage = () => setTicketPage(1);
  const PAGE_SIZE = 50;
  const [deleteConfirmOpen, setDeleteConfirmOpen] = useState(false);
  const [ticketToDelete, setTicketToDelete] = useState<any>(null);
  const [deleteError, setDeleteError] = useState<string | null>(null);
  const [boardConfirmOpen, setBoardConfirmOpen] = useState(false);
  const [ticketToBoard, setTicketToBoard] = useState<any>(null);
  const [printBpModalOpen, setPrintBpModalOpen] = useState(false);
  const [ticketToPrint, setTicketToPrint] = useState<any>(null);
  const [successMessage, setSuccessMessage] = useState('');
  const [detailsModalOpen, setDetailsModalOpen] = useState(false);
  const [selectedTicket, setSelectedTicket] = useState<any>(null);

  const [showExtraFilters, setShowExtraFilters] = useState(false);
  const [exportFormat, setExportFormat] = useState<'csv' | 'excel' | 'pdf'>('csv');

  const { user } = useAuthStore();
  const [excessModalOpen, setExcessModalOpen] = useState(false);
  const [excessTicket, setExcessTicket] = useState<any>(null);
  const [excessKg, setExcessKg] = useState('');
  const [excessCollectCash, setExcessCollectCash] = useState(false);
  const [excessError, setExcessError] = useState<string | null>(null);
  const [excessResult, setExcessResult] = useState<any>(null);

  const Field = ({ label, value, mono = false, truncate = false }: { label: string; value: string; mono?: boolean; truncate?: boolean }) => (
    <div className="bg-muted/40 rounded-lg p-3">
      <p className="text-xs text-muted-foreground mb-1">{label}</p>
      <p className={`text-sm font-semibold text-foreground${mono ? ' font-mono' : ''}${truncate ? ' truncate' : ''}`} title={value}>{value || '—'}</p>
    </div>
  );

  const SectionHeader = ({ title }: { title: string }) => (
    <h3 className="text-xs font-bold uppercase tracking-widest text-muted-foreground mb-3 flex items-center gap-2">
      <span className="w-4 h-px bg-muted-foreground/40 inline-block" />{title}
    </h3>
  );
  const [exportModalOpen, setExportModalOpen] = useState(false);
  const [exportDateFrom, setExportDateFrom] = useState('');
  const [exportDateTo, setExportDateTo] = useState('');
  const [selectedColumns, setSelectedColumns] = useState<Record<string, boolean>>({
    ticketNumber: true,
    booking: true,
    trip: true,
    seat: true,
    seatClass: true,
    amount: true,
    status: true,
  });
  const queryClient = useQueryClient();

  const { data, isLoading, error } = useQuery({
    queryKey: ['tickets', filters, ticketPage],
    queryFn: () => ticketsApi.getAll({
      search: filters.search || undefined,
      status: filters.status || undefined,
      originStationId: filters.originStationId || undefined,
      destinationStationId: filters.destinationStationId || undefined,
      departureDate: filters.departureDate || undefined,
      arrivalDate: filters.arrivalDate || undefined,
      dateFrom: filters.dateFrom || undefined,
      dateTo: filters.dateTo || undefined,
      coachId: filters.coachId || undefined,
      skip: (ticketPage - 1) * PAGE_SIZE,
      take: PAGE_SIZE,
    }),
  });

  const ticketMeta = (data as any)?.meta;
  const ticketTotalPages = ticketMeta ? ticketMeta.totalPages : Math.max(1, Math.ceil(((data as any)?.total ?? (data?.items?.length ?? 0)) / PAGE_SIZE));

  const { data: stationsData } = useQuery({
    queryKey: ['stations'],
    queryFn: () => stationsApi.getAll(),
  });

  const { data: coachesData } = useQuery({
    queryKey: ['coaches'],
    queryFn: () => apiClient.get('/fleet/coaches'),
  });

  const [generateMissingResult, setGenerateMissingResult] = useState<any>(null);

  const { data: hasMissingTickets } = useQuery({
    queryKey: ['bookings-missing-tickets'],
    queryFn: async () => {
      const res = await bookingsApi.getAll({ status: 'CONFIRMED', paymentStatus: 'SUCCEEDED', take: 50 });
      const items: any[] = (res as any)?.items ?? (Array.isArray(res) ? res : []);
      return items.some((b: any) => !b.tickets?.length);
    },
    refetchInterval: 30_000,
  });

  const generateMissingMutation = useMutation({
    mutationFn: async () => {
      let totalGenerated = 0;
      let totalFailed = 0;
      let totalProcessed = 0;
      let remaining = 1;

      while (remaining > 0) {
        const result: any = await ticketsApi.generateMissing(10);
        totalGenerated += result.generated ?? 0;
        totalFailed += result.failed ?? 0;
        totalProcessed += result.processed ?? 0;
        remaining = result.remaining ?? 0;
      }

      return { generated: totalGenerated, processed: totalProcessed, failed: totalFailed };
    },
    onSuccess: (result: any) => {
      queryClient.invalidateQueries({ queryKey: ['tickets'] });
      queryClient.invalidateQueries({ queryKey: ['bookings-missing-tickets'] });
      setGenerateMissingResult(result);
      setSuccessMessage(`Generated ${result.generated} ticket(s) for ${result.processed} booking(s)${result.failed ? ` (${result.failed} failed)` : ''}`);
      setTimeout(() => setSuccessMessage(''), 6000);
    },
    onError: (error: any) => {
      alert(error?.response?.data?.message || error?.message || 'Failed to generate missing tickets');
    },
  });

  const boardMutation = useMutation({
    mutationFn: ({ ticketId, leg }: { ticketId: string; leg?: 'outbound' | 'inbound' }) =>
      ticketsApi.validate(ticketId, { status: 'USED', boardedAt: new Date().toISOString(), leg: leg === 'inbound' ? 'RETURN' : 'OUTBOUND' }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['tickets'] });
      setBoardConfirmOpen(false);
      setTicketToBoard(null);
      setSuccessMessage('Ticket boarded successfully');
      setTimeout(() => setSuccessMessage(''), 3000);
    },
    onError: (error: any) => {
      alert(`Error: ${error.message || 'Failed to board ticket'}`);
    },
  });

  const excessMutation = useMutation({
    mutationFn: (data: any) => excessBaggageApi.logCharge(data),
    onSuccess: (result) => {
      setExcessResult(result);
      setExcessError(null);
    },
    onError: (e: any) => setExcessError(e?.response?.data?.message || e?.message || 'Failed to log charge'),
  });

  const openExcessModal = (ticket: any) => {
    setExcessTicket(ticket);
    setExcessKg('');
    setExcessCollectCash(false);
    setExcessError(null);
    setExcessResult(null);
    setExcessModalOpen(true);
  };

  const handleExcessSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!excessTicket) return;
    await excessMutation.mutateAsync({
      bookingId: excessTicket.booking?.id ?? excessTicket.bookingId,
      excessWeightKg: parseInt(excessKg),
      collectCash: excessCollectCash,
    });
  };

  const deleteMutation = useMutation({
    mutationFn: (id: string) => apiClient.delete(`/tickets/${id}`),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['tickets'] });
      setDeleteConfirmOpen(false);
      setTicketToDelete(null);
      setDeleteError(null);
      setSuccessMessage('Ticket deleted successfully');
      setTimeout(() => setSuccessMessage(''), 3000);
    },
    onError: (error: any) => {
      setDeleteError(error?.response?.data?.message || error?.message || 'Failed to delete ticket');
    },
  });

  const restoreMutation = useMutation({
    mutationFn: (id: string) => apiClient.patch(`/tickets/${id}/restore`, {}),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['tickets'] });
      setSuccessMessage('Ticket restored successfully');
      setTimeout(() => setSuccessMessage(''), 3000);
    },
    onError: (error: any) => alert(error?.response?.data?.message || error?.message || 'Failed to restore ticket'),
  });

  const handleBoard = (ticket: any) => {
    setTicketToBoard(ticket);
    setBoardConfirmOpen(true);
  };

  const handleConfirmBoard = async () => {
    if (!ticketToBoard) return;
    const isRoundTrip = ticketToBoard.booking?.bookingType === 'ROUND_TRIP' || ticketToBoard.booking?.bookingType === 'ROUND_TRIP_TRANSIT';
    const outboundDone = !!ticketToBoard.validatedAt || !!ticketToBoard.booking?.outboundBoardedAt;
    const leg: 'outbound' | 'inbound' = isRoundTrip && outboundDone ? 'inbound' : 'outbound';
    await boardMutation.mutateAsync({ ticketId: ticketToBoard.id, leg });
    printBoardingPass(ticketToBoard, leg);
  };

  const printBoardingPass = (ticket: any, leg: 'outbound' | 'inbound' = 'outbound') => {
    const w = window.open('', '_blank', 'width=520,height=460');
    if (!w) return;
    const isInbound = leg === 'inbound';
    const origin = isInbound
      ? (ticket.booking?.returnOriginStation?.name || ticket.schedule?.destinationStation?.name || 'N/A')
      : (ticket.schedule?.originStation?.name || 'N/A');
    const dest = isInbound
      ? (ticket.booking?.returnDestinationStation?.name || ticket.schedule?.originStation?.name || 'N/A')
      : (ticket.schedule?.destinationStation?.name || 'N/A');
    const date = isInbound
      ? (ticket.booking?.returnBoardedAt ? new Date(ticket.booking.returnBoardedAt).toLocaleString() : 'N/A')
      : (ticket.schedule?.departureAt ? new Date(ticket.schedule.departureAt).toLocaleString() : 'N/A');
    const seat = ticket.seat?.seatNumber || 'N/A';
    const coach = ticket.seat?.coach?.number || 'N/A';
    const bookingRef = ticket.booking?.bookingRef || 'N/A';
    const ticketNum = ticket.ticketNumber || 'N/A';
    const passenger = ticket.booking?.passenger?.fullName || ticket.booking?.seats?.[0]?.passengerName || ticket.passengerName || 'Guest';
    w.document.write(
      '<!DOCTYPE html><html><head><meta charset="utf-8"/><title>Boarding Pass</title><style>' +
      '*{box-sizing:border-box;margin:0;padding:0}' +
      'body{font-family:"Segoe UI",sans-serif;background:#f0fdf4;display:flex;align-items:center;justify-content:center;min-height:100vh;padding:24px}' +
      '.pass{background:#fff;border-radius:16px;overflow:hidden;box-shadow:0 8px 32px rgba(0,0,0,.12);width:460px}' +
      '.header{background:linear-gradient(135deg,#10b981,#059669);color:#fff;padding:24px 28px 20px}' +
      '.header-top{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}' +
      '.airline{font-size:12px;letter-spacing:2px;text-transform:uppercase;opacity:.85}' +
      '.badge{background:rgba(255,255,255,.2);border-radius:20px;padding:3px 12px;font-size:11px;letter-spacing:1px}' +
      '.route{display:flex;align-items:center;gap:8px;margin-top:14px}' +
      '.city{font-size:24px;font-weight:700}' +
      '.arrow{font-size:20px;opacity:.7;flex:1;text-align:center}' +
      '.body{padding:24px 28px}' +
      '.grid{display:grid;grid-template-columns:1fr 1fr;gap:16px}' +
      '.field label{font-size:10px;text-transform:uppercase;letter-spacing:1px;color:#6b7280;font-weight:600}' +
      '.field p{font-size:14px;font-weight:600;color:#111827;margin-top:3px}' +
      '.divider{border:none;border-top:2px dashed #d1fae5;margin:20px 0}' +
      '.footer{display:flex;justify-content:space-between;align-items:center}' +
      '.seat-box{background:#f0fdf4;border:2px solid #10b981;border-radius:10px;padding:8px 20px;text-align:center}' +
      '.seat-box label{font-size:10px;letter-spacing:1px;text-transform:uppercase;color:#059669;font-weight:700}' +
      '.seat-box p{font-size:28px;font-weight:800;color:#065f46}' +
      '@media print{body{background:#fff}.pass{box-shadow:none}}' +
      '</style></head><body>' +
      '<div class="pass">' +
        '<div class="header">' +
          '<div class="header-top"><span class="airline">EDR &mdash; Ethio-Djibouti Railway</span><span class="badge">BOARDING PASS</span></div>' +
          '<div class="route"><span class="city">' + origin + '</span><span class="arrow">&#129122;</span><span class="city">' + dest + '</span></div>' +
        '</div>' +
        '<div class="body">' +
          '<div class="grid">' +
            '<div class="field"><label>Booking Ref</label><p>' + bookingRef + '</p></div>' +
            '<div class="field"><label>Ticket No.</label><p>' + ticketNum + '</p></div>' +
            '<div class="field"><label>Date &amp; Time</label><p>' + date + '</p></div>' +
            '<div class="field"><label>Coach</label><p>' + coach + '</p></div>' +
          '</div>' +
          '<hr class="divider"/>' +
          '<div class="footer">' +
            '<div class="field"><label>Passenger</label><p>' + passenger + '</p></div>' +
            '<div class="seat-box"><label>Seat</label><p>' + seat + '</p></div>' +
          '</div>' +
        '</div>' +
      '</div>' +
      '</body></html>'
    );
    w.document.close();
    // Drive printing from the opener rather than an inline <script> in the popup — the
    // about:blank window inherits this page's CSP, which blocks non-nonced inline scripts.
    w.focus();
    w.onafterprint = () => w.close();
    w.print();
  };

  const handleDeleteClick = (ticket: any) => {
    setTicketToDelete(ticket);
    setDeleteError(null);
    setDeleteConfirmOpen(true);
  };

  const handleConfirmDelete = async () => {
    if (ticketToDelete) {
      await deleteMutation.mutateAsync(ticketToDelete.id);
    }
  };

  const TICKET_COLS = [
    { key: 'ticketNumber', label: 'Ticket Number' },
    { key: 'booking',      label: 'Booking Reference' },
    { key: 'passenger',    label: 'Passenger Name' },
    { key: 'trip',         label: 'Trip (Origin - Destination)' },
    { key: 'coach',        label: 'Coach Number' },
    { key: 'seat',         label: 'Seat Number' },
    { key: 'seatClass',    label: 'Seat Class' },
    { key: 'amount',       label: 'Amount' },
    { key: 'status',       label: 'Status' },
    { key: 'boarded',      label: 'Boarded' },
  ];

  const confirmExport = async () => {
    const cols = Object.entries(selectedColumns).filter(([, v]) => v).map(([k]) => k);
    if (!cols.length) { alert('Please select at least one column'); return; }
    const allData = await ticketsApi.getAll({ search: filters.search || undefined, status: filters.status || undefined, skip: 0, take: 9999 });
    const exportItems = (allData?.items || []).filter((ticket: any) => {
      if (!exportDateFrom && !exportDateTo) return true;
      const d = ticket.schedule?.arrivalAt ? new Date(ticket.schedule.arrivalAt).toISOString().split('T')[0] : null;
      if (exportDateFrom && (!d || d < exportDateFrom)) return false;
      if (exportDateTo && (!d || d > exportDateTo)) return false;
      return true;
    });
    const headers = TICKET_COLS.filter(c => cols.includes(c.key)).map(c => c.label);
    const rows = exportItems.map((ticket: any) =>
      TICKET_COLS.filter(c => cols.includes(c.key)).map(({ key }) => {
        switch (key) {
          case 'ticketNumber': return ticket.ticketNumber || 'N/A';
          case 'booking':      return ticket.booking?.bookingRef || 'N/A';
          case 'passenger':    return ticket.passengerName || ticket.booking?.seats?.[0]?.passengerName || ticket.booking?.passenger?.fullName || 'Guest';
          case 'trip':         return (ticket.schedule?.originStation?.name || 'N/A') + ' - ' + (ticket.schedule?.destinationStation?.name || 'N/A');
          case 'coach':        return ticket.seat?.coach?.number || 'N/A';
          case 'seat':         return ticket.seat?.seatNumber || 'N/A';
          case 'seatClass':    return ticket.seat?.coach?.coachType?.type || 'N/A';
          case 'amount':       return formatCurrency((ticket.booking?.totalMinor || 0), ticket.booking?.currency || 'ETB');
          case 'status':       return ticket.status || 'N/A';
          case 'boarded':      return ticket.boardedAt ? 'Yes' : 'No';
          default: return '';
        }
      })
    );
    const dateStr = new Date().toISOString().split('T')[0];
    if (exportFormat === 'pdf') {
      const w = window.open('', '_blank')!;
      w.document.write('<!DOCTYPE html><html><head><title>Tickets Export</title><style>body{font-family:sans-serif;font-size:11px}table{border-collapse:collapse;width:100%}th,td{border:1px solid #ccc;padding:4px 8px}th{background:#10b981;color:#fff}</style></head><body>');
      w.document.write('<h2>Tickets Export - ' + dateStr + '</h2><table><thead><tr>' + headers.map(h => '<th>' + h + '</th>').join('') + '</tr></thead><tbody>');
      rows.forEach((r: string[]) => { w.document.write('<tr>' + r.map((v: string) => '<td>' + v + '</td>').join('') + '</tr>'); });
      w.document.write('</tbody></table></body></html>');
      w.document.close(); w.print();
    } else if (exportFormat === 'excel') {
      const tsv = [headers.join('	'), ...rows.map((r: string[]) => r.join('	'))].join('\n');
      const blob = new Blob([tsv], { type: 'application/vnd.ms-excel' });
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a'); a.href = url; a.download = 'tickets-' + dateStr + '.xls'; a.click();
    } else {
      const csv = [headers.map((h: string) => '"' + h + '"').join(','), ...rows.map((r: string[]) => r.map((v: string) => '"' + v + '"').join(','))].join('\n');
      const blob = new Blob([csv], { type: 'text/csv' });
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement('a'); a.href = url; a.download = 'tickets-' + dateStr + '.csv'; a.click();
    }
    setExportModalOpen(false);
  };

  const columns = [
    {
      key: 'ticketNumber',
      label: 'Ticket Number',
      sortable: true,
      render: (ticket: any) => {
        const passengerName = ticket.passengerName || 
                             ticket.booking?.seats?.[0]?.passengerName || 
                             ticket.booking?.passenger?.fullName || 
                             'Guest';
        return (
          <div>
            <div className="font-mono font-semibold">{ticket.ticketNumber || 'N/A'}</div>
            <div className="text-sm text-muted-foreground">
              {passengerName}
            </div>
          </div>
        );
      },
    },
    {
      key: 'contact',
      label: 'Contact',
      render: (ticket: any) => {
        const phone = ticket.booking?.contactPhone || ticket.booking?.passenger?.phone || '—';
        const email = ticket.booking?.contactEmail || ticket.booking?.passenger?.email || '—';
        return (
          <div>
            <div className="font-medium">{phone}</div>
            <div className="text-xs text-muted-foreground truncate" title={email}>{email}</div>
          </div>
        );
      },
    },
    {
      key: 'trip',
      label: 'Trip',
      render: (ticket: any) => {
        const isRoundTrip = ticket.booking?.bookingType === 'ROUND_TRIP' || ticket.booking?.bookingType === 'ROUND_TRIP_TRANSIT';
        const returnDeparture = ticket.booking?.returnSchedule?.departureAt;
        const origin = ticket.booking?.originStation?.name || ticket.schedule?.originStation?.name || 'N/A';
        const destination = ticket.booking?.destinationStation?.name || ticket.schedule?.destinationStation?.name || 'N/A';

        return (
          <div>
            <div className="font-medium">
              {origin} → {destination}
            </div>
            <div className="text-xs text-muted-foreground">
              {!isRoundTrip ? (
                <span>{ticket.schedule?.departureAt ? formatDateTimeShort(ticket.schedule.departureAt) : 'N/A'}</span>
              ) : (
                <span>
                  {ticket.schedule?.departureAt ? formatDateTimeShort(ticket.schedule.departureAt) : 'N/A'} · 
                  {returnDeparture ? formatDateTimeShort(returnDeparture) : 'N/A'}
                </span>
              )}
            </div>
          </div>
        );
      },
    },
    {
      key: 'seat',
      label: 'Seat/Bed',
      sortable: true,
      render: (ticket: any) => {
        const isRoundTrip = ticket.booking?.bookingType === 'ROUND_TRIP' || ticket.booking?.bookingType === 'ROUND_TRIP_TRANSIT';
        
        if (isRoundTrip) {
          // Find seats for THIS specific passenger based on passengerName
          const passengerSeats = ticket.booking?.seats?.filter((s: any) => s.passengerName === ticket.passengerName) || [];
          const outboundSeat = passengerSeats.find((s: any) => s.leg === 1);
          const returnSeat = passengerSeats.find((s: any) => s.leg === 2);
          
          return (
            <div className="space-y-1">
              <div className="font-mono font-semibold text-sm">
                ➡ {outboundSeat?.seat?.coach?.number || 'N/A'}: {outboundSeat?.seat?.seatNumber || 'N/A'}
              </div>
              <div className="font-mono text-sm text-muted-foreground">
                ⬅ {returnSeat?.seat?.coach?.number || 'N/A'}: {returnSeat?.seat?.seatNumber || 'N/A'}
              </div>
            </div>
          );
        }
        
        // For one-way, show the ticket's primary seat
        return (
          <div>
            <div className="font-mono font-semibold">{ticket.seat?.coach?.number || 'N/A'}: {ticket.seat?.seatNumber || 'N/A'}</div>
            <div className="text-xs text-muted-foreground">{ticket.seat?.coach?.coachType?.type || 'N/A'}</div>
          </div>
        );
      },
    },
    {
      key: 'arrivalDate',
      label: 'Arrival Date',
      render: (ticket: any) => {
        const isRoundTrip = ticket.booking?.bookingType === 'ROUND_TRIP' || ticket.booking?.bookingType === 'ROUND_TRIP_TRANSIT';
        const outboundArrival = ticket.schedule?.arrivalAt;
        const returnArrival = ticket.booking?.returnSchedule?.arrivalAt;
        
        if (!isRoundTrip) {
          return (
            <span className="text-sm">
              {outboundArrival ? new Date(outboundArrival).toLocaleDateString() : '—'}
            </span>
          );
        }
        
        return (
          <div className="flex flex-col gap-0.5 text-sm">
            <span>➡ {outboundArrival ? new Date(outboundArrival).toLocaleDateString() : '—'}</span>
            <span>⬅ {returnArrival ? new Date(returnArrival).toLocaleDateString() : '—'}</span>
          </div>
        );
      },
    },
    {
      key: 'boardingTimes',
      label: 'Boarding Times',
      render: (ticket: any) => {
        const isRoundTrip = ticket.booking?.bookingType === 'ROUND_TRIP' || ticket.booking?.bookingType === 'ROUND_TRIP_TRANSIT';
        const outbound = ticket.booking?.outboundBoardedAt || ticket.validatedAt;
        const inbound = ticket.booking?.returnBoardedAt;
        
        if (!isRoundTrip) {
          // One-way tickets: only show outbound status
          return (
            <span className={`text-sm ${outbound ? 'text-green-600 dark:text-green-400' : 'text-muted-foreground'}`}>
              {outbound ? formatDateTimeShort(outbound) : 'Not boarded'}
            </span>
          );
        }
        
        // Round-trip tickets: show both legs
        const hasAny = outbound || inbound;
        if (!hasAny) return <span className="text-sm text-muted-foreground">Not boarded</span>;
        return (
          <div className="flex flex-col gap-0.5 text-sm">
            <span className={outbound ? 'text-green-600 dark:text-green-400' : 'text-muted-foreground'}>
              ➡ {outbound ? formatDateTimeShort(outbound) : 'Not boarded'}
            </span>
            <span className={inbound ? 'text-green-600 dark:text-green-400' : 'text-muted-foreground'}>
              ⬅ {inbound ? formatDateTimeShort(inbound) : 'Not boarded'}
            </span>
          </div>
        );
      },
    },
  ];

  const actions = [
    {
      label: 'Luggage',
      onClick: openExcessModal,
      variant: 'secondary' as const,
      icon: Package,
      show: (ticket: any) => !!ticket.booking && ['CONFIRMED', 'BOARDED'].includes(ticket.booking?.status ?? ticket.status),
    },
    {
      label: 'Board',
      onClick: handleBoard,
      variant: 'primary' as const,
      icon: LogIn,
      show: (ticket: any) => {
        const isRoundTrip = ticket.booking?.bookingType === 'ROUND_TRIP' || ticket.booking?.bookingType === 'ROUND_TRIP_TRANSIT';
        if (isRoundTrip) {
          const inboundBoarded = !!ticket.booking?.returnBoardedAt;
          const returnLegStatus = ticket.booking?.returnLegStatus;
          return !ticket.validatedAt || (!inboundBoarded && returnLegStatus !== 'BOTH_USED');
        }
        return !ticket.validatedAt;
      },
    },
    {
      label: 'Print BP',
      onClick: (ticket: any) => {
        setTicketToPrint(ticket);
        setPrintBpModalOpen(true);
      },
      variant: 'secondary' as const,
      icon: Printer,
      show: (ticket: any) => !!ticket.validatedAt || !!ticket.booking?.outboundBoardedAt || !!ticket.booking?.returnBoardedAt,
    },
    {
      label: 'Details',
      onClick: (ticket: any) => {
        setSelectedTicket(ticket);
        setDetailsModalOpen(true);
      },
      variant: 'secondary' as const,
      icon: ListCollapse,
    },
    {
      label: 'Restore',
      onClick: (ticket: any) => restoreMutation.mutate(ticket.id),
      variant: 'secondary' as const,
      icon: ListCollapse,
      show: (ticket: any) => ticket.status === 'CANCELLED',
    },
    {
      label: 'Delete',
      onClick: handleDeleteClick,
      variant: 'danger' as const,
      icon: Trash2,
    },
  ];

  const stations = stationsData?.items || [];

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-foreground">Tickets</h1>
          <p className="text-muted-foreground">Manage tickets and validations</p>
        </div>
        <div className="flex items-center gap-2">
          {hasMissingTickets && (
            <ActionButton
              icon={Download}
              variant="secondary"
              loading={generateMissingMutation.isPending}
              onClick={() => generateMissingMutation.mutate()}
            >
              Generate Missing
            </ActionButton>
          )}
          <ActionButton icon={Download} variant="export" onClick={() => setExportModalOpen(true)}>Export</ActionButton>
        </div>
      </div>

      {/* Filters */}
      <div className="card">
        {successMessage && (
          <div className="mb-4 rounded-lg bg-green-50 dark:bg-green-900/20 p-4 text-sm text-green-800 dark:text-green-200">
            ✓ {successMessage}
          </div>
        )}
        {error && (
          <div className="mb-4 rounded-lg bg-red-50 dark:bg-red-900/20 p-4 text-sm text-red-800 dark:text-red-200">
            Error loading tickets: {error instanceof Error ? error.message : 'Unknown error'}
          </div>
        )}
        <div className="grid grid-cols-1 md:grid-cols-3 lg:grid-cols-6 gap-4">
          <div>
            <label className="label">Search</label>
            <input
              type="text"
              placeholder="Search by ticket number..."
              className="input"
              value={filters.search}
              onChange={(e) => { resetTicketPage(); setFilters({ ...filters, search: e.target.value }); }}
            />
          </div>
          <div>
            <label className="label">Origin</label>
            <select
              className="input"
              value={filters.originStationId}
              onChange={(e) => { resetTicketPage(); setFilters({ ...filters, originStationId: e.target.value }); }}
            >
              <option value="">All Origins</option>
              {stations.map((station: any) => (
                <option key={station.id} value={station.id}>{station.name}</option>
              ))}
            </select>
          </div>
          <div>
            <label className="label">Destination</label>
            <select
              className="input"
              value={filters.destinationStationId}
              onChange={(e) => { resetTicketPage(); setFilters({ ...filters, destinationStationId: e.target.value }); }}
            >
              <option value="">All Destinations</option>
              {stations.map((station: any) => (
                <option key={station.id} value={station.id}>{station.name}</option>
              ))}
            </select>
          </div>
          <div>
            <label className="label">Departure Date</label>
            <input
              type="date"
              className="input"
              value={filters.departureDate}
              onChange={(e) => { resetTicketPage(); setFilters({ ...filters, departureDate: e.target.value }); }}
            />
          </div>
          <div>
            <label className="label">Coach</label>
            <select
              className="input"
              value={filters.coachId}
              onChange={(e) => { resetTicketPage(); setFilters({ ...filters, coachId: e.target.value }); }}
            >
              <option value="">All Coaches</option>
              {(Array.isArray(coachesData) ? coachesData : (coachesData as any)?.data || []).map((coach: any) => (
                <option key={coach.id} value={coach.id}>{coach.number}</option>
              ))}
            </select>
          </div>
          <div className="flex items-end">
            <button type="button" className="input w-full px-4 text-sm font-medium text-primary border-primary/40"
              onClick={() => setShowExtraFilters(v => !v)}>
              {showExtraFilters ? 'Hide Filters ▲' : 'More Filters ▼'}
            </button>
          </div>
        </div>
        {showExtraFilters && (
          <div className="grid grid-cols-1 sm:grid-cols-3 gap-3 mt-3">
            <div>
              <label className="label">Status</label>
              <select
                className="input"
                value={filters.status}
                onChange={(e) => { resetTicketPage(); setFilters({ ...filters, status: e.target.value }); }}
              >
                <option value="">All Status</option>
                <option value="ACTIVE">Active</option>
                <option value="USED">Used</option>
                <option value="CANCELLED">Cancelled</option>
              </select>
            </div>
            <div>
              <label className="label">Issued From</label>
              <input type="date" className="input" value={filters.dateFrom}
                onChange={(e) => { resetTicketPage(); setFilters({ ...filters, dateFrom: e.target.value }); }} />
            </div>
            <div>
              <label className="label">Issued To</label>
              <input type="date" className="input" value={filters.dateTo}
                onChange={(e) => { resetTicketPage(); setFilters({ ...filters, dateTo: e.target.value }); }} />
            </div>
          </div>
        )}
      </div>

      {/* Tickets Table */}
      <DataTable
        data={data?.items || []}
        columns={columns}
        actions={actions}
        loading={isLoading}
        emptyMessage="No tickets found"
      />
      <Pagination currentPage={ticketPage} totalPages={ticketTotalPages} onPageChange={setTicketPage} />

      {/* Board Confirmation Modal */}
      <Modal
        isOpen={boardConfirmOpen}
        onClose={() => { setBoardConfirmOpen(false); setTicketToBoard(null); }}
        title="Board Ticket"
        size="sm"
      >
        <div className="space-y-4">
          <div className="space-y-1">
            <p className="font-medium">Are you sure you want to board ticket {ticketToBoard?.ticketNumber}?</p>
            <p className="text-sm text-muted-foreground">This will mark the ticket as USED.</p>
          </div>
          <div className="flex justify-end gap-2 pt-2">
            <ActionButton variant="secondary" onClick={() => { setBoardConfirmOpen(false); setTicketToBoard(null); }}>Cancel</ActionButton>
            <ActionButton icon={LogIn} loading={boardMutation.isPending} onClick={handleConfirmBoard}>Board and Print</ActionButton>
          </div>
        </div>
      </Modal>

      {/* Print BP Modal */}
      <Modal
        isOpen={printBpModalOpen}
        onClose={() => { setPrintBpModalOpen(false); setTicketToPrint(null); }}
        title="Print Boarding Pass"
        size="sm"
      >
        <div className="space-y-4">
          {(() => {
            const isRoundTrip = ticketToPrint?.booking?.bookingType === 'ROUND_TRIP' || ticketToPrint?.booking?.bookingType === 'ROUND_TRIP_TRANSIT';
            const outboundBoarded = !!ticketToPrint?.booking?.outboundBoardedAt || !!ticketToPrint?.validatedAt;
            const inboundBoarded = !!ticketToPrint?.booking?.returnBoardedAt;
            if (isRoundTrip && outboundBoarded && inboundBoarded) {
              return (
                <>
                  <p className="text-sm text-muted-foreground">Select which leg to print:</p>
                  <div className="flex flex-col gap-2">
                    <ActionButton icon={Printer} onClick={() => { printBoardingPass(ticketToPrint, 'outbound'); setPrintBpModalOpen(false); }}>
                      Outbound
                    </ActionButton>
                    <ActionButton icon={Printer} variant="secondary" onClick={() => { printBoardingPass(ticketToPrint, 'inbound'); setPrintBpModalOpen(false); }}>
                      Inbound (Return)
                    </ActionButton>
                  </div>
                </>
              );
            }
            const leg = isRoundTrip && inboundBoarded && !outboundBoarded ? 'inbound' : 'outbound';
            return (
              <>
                <p className="text-sm text-muted-foreground">
                  Print {leg === 'inbound' ? 'inbound (return)' : 'outbound'} boarding pass for ticket {ticketToPrint?.ticketNumber}?
                </p>
                <div className="flex justify-end gap-2 pt-2">
                  <ActionButton variant="secondary" onClick={() => { setPrintBpModalOpen(false); setTicketToPrint(null); }}>Cancel</ActionButton>
                  <ActionButton icon={Printer} onClick={() => { printBoardingPass(ticketToPrint, leg); setPrintBpModalOpen(false); }}>Print</ActionButton>
                </div>
              </>
            );
          })()}
        </div>
      </Modal>

      {/* Delete Confirmation Dialog */}
      <ConfirmDialog
        isOpen={deleteConfirmOpen}
        onClose={() => { setDeleteConfirmOpen(false); setTicketToDelete(null); setDeleteError(null); }}
        onConfirm={handleConfirmDelete}
        title="Delete Ticket"
        message={`Are you sure you want to permanently delete ticket ${ticketToDelete?.ticketNumber}? This action cannot be undone.`}
        confirmText="Delete"
        cancelText="Cancel"
        isLoading={deleteMutation.isPending}
        isDanger={true}
        error={deleteError ?? undefined}
      />

      {/* Ticket Details Modal */}
      <Modal
        isOpen={detailsModalOpen}
        onClose={() => { setDetailsModalOpen(false); setSelectedTicket(null); }}
        title="Ticket Details"
        size="xl"
      >
        {selectedTicket && (() => {
          const t = selectedTicket;
          const b = t.booking;
          const isRoundTrip = b?.bookingType === 'ROUND_TRIP' || b?.bookingType === 'ROUND_TRIP_TRANSIT';
          const passengerName = b?.seats?.[0]?.passengerName || b?.passenger?.fullName || 'Guest';
          return (
            <div>
              {/* Gradient header */}
              <div className="-mx-6 -mt-4 mb-6 px-6 py-5 bg-gradient-to-r from-emerald-600 to-emerald-700 rounded-t-lg">
                <div className="flex items-start justify-between gap-4">
                  <div>
                    <p className="text-emerald-100 text-xs font-semibold uppercase tracking-widest mb-1">Ticket Number</p>
                    <p className="text-white text-3xl font-mono font-bold tracking-wider">{t.ticketNumber || '—'}</p>
                  </div>
                  <div className="text-right shrink-0 flex flex-col items-end gap-1">
                    <Badge variant="status" status={t.status || 'ACTIVE'}>{t.status || 'ACTIVE'}</Badge>
                    <span className={`text-xs font-semibold px-2 py-0.5 rounded-full ${t.qrCode ? 'bg-emerald-200 text-emerald-900' : 'bg-white/20 text-white/60'}`}>
                      {t.qrCode ? '✓ QR Available' : 'No QR'}
                    </span>
                    {t.validatedAt && <p className="text-emerald-200 text-xs">Validated {formatDateTime(t.validatedAt)}</p>}
                  </div>
                </div>
                <div className="mt-4 grid grid-cols-3 gap-3">
                  {[
                    { label: 'Passenger', value: passengerName },
                    { label: 'Route', value: `${t.schedule?.originStation?.name || '?'} → ${t.schedule?.destinationStation?.name || '?'}` },
                    { label: 'Amount', value: formatCurrency(b?.totalMinor || 0, b?.currency || 'ETB') },
                  ].map(({ label, value }) => (
                    <div key={label} className="bg-white/10 rounded-lg px-3 py-2">
                      <p className="text-emerald-200 text-xs">{label}</p>
                      <p className="text-white text-sm font-bold truncate">{value}</p>
                    </div>
                  ))}
                </div>
              </div>

              <div className="space-y-6">
                {/* Booking */}
                <section>
                  <SectionHeader title="Booking Information" />
                  <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
                    <Field label="Booking Ref" value={b?.bookingRef} mono />
                    <Field label="Booking Type" value={(b?.bookingType || 'ONE_WAY').replace(/_/g, ' ')} />
                    <Field label="Payment Status" value={b?.paymentIntent?.status || 'N/A'} />
                    <Field label="Contact Phone" value={b?.contactPhone || b?.passenger?.phone} />
                    <Field label="Contact Email" value={b?.contactEmail || b?.passenger?.email} truncate />
                    <Field label="Adults" value={String(b?.adultCount ?? 0)} />
                    <Field label="Children" value={String(b?.childCount ?? 0)} />
                    <Field label="Booking ID" value={b?.id} mono truncate />
                  </div>
                </section>

                {/* Trip */}
                <section>
                  <SectionHeader title="Trip Information" />
                  <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
                    <Field label="Origin" value={t.booking?.originStation?.name || t.schedule?.originStation?.name} />
                    <Field label="Destination" value={t.booking?.destinationStation?.name || t.schedule?.destinationStation?.name} />
                    <Field label="Departure" value={t.schedule?.departureAt ? formatDateTime(t.schedule.departureAt) : ''} />
                    <Field label="Arrival" value={t.schedule?.arrivalAt ? formatDateTime(t.schedule.arrivalAt) : ''} />
                    <Field label="Train" value={t.schedule?.train?.name || t.schedule?.train?.number} />
                    <Field label="Schedule ID" value={t.scheduleId} mono truncate />
                  </div>
                </section>

                {/* Seat */}
                <section>
                  <SectionHeader title="Seat Information" />
                  <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
                    <div className="bg-emerald-50 dark:bg-emerald-900/20 border border-emerald-100 dark:border-emerald-800 rounded-lg p-3 col-span-2 md:col-span-1 flex flex-col items-center justify-center">
                      <p className="text-xs text-emerald-700 dark:text-emerald-400 mb-1">Seat</p>
                      <p className="text-2xl font-mono font-bold text-emerald-800 dark:text-emerald-300">{t.seat?.seatNumber || '—'}</p>
                    </div>
                    <Field label="Coach" value={t.seat?.coach?.number} mono />
                    <Field label="Class" value={t.seat?.coach?.coachType?.name || t.seat?.coach?.coachType?.type} />
                    <Field label="Seat ID" value={t.seatId} mono truncate />
                  </div>
                </section>

                {/* Round-trip */}
                {isRoundTrip && (
                  <section>
                    <SectionHeader title="Round-Trip Legs" />
                    <div className="grid grid-cols-2 md:grid-cols-3 gap-3">
                      <Field label="Leg Status" value={(b?.returnLegStatus || '—').replace(/_/g, ' ')} />
                      <Field label="Outbound Boarded" value={b?.outboundBoardedAt ? formatDateTime(b.outboundBoardedAt) : 'Not yet'} />
                      <Field label="Return Boarded" value={b?.returnBoardedAt ? formatDateTime(b.returnBoardedAt) : 'Not yet'} />
                    </div>
                  </section>
                )}

                {/* QR Code */}
                {t.qrCode && (
                  <section>
                    <SectionHeader title="QR Code" />
                    <div className="flex justify-center">
                      <div className="bg-white p-4 rounded-xl border border-muted inline-block">
                        <Image
                          src={t.qrCode.startsWith('data:') ? t.qrCode : `data:image/png;base64,${t.qrCode}`}
                          alt={`QR Code for ${t.ticketNumber}`}
                          width={192}
                          height={192}
                          className="object-contain"
                          unoptimized
                        />
                        <p className="text-center text-xs text-muted-foreground mt-2 font-mono">{t.ticketNumber}</p>
                      </div>
                    </div>
                  </section>
                )}

                {/* Validation */}
                <section>
                  <SectionHeader title="Validation & Timestamps" />
                  <div className="grid grid-cols-2 md:grid-cols-3 gap-3">
                    <Field label="Validated At" value={t.validatedAt ? formatDateTime(t.validatedAt) : 'Not validated'} />
                    <Field label="Boarded At" value={t.boardedAt ? formatDateTime(t.boardedAt) : 'Not boarded'} />
                    <Field label="Created" value={formatDateTime(t.createdAt)} />
                    <Field label="Last Updated" value={formatDateTime(t.updatedAt)} />
                    <Field label="Ticket ID" value={t.id} mono truncate />
                  </div>
                </section>
              </div>

              <div className="flex justify-end gap-2 pt-6 mt-2 border-t border-muted">
                <ActionButton variant="secondary" onClick={() => { setDetailsModalOpen(false); setSelectedTicket(null); }}>Close</ActionButton>
              </div>
            </div>
          );
        })()}
      </Modal>

      {/* Excess Luggage Modal */}
      <Modal
        isOpen={excessModalOpen}
        onClose={() => { setExcessModalOpen(false); setExcessTicket(null); setExcessResult(null); }}
        title="Log Excess Luggage"
        size="sm"
      >
        {excessResult ? (
          <div className="space-y-4">
            <div className="rounded-lg bg-green-50 dark:bg-green-900/20 p-4 text-sm text-green-800 dark:text-green-200">
              {excessResult.status === 'CASH_COLLECTED'
                ? '✓ Cash collected and charge recorded.'
                : `✓ Payment link sent to passenger. Charge: ${formatCurrency(excessResult.totalMinor, excessResult.currency)}`}
            </div>
            <div className="text-sm space-y-1">
              <div className="flex justify-between"><span className="text-muted-foreground">Excess weight</span><span className="font-medium">{excessResult.excessWeightKg} kg</span></div>
              <div className="flex justify-between"><span className="text-muted-foreground">Amount due</span><span className="font-semibold">{formatCurrency(excessResult.totalMinor, excessResult.currency)}</span></div>
              <div className="flex justify-between"><span className="text-muted-foreground">Status</span><span className="font-medium">{excessResult.status}</span></div>
            </div>
            <div className="flex justify-end pt-2">
              <ActionButton variant="secondary" onClick={() => { setExcessModalOpen(false); setExcessResult(null); }}>Close</ActionButton>
            </div>
          </div>
        ) : (
          <form onSubmit={handleExcessSubmit} className="space-y-4">
            <div className="text-sm text-muted-foreground">
              Booking: <span className="font-semibold text-foreground">{excessTicket?.booking?.bookingRef}</span>
            </div>
            {user && (
              <div className="text-sm text-muted-foreground">
                Agent: <span className="font-semibold text-foreground">{user.fullName}</span>
              </div>
            )}
            <div>
              <label className="label">Excess weight (kg)</label>
              <input
                type="number"
                min="1"
                className="input"
                placeholder="e.g. 7"
                value={excessKg}
                onChange={(e) => setExcessKg(e.target.value)}
                required
              />
            </div>
            <label className="flex items-center gap-3 cursor-pointer">
              <input
                type="checkbox"
                checked={excessCollectCash}
                onChange={(e) => setExcessCollectCash(e.target.checked)}
                className="w-4 h-4 rounded border-gray-300"
              />
              <span className="text-sm">Collect cash now (no payment link sent)</span>
            </label>
            {excessError && (
              <p className="text-sm text-red-600 dark:text-red-400">{excessError}</p>
            )}
            <div className="flex justify-end gap-2 pt-2">
              <ActionButton variant="secondary" onClick={() => setExcessModalOpen(false)}>Cancel</ActionButton>
              <ActionButton icon={Package} loading={excessMutation.isPending} type="submit">
                {excessCollectCash ? 'Collect Cash' : 'Send Payment Link'}
              </ActionButton>
            </div>
          </form>
        )}
      </Modal>

      {/* Export Modal */}
      <Modal
        isOpen={exportModalOpen}
        onClose={() => setExportModalOpen(false)}
        title="Export Tickets"
        size="md"
      >
        <div className="space-y-4">
          <div className="grid grid-cols-2 gap-4">
            <div>
              <label className="label">Date From (Arrival)</label>
              <input type="date" className="input" value={exportDateFrom} onChange={(e) => setExportDateFrom(e.target.value)} />
            </div>
            <div>
              <label className="label">Date To (Arrival)</label>
              <input type="date" className="input" value={exportDateTo} onChange={(e) => setExportDateTo(e.target.value)} />
            </div>
          </div>

          <div>
            <p className="text-sm font-medium mb-2">Select Columns</p>
            <div className="space-y-2 max-h-56 overflow-y-auto">
              {[
                { key: 'ticketNumber', label: 'Ticket Number' },
                { key: 'booking', label: 'Booking Reference & Passenger' },
                { key: 'trip', label: 'Trip (Origin → Destination)' },
                { key: 'coach', label: 'Coach Number' },
                { key: 'seat', label: 'Seat Number' },
                { key: 'seatClass', label: 'Seat Class' },
                { key: 'amount', label: 'Amount' },
                { key: 'status', label: 'Status' },
                { key: 'boarded', label: 'Boarded Status' },
              ].map((col) => (
                <label key={col.key} className="flex items-center gap-3 p-2 hover:bg-gray-50 dark:hover:bg-gray-900/50 rounded cursor-pointer">
                  <input
                    type="checkbox"
                    checked={selectedColumns[col.key] || false}
                    onChange={(e) => setSelectedColumns({ ...selectedColumns, [col.key]: e.target.checked })}
                    className="w-4 h-4 rounded border-gray-300"
                  />
                  <span className="text-sm font-medium">{col.label}</span>
                </label>
              ))}
            </div>
          </div>

          <div>
            <p className="text-sm font-medium mb-2">Export Format</p>
            <div className="flex gap-4">
              {(['csv', 'excel', 'pdf'] as const).map(fmt => (
                <label key={fmt} className="flex items-center gap-2 cursor-pointer">
                  <input type="radio" name="ticketExportFmt" value={fmt} checked={exportFormat === fmt} onChange={() => setExportFormat(fmt)} className="w-4 h-4" />
                  <span className="text-sm font-medium">{fmt === 'excel' ? 'Excel (.xls)' : fmt === 'pdf' ? 'PDF (Print)' : 'CSV'}</span>
                </label>
              ))}
            </div>
          </div>
          <div className="flex justify-end gap-2 pt-4 border-t">
            <ActionButton variant="secondary" onClick={() => setExportModalOpen(false)}>Cancel</ActionButton>
            <ActionButton onClick={confirmExport}>Export</ActionButton>
          </div>
        </div>
      </Modal>
    </div>
  );
}
