'use client';

import { useState } from 'react';
import { useQuery, useMutation } from '@tanstack/react-query';
import { Search, Layers, ChevronDown, ChevronUp, CheckSquare, Square, AlertCircle, CheckCircle2, X, Loader2 } from 'lucide-react';
import { seatsApi } from '@/lib/api';
import { formatDateTime } from '@/lib/utils';

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

interface DuplicateBooking {
  bookingSeatId: string;
  bookingId: string;
  bookingRef: string;
  passengerName: string;
  contactPhone: string | null;
  createdAt: string;
}

interface DuplicateSeatGroup {
  seatId: string;
  seatNumber: string;
  leg: number;
  bookings: DuplicateBooking[];
}

interface AvailableSeat {
  seatId: string;
  seatNumber: string;
}

interface CoachReport {
  coachId: string;
  coachNumber: string;
  coachTypeName: string;
  duplicates: DuplicateSeatGroup[];
  availableSeats: AvailableSeat[];
}

interface ScheduleReport {
  scheduleId: string;
  origin: string;
  destination: string;
  departureAt: string;
  coaches: CoachReport[];
}

interface DuplicatesResponse {
  date: string;
  schedules: ScheduleReport[];
  totalDuplicates: number;
}

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

function today() {
  return new Date().toISOString().slice(0, 10);
}

function scheduleDuplicateCount(s: ScheduleReport) {
  return s.coaches.reduce((sum, c) => sum + c.duplicates.length, 0);
}

// ── Resolve modal ─────────────────────────────────────────────────────────

interface ResolveModalProps {
  schedule: ScheduleReport;
  coach: CoachReport;
  onClose: () => void;
  onSuccess: () => void;
}

