import { useState, useEffect, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  ClipboardList, Search, ChevronDown, ChevronUp,
  Clock,
} from 'lucide-react';
import { format, parseISO, isAfter } from 'date-fns';
import { cn } from '../../utils/helpers';
import { usePractitionerStore } from '../store/usePractitionerStore';
import type { APIHospitalVisit } from '../../services/medical';

/* ═══════════════════════════════════════════════════════════════════════
   HELPERS
   ═══════════════════════════════════════════════════════════════════════ */

type SortField = 'date' | 'patient' | 'hospital';
type SortDir = 'asc' | 'desc';
type StatusFilter = 'all' | 'upcoming' | 'past';

function initials(name: string) {
  return name.split(' ').map(n => n[0]).join('').slice(0, 2).toUpperCase();
}

function safeDate(d: string) { try { return parseISO(d); } catch { return new Date(d); } }
function fmt(d: string, f = 'MMM d, yyyy') { try { return format(safeDate(d), f); } catch { return d; } }

function isUpcoming(visit: APIHospitalVisit) {
  try { return isAfter(parseISO(visit.visitDate), new Date()); } catch { return false; }
}

function visitType(visit: APIHospitalVisit): string {
  return visit.department || 'General';
}


const TYPE_STYLES: Record<string, string> = {
  Examination:  'bg-primary/10 text-primary border-primary/20',
  Control:      'bg-emerald-50 text-emerald-700 border-emerald-200',
  Consultation: 'bg-violet-50 text-violet-700 border-violet-200',
  'Follow-up':  'bg-amber-50 text-amber-700 border-amber-200',
};

const DEFAULT_TYPE_STYLE = 'bg-gray-50 text-gray-600 border-gray-200';

/* ═══════════════════════════════════════════════════════════════════════
   COMPONENT
   ═══════════════════════════════════════════════════════════════════════ */