function ResolveModal({ schedule, coach, onClose, onSuccess }: ResolveModalProps) {
  // Default: pre-select all-but-first passenger in every duplicate group
  const defaultSelected = new Set<string>(
    coach.duplicates.flatMap(g => g.bookings.slice(1).map(b => b.bookingSeatId)),
  );
  const [selectedSeats, setSelectedSeats] = useState<Set<string>>(defaultSelected);

  // Coaches that have at least one available seat (pre-select all)
  const coachesWithSeats = schedule.coaches.filter(c => c.availableSeats.length > 0);
  const [selectedCoachIds, setSelectedCoachIds] = useState<Set<string>>(
    new Set(coachesWithSeats.map(c => c.coachId)),
  );

  const [successMsg, setSuccessMsg] = useState<string | null>(null);
  const [errorMsg, setErrorMsg] = useState<string | null>(null);

  const mutation = useMutation({
    mutationFn: (data: { bookingSeatIds: string[]; coachIds: string[] }) =>
      seatsApi.resolveDuplicates(data),
    onSuccess: (res) => {
      setSuccessMsg(
        `${res.resolved ?? 0} passenger(s) successfully reassigned.` +
        (res.unresolved > 0 ? ` ${res.unresolved} could not be resolved (no available seat).` : ''),
      );
      setErrorMsg(null);
      onSuccess();
    },
    onError: (err: any) => {
      setErrorMsg(err?.response?.data?.message ?? 'Failed to resolve duplicates.');
    },
  });

  function toggleBookingSeat(id: string) {
    setSelectedSeats(prev => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });
  }

  function toggleCoach(id: string) {
    setSelectedCoachIds(prev => {
      const next = new Set(prev);
      next.has(id) ? next.delete(id) : next.add(id);
      return next;
    });
  }

  function handleAssign() {
    setErrorMsg(null);
    if (selectedSeats.size === 0) {
      setErrorMsg('Select at least one passenger to reassign.');
      return;
    }
    if (selectedCoachIds.size === 0) {
      setErrorMsg('Select at least one coach to source the replacement seat from.');
      return;
    }
    mutation.mutate({
      bookingSeatIds: [...selectedSeats],
      coachIds:       [...selectedCoachIds],
    });
  }

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4">
      <div className="w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-xl bg-white dark:bg-gray-900 shadow-2xl flex flex-col">

        {/* Header */}
        <div className="flex items-center justify-between px-6 py-4 border-b border-gray-200 dark:border-gray-700">
          <div>
            <h2 className="text-lg font-semibold text-gray-900 dark:text-white">
              Resolve Duplicates — {coach.coachNumber}
            </h2>
            <p className="text-sm text-gray-500 dark:text-gray-400">
              {schedule.origin} → {schedule.destination} · {formatDateTime(schedule.departureAt)}
            </p>
          </div>
          <button onClick={onClose} className="p-1 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800">
            <X className="w-5 h-5 text-gray-500" />
          </button>
        </div>

        <div className="flex-1 overflow-y-auto px-6 py-5 space-y-6">

          {/* Duplicate seat groups */}
          <div className="space-y-4">
            <h3 className="text-sm font-semibold text-gray-700 dark:text-gray-300 uppercase tracking-wide">
              Duplicate seat assignments
            </h3>
            <p className="text-xs text-gray-500 dark:text-gray-400">
              Check the passengers you want to reassign to a new seat. Unchecked passengers keep their current seat.
            </p>

            {coach.duplicates.map(group => (
              <div
                key={`${group.seatId}-${group.leg}`}
                className="rounded-lg border border-orange-200 dark:border-orange-800 bg-orange-50 dark:bg-orange-950/30 p-4"
              >
                <div className="flex items-center gap-2 mb-3">
                  <AlertCircle className="w-4 h-4 text-orange-500 shrink-0" />
                  <span className="text-sm font-medium text-orange-800 dark:text-orange-300">
                    Seat {group.seatNumber} — {group.bookings.length} passengers assigned
                  </span>
                </div>
                <div className="space-y-2">
                  {group.bookings.map((b, idx) => {
                    const checked = selectedSeats.has(b.bookingSeatId);
                    return (
                      <label
                        key={b.bookingSeatId}
                        className="flex items-start gap-3 cursor-pointer rounded-lg px-3 py-2 hover:bg-orange-100 dark:hover:bg-orange-900/30 transition-colors"
                      >
                        <input
                          type="checkbox"
                          checked={checked}
                          onChange={() => toggleBookingSeat(b.bookingSeatId)}
                          className="mt-0.5 h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
                        />
                        <div className="flex-1 min-w-0">
                          <div className="flex items-center gap-2 flex-wrap">
                            <span className="text-sm font-medium text-gray-900 dark:text-white">
                              {b.passengerName || '—'}
                            </span>
                            <span className="text-xs font-mono bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 px-1.5 py-0.5 rounded">
                              {b.bookingRef}
                            </span>
                            {idx === 0 && (
                              <span className="text-xs bg-green-100 dark:bg-green-900/30 text-green-700 dark:text-green-400 px-1.5 py-0.5 rounded">
                                earliest
                              </span>
                            )}
                          </div>
                          <div className="text-xs text-gray-500 dark:text-gray-400 mt-0.5">
                            {b.contactPhone ?? 'No phone'} · Booked {formatDateTime(b.createdAt)}
                          </div>
                        </div>
                      </label>
                    );
                  })}
                </div>
              </div>
            ))}
          </div>

          {/* Coach selection */}
          <div className="space-y-3">
            <h3 className="text-sm font-semibold text-gray-700 dark:text-gray-300 uppercase tracking-wide">
              Reassign to seats in
            </h3>
            <p className="text-xs text-gray-500 dark:text-gray-400">
              The system picks the first available seat in the selected coaches.
            </p>
            <div className="space-y-2">
              {coachesWithSeats.length === 0 ? (
                <p className="text-sm text-red-500">No coaches have available seats on this schedule.</p>
              ) : (
                coachesWithSeats.map(c => (
                  <label
                    key={c.coachId}
                    className="flex items-center gap-3 cursor-pointer rounded-lg border border-gray-200 dark:border-gray-700 px-3 py-2 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors"
                  >
                    <input
                      type="checkbox"
                      checked={selectedCoachIds.has(c.coachId)}
                      onChange={() => toggleCoach(c.coachId)}
                      className="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
                    />
                    <div className="flex-1">
                      <span className="text-sm font-medium text-gray-900 dark:text-white">
                        {c.coachNumber}
                      </span>
                      <span className="text-xs text-gray-500 dark:text-gray-400 ml-2">
                        {c.coachTypeName}
                      </span>
                    </div>
                    <span className="text-xs text-green-600 dark:text-green-400 font-medium">
                      {c.availableSeats.length} available
                    </span>
                  </label>
                ))
              )}
            </div>
          </div>

          {/* Feedback */}
          {errorMsg && (
            <div className="flex items-start gap-2 rounded-lg bg-red-50 dark:bg-red-950/30 border border-red-200 dark:border-red-800 px-4 py-3">
              <AlertCircle className="w-4 h-4 text-red-500 shrink-0 mt-0.5" />
              <p className="text-sm text-red-700 dark:text-red-400">{errorMsg}</p>
            </div>
          )}
          {successMsg && (
            <div className="flex items-start gap-2 rounded-lg bg-green-50 dark:bg-green-950/30 border border-green-200 dark:border-green-800 px-4 py-3">
              <CheckCircle2 className="w-4 h-4 text-green-500 shrink-0 mt-0.5" />
              <p className="text-sm text-green-700 dark:text-green-400">{successMsg}</p>
            </div>
          )}
        </div>

        {/* Footer */}
        <div className="flex items-center justify-between px-6 py-4 border-t border-gray-200 dark:border-gray-700 gap-3">
          <button
            onClick={onClose}
            className="px-4 py-2 text-sm rounded-lg border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors"
          >
            {successMsg ? 'Close' : 'Cancel'}
          </button>
          {!successMsg && (
            <button
              onClick={handleAssign}
              disabled={mutation.isPending || selectedSeats.size === 0 || selectedCoachIds.size === 0}
              className="flex items-center gap-2 px-5 py-2 text-sm font-medium rounded-lg bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
            >
              {mutation.isPending && <Loader2 className="w-4 h-4 animate-spin" />}
              Assign {selectedSeats.size > 0 ? `${selectedSeats.size} passenger${selectedSeats.size > 1 ? 's' : ''}` : ''}
            </button>
          )}
        </div>
      </div>
    </div>
  );
}

// ── Coach card ────────────────────────────────────────────────────────────

interface CoachCardProps {
  coach: CoachReport;
  schedule: ScheduleReport;
  onResolve: () => void;
}

function CoachCard({ coach, schedule, onResolve }: CoachCardProps) {
  const [expanded, setExpanded] = useState(false);
  const hasDuplicates = coach.duplicates.length > 0;

  return (
    <div className={`rounded-xl border ${hasDuplicates ? 'border-orange-200 dark:border-orange-800' : 'border-gray-200 dark:border-gray-700'} bg-white dark:bg-gray-900 overflow-hidden`}>
      {/* Card header */}
      <div className="flex items-center gap-4 px-5 py-4">
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2 flex-wrap">
            <span className="font-semibold text-gray-900 dark:text-white">{coach.coachNumber}</span>
            <span className="text-sm text-gray-500 dark:text-gray-400">{coach.coachTypeName}</span>
          </div>
          <div className="flex items-center gap-3 mt-1 text-xs text-gray-500 dark:text-gray-400">
            <span>{coach.availableSeats.length} available seats</span>
            {hasDuplicates && (
              <span className="flex items-center gap-1 text-orange-600 dark:text-orange-400 font-medium">
                <AlertCircle className="w-3.5 h-3.5" />
                {coach.duplicates.length} duplicate{coach.duplicates.length > 1 ? 's' : ''}
              </span>
            )}
          </div>
        </div>

        <div className="flex items-center gap-2 shrink-0">
          {hasDuplicates && (
            <button
              onClick={onResolve}
              className="px-3 py-1.5 text-xs font-medium rounded-lg bg-orange-500 text-white hover:bg-orange-600 transition-colors"
            >
              Resolve
            </button>
          )}
          {hasDuplicates && (
            <button
              onClick={() => setExpanded(v => !v)}
              className="p-1.5 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 text-gray-500 transition-colors"
              title={expanded ? 'Collapse' : 'View passengers'}
            >
              {expanded ? <ChevronUp className="w-4 h-4" /> : <ChevronDown className="w-4 h-4" />}
            </button>
          )}
        </div>
      </div>

      {/* Expanded passenger list */}
      {expanded && hasDuplicates && (
        <div className="border-t border-gray-100 dark:border-gray-800 divide-y divide-gray-100 dark:divide-gray-800">
          {coach.duplicates.map(group => (
            <div key={`${group.seatId}-${group.leg}`} className="px-5 py-3">
              <p className="text-xs font-semibold text-orange-600 dark:text-orange-400 mb-2">
                Seat {group.seatNumber} — {group.bookings.length} passengers
              </p>
              <div className="space-y-2">
                {group.bookings.map((b, idx) => (
                  <div key={b.bookingSeatId} className="flex items-center gap-3 text-sm">
                    <span className="w-5 h-5 rounded-full bg-gray-100 dark:bg-gray-800 text-gray-600 dark:text-gray-400 text-xs flex items-center justify-center font-medium shrink-0">
                      {idx + 1}
                    </span>
                    <div className="flex-1 min-w-0">
                      <span className="font-medium text-gray-900 dark:text-white">{b.passengerName || '—'}</span>
                      <span className="ml-2 text-xs font-mono text-gray-500 dark:text-gray-400">{b.bookingRef}</span>
                    </div>
                    <span className="text-xs text-gray-400 dark:text-gray-500 shrink-0">{b.contactPhone ?? '—'}</span>
                  </div>
                ))}
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ── Main page ─────────────────────────────────────────────────────────────

export default function DiscrepancyPage() {
  const [date, setDate] = useState(today());
  const [searchDate, setSearchDate] = useState('');
  const [resolveTarget, setResolveTarget] = useState<{ schedule: ScheduleReport; coach: CoachReport } | null>(null);

  const { data, isLoading, isError, refetch } = useQuery<DuplicatesResponse>({
    queryKey: ['seat-duplicates', searchDate],
    queryFn: () => seatsApi.getDuplicates(searchDate),
    enabled: !!searchDate,
  });

  function handleSearch() {
    if (date) setSearchDate(date);
  }

  function handleKeyDown(e: React.KeyboardEvent) {
    if (e.key === 'Enter') handleSearch();
  }

  return (
    <div className="p-6 space-y-6 max-w-5xl mx-auto">

      {/* Page header */}
      <div className="flex items-center gap-3">
        <div className="p-2 rounded-lg bg-orange-100 dark:bg-orange-950/40">
          <Layers className="w-6 h-6 text-orange-600 dark:text-orange-400" />
        </div>
        <div>
          <h1 className="text-2xl font-bold text-gray-900 dark:text-white">Seat Discrepancy</h1>
          <p className="text-sm text-gray-500 dark:text-gray-400">
            Detect and resolve duplicate seat assignments by schedule date
          </p>
        </div>
      </div>

      {/* Date picker */}
      <div className="flex items-center gap-3">
        <input
          type="date"
          value={date}
          onChange={e => setDate(e.target.value)}
          onKeyDown={handleKeyDown}
          className="rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-white px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
        />
        <button
          onClick={handleSearch}
          disabled={!date || isLoading}
          className="flex items-center gap-2 px-4 py-2 rounded-lg bg-blue-600 text-white text-sm font-medium hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
        >
          {isLoading ? <Loader2 className="w-4 h-4 animate-spin" /> : <Search className="w-4 h-4" />}
          Search
        </button>
      </div>

      {/* Error */}
      {isError && (
        <div className="flex items-center gap-2 rounded-lg bg-red-50 dark:bg-red-950/30 border border-red-200 dark:border-red-800 px-4 py-3 text-sm text-red-700 dark:text-red-400">
          <AlertCircle className="w-4 h-4 shrink-0" />
          Failed to load duplicate seat data. Please try again.
        </div>
      )}

      {/* Summary banner */}
      {data && (
        <div className={`rounded-xl border px-5 py-4 flex items-center gap-3 ${
          data.totalDuplicates > 0
            ? 'bg-orange-50 dark:bg-orange-950/20 border-orange-200 dark:border-orange-800'
            : 'bg-green-50 dark:bg-green-950/20 border-green-200 dark:border-green-800'
        }`}>
          {data.totalDuplicates > 0 ? (
            <AlertCircle className="w-5 h-5 text-orange-500 shrink-0" />
          ) : (
            <CheckCircle2 className="w-5 h-5 text-green-500 shrink-0" />
          )}
          <span className={`text-sm font-medium ${
            data.totalDuplicates > 0
              ? 'text-orange-800 dark:text-orange-300'
              : 'text-green-800 dark:text-green-300'
          }`}>
            {data.totalDuplicates > 0
              ? `${data.totalDuplicates} duplicate seat assignment${data.totalDuplicates > 1 ? 's' : ''} found across ${data.schedules.length} schedule${data.schedules.length > 1 ? 's' : ''} on ${data.date}`
              : `No duplicate seat assignments found on ${data.date}`}
          </span>
        </div>
      )}

      {/* Results per schedule */}
      {data?.schedules.map(schedule => (
        <div key={schedule.scheduleId} className="space-y-3">
          {/* Schedule header */}
          <div className="flex items-center justify-between">
            <div>
              <h2 className="text-base font-semibold text-gray-900 dark:text-white">
                {schedule.origin} → {schedule.destination}
              </h2>
              <p className="text-xs text-gray-500 dark:text-gray-400">
                {formatDateTime(schedule.departureAt)} · {scheduleDuplicateCount(schedule)} duplicate{scheduleDuplicateCount(schedule) !== 1 ? 's' : ''}
              </p>
            </div>
          </div>

          {/* Coach cards grid */}
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
            {schedule.coaches.map(coach => (
              <CoachCard
                key={coach.coachId}
                coach={coach}
                schedule={schedule}
                onResolve={() => setResolveTarget({ schedule, coach })}
              />
            ))}
          </div>
        </div>
      ))}

      {/* Empty state when searched but no results */}
      {data && data.schedules.length === 0 && data.totalDuplicates === 0 && searchDate && (
        <div className="flex flex-col items-center justify-center py-16 text-center">
          <CheckCircle2 className="w-12 h-12 text-green-400 mb-3" />
          <p className="text-gray-500 dark:text-gray-400">All seats are correctly assigned for {data.date}</p>
        </div>
      )}

      {/* Resolve modal */}
      {resolveTarget && (
        <ResolveModal
          schedule={resolveTarget.schedule}
          coach={resolveTarget.coach}
          onClose={() => setResolveTarget(null)}
          onSuccess={() => {
            refetch();
            // Keep modal open to show success message; user closes manually
          }}
        />
      )}
    </div>
  );
}