export default function AppointmentsPage() {
  const navigate = useNavigate();
  const { patients, appointments, appointmentsLoading, loadAppointments } = usePractitionerStore();

  const [search, setSearch] = useState('');
  const [statusFilter, setStatusFilter] = useState<StatusFilter>('all');
  const [sortField, setSortField] = useState<SortField>('date');
  const [sortDir, setSortDir] = useState<SortDir>('desc');
  const [expandedId, setExpandedId] = useState<string | null>(null);

  // Load all appointments on mount
  useEffect(() => { loadAppointments(); }, [loadAppointments]);

  // Build patient lookup map
  const patientMap = useMemo(() => {
    const m = new Map<string, { name: string; city?: string }>();
    patients.forEach(p => m.set(p._id, { name: p.dispName, city: p.residentCity }));
    return m;
  }, [patients]);

  function getPatientName(id: string) { return patientMap.get(id)?.name || 'Unknown Patient'; }

  const filtered = useMemo(() => {
    let list = [...appointments];

    // Status filter
    if (statusFilter === 'upcoming') list = list.filter(isUpcoming);
    if (statusFilter === 'past') list = list.filter(v => !isUpcoming(v));

    // Search
    if (search.trim()) {
      const q = search.toLowerCase();
      list = list.filter(v => {
        const pName = getPatientName(v.patientId).toLowerCase();
        const hospital = (v.hospital || '').toLowerCase();
        const dept = (v.department || '').toLowerCase();
        const dxNames = v.populatedDiagnoses?.map(d => (d.diseaseName || d.icdCode || '').toLowerCase()).join(' ') || '';
        return pName.includes(q) || hospital.includes(q) || dept.includes(q) || dxNames.includes(q);
      });
    }

    // Sort
    list.sort((a, b) => {
      let cmp = 0;
      if (sortField === 'date') cmp = safeDate(a.visitDate).getTime() - safeDate(b.visitDate).getTime();
      else if (sortField === 'patient') cmp = getPatientName(a.patientId).localeCompare(getPatientName(b.patientId));
      else if (sortField === 'hospital') cmp = (a.hospital || '').localeCompare(b.hospital || '');
      return sortDir === 'desc' ? -cmp : cmp;
    });

    return list;
  }, [appointments, search, statusFilter, sortField, sortDir, patientMap]);

  function toggleSort(field: SortField) {
    if (sortField === field) setSortDir(d => d === 'asc' ? 'desc' : 'asc');
    else { setSortField(field); setSortDir('desc'); }
  }

  const SortIcon = ({ field }: { field: SortField }) => {
    if (sortField !== field) return <ChevronDown className="w-3 h-3 text-gray-300" />;
    return sortDir === 'desc'
      ? <ChevronDown className="w-3 h-3 text-primary" />
      : <ChevronUp className="w-3 h-3 text-primary" />;
  };

  const upcomingCount = appointments.filter(isUpcoming).length;
  const pastCount = appointments.length - upcomingCount;

  return (
    <div className="space-y-5 animate-fade-in">
      {/* ── Header ───────────────────────────────────────────────── */}
      <div className="flex items-center gap-3">
        <div className="w-10 h-10 rounded-xl bg-primary/10 flex items-center justify-center">
          <ClipboardList className="w-5 h-5 text-primary" />
        </div>
        <div>
          <h1 className="text-[17px] font-bold text-gray-900 tracking-tight">My Appointments</h1>
          <p className="text-[12px] text-gray-500">
            {appointments.length} total &middot; {upcomingCount} upcoming &middot; {pastCount} past
          </p>
        </div>
      </div>

      {/* ── Stats row ────────────────────────────────────────────── */}
      <div className="grid grid-cols-3 gap-3">
        {[
          { label: 'Total', value: appointments.length, color: 'bg-gray-50 border-gray-200' },
          { label: 'Upcoming', value: upcomingCount, color: 'bg-primary/5 border-primary/20' },
          { label: 'Completed', value: pastCount, color: 'bg-emerald-50 border-emerald-200' },
        ].map(s => (
          <div key={s.label} className={cn('rounded-xl border px-4 py-3', s.color)}>
            <p className="text-[20px] font-bold text-gray-900 tabular-nums">{s.value}</p>
            <p className="text-[11px] font-medium text-gray-500 uppercase tracking-wider">{s.label}</p>
          </div>
        ))}
      </div>

      {/* ── Filters ──────────────────────────────────────────────── */}
      <div className="flex flex-col sm:flex-row gap-3">
        <div className="relative flex-1">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-3.5 h-3.5 text-gray-400" />
          <input
            type="text"
            placeholder="Search by patient, hospital, diagnosis..."
            value={search}
            onChange={e => setSearch(e.target.value)}
            className="w-full pl-9 pr-3 py-2.5 rounded-xl border border-gray-200 text-[13px] bg-white placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary"
          />
        </div>
        <div className="flex gap-1.5">
          {(['all', 'upcoming', 'past'] as StatusFilter[]).map(f => (
            <button
              key={f}
              onClick={() => setStatusFilter(f)}
              className={cn(
                'px-3.5 py-2 rounded-xl text-[12px] font-medium border transition-colors capitalize',
                statusFilter === f
                  ? 'bg-primary text-white border-primary'
                  : 'bg-white text-gray-600 border-gray-200 hover:bg-gray-50',
              )}
            >
              {f}
            </button>
          ))}
        </div>
      </div>

      {/* ── Table ────────────────────────────────────────────────── */}
      <div className="bg-white rounded-2xl border border-gray-200 shadow-card overflow-hidden">
        {/* Table header */}
        <div className="grid grid-cols-[1fr_1.2fr_0.8fr_0.7fr_0.5fr] gap-3 px-5 py-3 border-b border-gray-100 bg-gray-50/50">
          <button onClick={() => toggleSort('date')} className="flex items-center gap-1 text-left">
            <span className="text-[11px] font-semibold text-gray-500 uppercase tracking-wider">Date & Time</span>
            <SortIcon field="date" />
          </button>
          <button onClick={() => toggleSort('patient')} className="flex items-center gap-1 text-left">
            <span className="text-[11px] font-semibold text-gray-500 uppercase tracking-wider">Patient</span>
            <SortIcon field="patient" />
          </button>
          <button onClick={() => toggleSort('hospital')} className="flex items-center gap-1 text-left">
            <span className="text-[11px] font-semibold text-gray-500 uppercase tracking-wider">Hospital</span>
            <SortIcon field="hospital" />
          </button>
          <span className="text-[11px] font-semibold text-gray-500 uppercase tracking-wider">Type</span>
          <span className="text-[11px] font-semibold text-gray-500 uppercase tracking-wider text-right">Status</span>
        </div>

        {/* Loading */}
        {appointmentsLoading && (
          <div className="flex items-center justify-center py-12">
            <div className="animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full" />
          </div>
        )}

        {/* Empty */}
        {!appointmentsLoading && filtered.length === 0 && (
          <div className="py-16 text-center">
            <div className="w-12 h-12 rounded-full bg-gray-100 flex items-center justify-center mx-auto mb-3">
              <ClipboardList className="w-6 h-6 text-gray-400" />
            </div>
            <p className="text-[13px] font-medium text-gray-900">No appointments found</p>
            <p className="text-[12px] text-gray-500 mt-1">
              {search ? 'Try a different search term' : 'Appointments booked by your patients will appear here'}
            </p>
          </div>
        )}

        {/* Rows */}
        {!appointmentsLoading && filtered.map((visit, idx) => {
          const pName = getPatientName(visit.patientId);
          const pCity = patientMap.get(visit.patientId)?.city;
          const upcoming = isUpcoming(visit);
          const type = visitType(visit);
          const typeStyle = TYPE_STYLES[type] || DEFAULT_TYPE_STYLE;
          const expanded = expandedId === visit._id;
          const dxList = visit.populatedDiagnoses || [];
          const rxList = visit.populatedPrescriptions || [];

          return (
            <div key={visit._id}>
              <div
                onClick={() => setExpandedId(expanded ? null : visit._id)}
                className={cn(
                  'grid grid-cols-[1fr_1.2fr_0.8fr_0.7fr_0.5fr] gap-3 px-5 py-3.5 items-center cursor-pointer transition-colors',
                  idx > 0 && 'border-t border-gray-50',
                  expanded ? 'bg-primary/[0.02]' : 'hover:bg-gray-50/50',
                )}
              >
                {/* Date & Time */}
                <div className="flex items-center gap-2.5">
                  <div className={cn(
                    'w-9 h-9 rounded-lg flex flex-col items-center justify-center flex-none border',
                    upcoming ? 'bg-primary/5 border-primary/15' : 'bg-gray-50 border-gray-200',
                  )}>
                    <span className={cn('text-[10px] font-bold leading-none', upcoming ? 'text-primary' : 'text-gray-500')}>
                      {fmt(visit.visitDate, 'MMM')}
                    </span>
                    <span className={cn('text-[14px] font-bold leading-tight tabular-nums', upcoming ? 'text-primary' : 'text-gray-700')}>
                      {fmt(visit.visitDate, 'd')}
                    </span>
                  </div>
                  <div>
                    <p className="text-[13px] font-medium text-gray-900 tabular-nums">
                      {fmt(visit.visitDate, 'EEEE')}
                    </p>
                    <p className="text-[11px] text-gray-500 flex items-center gap-1">
                      <Clock className="w-3 h-3" />
                      {fmt(visit.visitDate, 'HH:mm')}
                    </p>
                  </div>
                </div>

                {/* Patient */}
                <div
                  className="flex items-center gap-2.5 cursor-pointer group"
                  onClick={e => { e.stopPropagation(); navigate(`/patients/${visit.patientId}`); }}
                >
                  <div className="w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center text-primary text-[10px] font-bold flex-none">
                    {initials(pName)}
                  </div>
                  <div className="min-w-0">
                    <p className="text-[13px] font-medium text-gray-900 truncate group-hover:text-primary transition-colors">
                      {pName}
                    </p>
                    {pCity && <p className="text-[11px] text-gray-500 truncate">{pCity}</p>}
                  </div>
                </div>

                {/* Hospital */}
                <div className="min-w-0">
                  <p className="text-[13px] text-gray-900 truncate">{visit.hospital}</p>
                </div>

                {/* Type */}
                <span className={cn('inline-flex items-center px-2 py-0.5 rounded-full text-[11px] font-medium border w-fit', typeStyle)}>
                  {type}
                </span>

                {/* Status */}
                <div className="text-right">
                  <span className={cn(
                    'inline-flex items-center gap-1.5 px-2 py-0.5 rounded-full text-[11px] font-medium',
                    upcoming ? 'bg-primary/10 text-primary' : 'bg-gray-100 text-gray-500',
                  )}>
                    <span className={cn('w-1.5 h-1.5 rounded-full', upcoming ? 'bg-primary' : 'bg-gray-400')} />
                    {upcoming ? 'Upcoming' : 'Completed'}
                  </span>
                </div>
              </div>

              {/* Expanded detail */}
              {expanded && (
                <div className="px-5 pb-4 pt-1 bg-gray-50/30 border-t border-gray-100 animate-fade-in">
                  <div className="grid grid-cols-2 gap-4 pl-[52px]">
                    {/* Diagnoses */}
                    <div>
                      <p className="text-[11px] font-semibold text-gray-500 uppercase tracking-wider mb-2">Diagnoses</p>
                      {dxList.length > 0 ? (
                        <div className="flex flex-wrap gap-1.5">
                          {dxList.map(d => (
                            <span key={d._id} className="badge badge-blue text-[11px]">
                              {d.diseaseName || d.icdCode}
                            </span>
                          ))}
                        </div>
                      ) : (
                        <p className="text-[12px] text-gray-400 italic">No diagnoses recorded</p>
                      )}
                    </div>

                    {/* Prescriptions */}
                    <div>
                      <p className="text-[11px] font-semibold text-gray-500 uppercase tracking-wider mb-2">Prescriptions</p>
                      {rxList.length > 0 ? (
                        <div className="flex flex-wrap gap-1.5">
                          {rxList.map(r => (
                            <span key={r._id} className="badge badge-green text-[11px]">
                              {r.medicationName || 'Rx'} &middot; {r.dosage}
                            </span>
                          ))}
                        </div>
                      ) : (
                        <p className="text-[12px] text-gray-400 italic">No prescriptions</p>
                      )}
                    </div>

                    {/* Notes */}
                    {visit.dischargeSummary && (
                      <div className="col-span-2">
                        <p className="text-[11px] font-semibold text-gray-500 uppercase tracking-wider mb-1.5">Notes</p>
                        <p className="text-[12px] text-gray-700 leading-relaxed">{visit.dischargeSummary}</p>
                      </div>
                    )}
                  </div>
                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}
