import { useState, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  Search,
  ArrowUpDown,
  Pill,
  Download,
  Activity,
  Plus,
  X,
  Save,
  Edit2,
  Trash2,
  ExternalLink,
} from 'lucide-react';
import { format, isAfter, parseISO } from 'date-fns';
import { cn } from '../utils/helpers';
import { useHealthStore } from '../store/useHealthStore';
import { searchMedications } from '../services/medical';
import { DatePickerInput } from '../components/DatePickerInput';
import { useActivePatientId } from '../hooks/useActivePatientId';
import type { APIPrescription, APIDiagnosis } from '../services/medical';

/* ── Helpers ────────────────────────────────────────────────────────────── */

type StatusFilter = 'All' | 'Active' | 'Expired';
type SortField = 'date' | 'medication' | 'diagnosis';
type SortDirection = 'asc' | 'desc';

function isActive(p: APIPrescription) {
  if (!p.endDate) return true;
  try { return isAfter(parseISO(p.endDate), new Date()); } catch { return false; }
}

function medName(p: APIPrescription) {
  return p.medication?.brandName || p.medication?.genericName || 'Unknown Medication';
}

function fmtDate(d?: string) {
  if (!d) return '—';
  try { return format(parseISO(d), 'MMM d, yyyy'); } catch { return d; }
}

function buildDiagLookup(diagnoses: APIDiagnosis[]) {
  const diagById = new Map<string, APIDiagnosis>();
  const diagByPrescId = new Map<string, APIDiagnosis>();
  for (const d of diagnoses) {
    diagById.set(d._id, d);
    for (const rp of d.relatedPrescriptions || []) {
      diagByPrescId.set(rp._id, d);
    }
  }
  return { diagById, diagByPrescId };
}

function findLinkedDiagnosis(
  p: APIPrescription,
  diagById: Map<string, APIDiagnosis>,
  diagByPrescId: Map<string, APIDiagnosis>,
) {
  if (p.diagnosisId && diagById.has(p.diagnosisId)) return diagById.get(p.diagnosisId)!;
  return diagByPrescId.get(p._id) || null;
}

function diagName(d: APIDiagnosis | null) {
  return d?.disease?.name || null;
}

/* ── Component ──────────────────────────────────────────────────────────── */

export function PrescriptionsPage() {
  const navigate = useNavigate();
  const [searchTerm, setSearchTerm] = useState('');
  const [statusFilter, setStatusFilter] = useState<StatusFilter>('All');
  const [sortField, setSortField] = useState<SortField>('date');
  const [sortDirection, setSortDirection] = useState<SortDirection>('desc');
  const activePatientId = useActivePatientId();

  const addPrescription = useHealthStore(s => s.addPrescription);
  const editPrescription = useHealthStore(s => s.editPrescription);
  const removePrescription = useHealthStore(s => s.removePrescription);

  // Upload/Edit Form States
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [processing, setProcessing] = useState(false);
  const [form, setForm] = useState({
    prescriptionId: '',
    medicationId: '',
    medicationName: '',
    dosage: '',
    frequency: '',
    startDate: format(new Date(), 'yyyy-MM-dd'),
    endDate: format(new Date(), 'yyyy-MM-dd'),
    diagnosisId: '',
  });

  // Medication Search States
  const [medQuery, setMedQuery] = useState('');
  const [medResults, setMedResults] = useState<any[]>([]);
  const [isSearchingMeds, setIsSearchingMeds] = useState(false);
  const [showMedResults, setShowMedResults] = useState(false);

  const rawPrescriptions = useHealthStore((s) => s._rawPrescriptions);
  const rawDiagnoses = useHealthStore((s) => s._rawDiagnoses);
  const loadedUserId = useHealthStore((s) => s._loadedUserId);
  const isLoading = loadedUserId === null;

  const { diagById, diagByPrescId } = useMemo(
    () => buildDiagLookup(rawDiagnoses),
    [rawDiagnoses]
  );

  // Lookup helper used in sort + render
  const getDiag = (p: APIPrescription) => findLinkedDiagnosis(p, diagById, diagByPrescId);

  const filtered = useMemo(() => {
    return rawPrescriptions.filter(p => {
      const search = searchTerm.toLowerCase();
      const linked = getDiag(p);
      const matchesSearch = !searchTerm ||
        medName(p).toLowerCase().includes(search) ||
        (p.medication?.genericName || '').toLowerCase().includes(search) ||
        p.prescriptionId?.toLowerCase().includes(search) ||
        (p.doctorName || '').toLowerCase().includes(search) ||
        (diagName(linked) || '').toLowerCase().includes(search);

      const active = isActive(p);
      const matchesStatus = statusFilter === 'All' ||
        (statusFilter === 'Active' && active) ||
        (statusFilter === 'Expired' && !active);

      return matchesSearch && matchesStatus;
    });
  }, [rawPrescriptions, rawDiagnoses, searchTerm, statusFilter]);

  const sorted = useMemo(() => {
    return [...filtered].sort((a, b) => {
      let cmp = 0;
      switch (sortField) {
        case 'date':
          cmp = new Date(a.startDate || a.created_at || 0).getTime() - new Date(b.startDate || b.created_at || 0).getTime();
          break;
        case 'medication':
          cmp = medName(a).localeCompare(medName(b));
          break;
        case 'diagnosis':
          cmp = (diagName(getDiag(a)) || '').localeCompare(diagName(getDiag(b)) || '');
          break;
      }
      return sortDirection === 'asc' ? cmp : -cmp;
    });
  }, [filtered, sortField, sortDirection, rawDiagnoses]);

  const handleSort = (field: SortField) => {
    if (sortField === field) setSortDirection(d => d === 'asc' ? 'desc' : 'asc');
    else { setSortField(field); setSortDirection('desc'); }
  };

  const handleMedSearch = async (query: string) => {
    setMedQuery(query);
    if (query.length < 2) {
      setMedResults([]);
      return;
    }
    setIsSearchingMeds(true);
    try {
      const results = await searchMedications(query);
      setMedResults(results);
      setShowMedResults(true);
    } catch (err) {
      console.error("Med search failed", err);
    } finally {
      setIsSearchingMeds(false);
    }
  };

  const selectMedication = (med: any) => {
    setForm({
      ...form,
      medicationId: med._id,
      medicationName: med.brandName || med.genericName
    });
    setMedQuery(med.brandName || med.genericName);
    setShowMedResults(false);
  };

  const handleOpenAdd = () => {
    setEditingId(null);
    setForm({
      prescriptionId: '',
      medicationId: '',
      medicationName: '',
      dosage: '',
      frequency: '',
      startDate: format(new Date(), 'yyyy-MM-dd'),
      endDate: format(new Date(), 'yyyy-MM-dd'),
      diagnosisId: '',
    });
    setMedQuery('');
    setIsModalOpen(true);
  };

  const handleOpenEdit = (p: APIPrescription) => {
    setEditingId(p._id);
    setForm({
      prescriptionId: p.prescriptionId || '',
      medicationId: p.medicationId || '',
      medicationName: medName(p),
      dosage: p.dosage || '',
      frequency: p.frequency || '',
      startDate: p.startDate ? format(parseISO(p.startDate), 'yyyy-MM-dd') : format(new Date(), 'yyyy-MM-dd'),
      endDate: p.endDate ? format(parseISO(p.endDate), 'yyyy-MM-dd') : format(new Date(), 'yyyy-MM-dd'),
      diagnosisId: p.diagnosisId || '',
    });
    setMedQuery(medName(p));
    setIsModalOpen(true);
  };


  const handleDelete = async (id: string) => {
    if (!window.confirm("Are you sure you want to remove this prescription?")) return;
    try {
      await removePrescription(id);
    } catch (err) {
      alert("Failed to remove prescription");
    }
  };

  const handleSubmit = async () => {
    if (!activePatientId) return;
    if (!form.medicationId || !form.dosage || !form.startDate || !form.endDate) {
      alert("Please fill all required fields.");
      return;
    }

    setProcessing(true);
    try {
      const payload = {
        prescriptionId: form.prescriptionId || `PRE-${Date.now()}`,
        medicationId: form.medicationId,
        dosage: form.dosage,
        frequency: form.frequency,
        startDate: new Date(form.startDate).toISOString(),
        endDate: new Date(form.endDate).toISOString(),
        diagnosisId: form.diagnosisId || undefined,
        patientId: activePatientId
      };

      if (editingId) {
        await editPrescription(editingId, payload);
      } else {
        await addPrescription(payload);
      }
      setIsModalOpen(false);
    } catch (err) {
      console.error("Operation failed", err);
      alert("Operation failed: " + (err as Error).message);
    } finally {
      setProcessing(false);
    }
  };

  const handleExport = () => {
    const headers = ['Medication', 'Generic Name', 'Dosage', 'Frequency', 'Diagnosis', 'Prescribed By', 'Start', 'End', 'Status'];
    const csv = [
      headers.join(','),
      ...sorted.map(p => [
        `"${medName(p)}"`,
        `"${p.medication?.genericName || ''}"`,
        `"${p.dosage}"`,
        `"${p.frequency}"`,
        `"${diagName(getDiag(p)) || ''}"`,
        `"${p.doctorName || ''}"`,
        p.startDate || '',
        p.endDate || '',
        isActive(p) ? 'Active' : 'Expired',
      ].join(','))
    ].join('\n');

    const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
    const link = document.createElement('a');
    const url = URL.createObjectURL(blob);
    link.setAttribute('href', url);
    link.setAttribute('download', 'prescriptions.csv');
    link.style.visibility = 'hidden';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  };

  const SortButton = ({ field, label }: { field: SortField; label: string }) => (
    <button
      onClick={() => handleSort(field)}
      className="flex items-center gap-1 group text-xs font-semibold text-gray-500 uppercase tracking-wider hover:text-gray-700"
    >
      <span>{label}</span>
      <ArrowUpDown className={cn(
        "w-3 h-3 transition-colors",
        sortField === field ? "text-primary" : "text-gray-300 group-hover:text-gray-400"
      )} />
    </button>
  );

  if (isLoading) {
    return (
      <div className="flex items-center justify-center py-32">
        <div className="animate-spin h-8 w-8 border-4 border-primary border-t-transparent rounded-full" />
      </div>
    );
  }

  return (
    <div className="pb-20">
      {/* Header */}
      <div className="flex flex-col sm:flex-row justify-between items-start sm:items-center mb-8 gap-4">
        <div>
          <h1 className="text-2xl font-semibold text-gray-900">My Prescriptions</h1>
          <p className="text-gray-500 text-sm mt-1">Track and manage your medication prescriptions</p>
        </div>
        <div className="flex flex-col sm:flex-row gap-3 w-full md:w-auto">
          <button
            onClick={handleExport}
            className="inline-flex items-center gap-2 px-4 py-2 bg-[#2DD4BF] text-white rounded-lg hover:bg-[#26b8a6] transition-colors font-medium text-sm shadow-sm"
          >
            <Download className="w-4 h-4" />
            Export Prescriptions
          </button>
          <button
            onClick={handleOpenAdd}
            className="flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-primary text-white text-sm font-bold shadow-lg shadow-primary/25 hover:-translate-y-0.5 active:translate-y-0 transition-all shrink-0"
          >
            <Plus className="w-4 h-4" />
            <span>Add Prescription</span>
          </button>
        </div>
      </div>

      {/* Filters */}
      <div className="mb-8">
        <div className="flex flex-col sm:flex-row gap-4 items-center">
          <div className="relative w-full sm:w-[400px]">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-4 h-4" />
            <input
              type="text"
              placeholder="Search by prescription or diagnosis..."
              className="pl-10 pr-4 py-2.5 w-full bg-white border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary transition-all placeholder:text-gray-400"
              value={searchTerm}
              onChange={(e) => setSearchTerm(e.target.value)}
            />
          </div>
          <div className="flex bg-gray-100/80 p-1 rounded-lg sm:ml-auto">
            {(['All', 'Active', 'Expired'] as StatusFilter[]).map((status) => (
              <button
                key={status}
                onClick={() => setStatusFilter(status)}
                className={cn(
                  "px-4 py-1.5 text-sm font-medium rounded-md transition-all",
                  statusFilter === status
                    ? "bg-white text-gray-900 shadow-sm"
                    : "text-gray-500 hover:text-gray-700 hover:bg-gray-200/50"
                )}
              >
                {status}
              </button>
            ))}
          </div>
        </div>
      </div>

      {/* Table */}
      <div className="bg-white rounded-2xl border border-gray-200 shadow-sm overflow-hidden ring-1 ring-black/[0.02]">
        <table className="w-full text-left table-fixed">
          <thead className="bg-gray-50/50 border-b border-gray-100">
            <tr>
              <th className="px-6 py-4 w-[28%]">
                <SortButton field="medication" label="Medication" />
              </th>
              <th className="px-6 py-4 w-[15%]">
                <span className="text-[10px] font-bold text-gray-400 uppercase tracking-widest">Dosage & Frequency</span>
              </th>
              <th className="px-6 py-4 w-[18%]">
                <SortButton field="diagnosis" label="Linked Diagnosis" />
              </th>
              <th className="px-6 py-4 w-[18%]">
                <SortButton field="date" label="Prescription Period" />
              </th>
              <th className="px-6 py-4 w-[10%]">
                <span className="text-[10px] font-bold text-gray-400 uppercase tracking-widest">Status</span>
              </th>
              <th className="px-6 py-4 w-32" />
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-100">
            {sorted.map(p => {
              const active = isActive(p);
              const linked = getDiag(p);
              const generic = p.medication?.genericName;
              const hasBrand = p.medication?.brandName && generic;

              return (
                <tr
                  className={cn(
                      "hover:bg-gray-50/50 transition-all bg-white group cursor-pointer",
                    )}
                  >
                    <td className="px-6 py-5 align-top">
                      <div className="flex items-center gap-4">
                        <div className={cn(
                          "w-10 h-10 rounded-xl flex items-center justify-center shrink-0 border transition-colors",
                          active 
                            ? "bg-blue-50 text-blue-600 border-blue-100 shadow-sm" 
                            : "bg-gray-50 text-gray-400 border-gray-100"
                        )}>
                          <Pill className="w-5 h-5" />
                        </div>
                        <div className="min-w-0">
                          <p className="text-sm font-bold text-gray-900 truncate">{medName(p)}</p>
                          {hasBrand && (
                            <p className="text-[11px] font-medium text-gray-400 mt-0.5 truncate tracking-tight">{generic}</p>
                          )}
                        </div>
                      </div>
                    </td>
                    <td className="px-6 py-5 align-top">
                      <p className="text-sm font-semibold text-gray-900">{p.dosage || '—'}</p>
                      <p className="text-[11px] font-medium text-gray-500 mt-1">{p.frequency || '—'}</p>
                    </td>
                    <td className="px-6 py-5 align-top">
                      {linked ? (
                        <div className="flex items-center gap-2.5 min-w-0">
                          <div className="w-6 h-6 rounded-md bg-blue-50 flex items-center justify-center shrink-0">
                            <Activity className="w-3 h-3 text-blue-500" />
                          </div>
                          <div className="min-w-0">
                            <p className="text-sm font-semibold text-gray-800 truncate leading-none mb-1">{diagName(linked)}</p>
                            <p className="text-[10px] font-bold font-mono text-gray-400 uppercase tracking-tighter">{linked.icdCode}</p>
                          </div>
                        </div>
                      ) : (
                        <span className="text-xs font-bold text-gray-300 uppercase tracking-widest">Not Linked</span>
                      )}
                    </td>
                    <td className="px-6 py-5 align-top">
                      <div className="flex flex-col gap-1">
                        <div className="flex items-center gap-2">
                          <span className="text-[10px] font-bold text-gray-400 uppercase tracking-tighter w-8">From</span>
                          <span className="text-sm font-semibold text-gray-700">{fmtDate(p.startDate)}</span>
                        </div>
                        {p.endDate && (
                          <div className="flex items-center gap-2">
                            <span className="text-[10px] font-bold text-gray-400 uppercase tracking-tighter w-8">Until</span>
                            <span className={cn(
                              "text-sm font-semibold",
                              active ? "text-gray-700" : "text-red-400"
                            )}>{fmtDate(p.endDate)}</span>
                          </div>
                        )}
                      </div>
                    </td>
                    <td className="px-6 py-5 align-top">
                      <span className={cn(
                        "inline-flex items-center px-2.5 py-1 rounded-full text-[10px] font-bold uppercase tracking-widest border",
                        active 
                          ? "bg-green-50 text-green-700 border-green-100" 
                          : "bg-gray-50 text-gray-500 border-gray-100"
                      )}>
                        {active ? 'Active' : 'Expired'}
                      </span>
                    </td>
                    <td className="px-6 py-5 text-right align-top">
                      <div className="flex items-center justify-end gap-1">
                        <div className="flex items-center gap-1">
                          <button
                            onClick={(e) => { e.stopPropagation(); handleOpenEdit(p); }}
                            className="p-1.5 text-gray-400 hover:text-blue-600 hover:bg-blue-50 rounded-lg transition-all"
                            title="Edit Prescription"
                          >
                            <Edit2 className="w-4 h-4" />
                          </button>
                          <button
                            onClick={(e) => { e.stopPropagation(); handleDelete(p._id); }}
                            className="p-1.5 text-gray-400 hover:text-red-600 hover:bg-red-50 rounded-lg transition-all"
                            title="Remove Record"
                          >
                            <Trash2 className="w-4 h-4" />
                          </button>
                        </div>
                        <button
                          onClick={(e) => { e.stopPropagation(); navigate(`/prescriptions/${p._id}`); }}
                          className="w-8 h-8 rounded-lg flex items-center justify-center text-gray-400 hover:bg-primary/10 hover:text-primary transition-all duration-200"
                          title="Open Detailed View"
                        >
                          <ExternalLink className="w-4 h-4" />
                        </button>
                      </div>
                    </td>
                  </tr>
                );
              })}
          </tbody>
        </table>

        {sorted.length === 0 && (
          <div className="flex flex-col items-center justify-center py-24 px-4">
            <div className="w-20 h-20 rounded-full bg-gray-50 flex items-center justify-center mb-6 ring-1 ring-black/[0.02]">
              <Pill className="w-10 h-10 text-gray-200" />
            </div>
            <h3 className="text-xl font-bold text-gray-900 mb-2">No prescriptions found</h3>
            <p className="text-sm text-gray-400 text-center max-w-sm font-medium">
              {searchTerm || statusFilter !== 'All'
                ? 'Try adjusting your filters or search terms.'
                : 'Your prescription records will appear here.'}
            </p>
          </div>
        )}
      </div>

      {/* Upload/Edit Modal */}
      {isModalOpen && (
        <div className="fixed inset-0 bg-black/60 z-[100] backdrop-blur-sm flex items-center justify-center p-4">
          <div className="bg-white rounded-2xl shadow-xl w-full max-w-lg overflow-hidden animate-in zoom-in-95 duration-200">
            <div className="p-4 border-b flex justify-between items-center bg-gray-50">
              <h3 className="font-bold text-gray-900">{editingId ? 'Edit Prescription' : 'Add New Prescription'}</h3>
              <button onClick={() => setIsModalOpen(false)} className="p-1 hover:bg-gray-200 rounded-md">
                <X className="w-5 h-5 text-gray-500" />
              </button>
            </div>
            <div className="p-6 space-y-4 max-h-[80vh] overflow-y-auto">
              <div className="grid grid-cols-2 gap-4">
                <div className="col-span-2 relative">
                  <label className="block text-xs font-bold text-gray-500 uppercase tracking-wider mb-1.5">Medication *</label>
                  <div className="relative">
                    <Pill className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 w-4 h-4" />
                    <input
                      type="text"
                      value={medQuery}
                      onChange={e => handleMedSearch(e.target.value)}
                      onFocus={() => medResults.length > 0 && setShowMedResults(true)}
                      className="w-full pl-10 pr-3 py-2 rounded-lg border border-gray-200 focus:ring-2 focus:ring-primary/20"
                      placeholder="Search medication name..."
                    />
                    {isSearchingMeds && (
                      <div className="absolute right-3 top-1/2 -translate-y-1/2">
                        <div className="w-4 h-4 border-2 border-primary/30 border-t-primary rounded-full animate-spin" />
                      </div>
                    )}
                  </div>

                  {showMedResults && medResults.length > 0 && (
                    <div className="absolute z-10 w-full mt-1 bg-white border border-gray-200 rounded-lg shadow-lg overflow-hidden">
                      {medResults.map(med => (
                        <button
                          key={med._id}
                          onClick={() => selectMedication(med)}
                          className="w-full px-4 py-2 text-left hover:bg-gray-50 transition-colors text-sm"
                        >
                          <p className="font-medium text-gray-900">{med.brandName || med.genericName}</p>
                          {med.brandName && med.genericName && <p className="text-xs text-gray-500">{med.genericName}</p>}
                        </button>
                      ))}
                    </div>
                  )}
                </div>

                <div>
                  <label className="block text-xs font-bold text-gray-500 uppercase tracking-wider mb-1.5">Dosage *</label>
                  <input
                    type="text"
                    value={form.dosage}
                    onChange={e => setForm({ ...form, dosage: e.target.value })}
                    className="w-full px-3 py-2 rounded-lg border border-gray-200 focus:ring-2 focus:ring-primary/20"
                    placeholder="e.g. 500mg"
                  />
                </div>
                <div>
                  <label className="block text-xs font-bold text-gray-500 uppercase tracking-wider mb-1.5">Frequency</label>
                  <input
                    type="text"
                    value={form.frequency}
                    onChange={e => setForm({ ...form, frequency: e.target.value })}
                    className="w-full px-3 py-2 rounded-lg border border-gray-200 focus:ring-2 focus:ring-primary/20"
                    placeholder="e.g. Twice daily"
                  />
                </div>

                <div>
                  <label className="block text-xs font-bold text-gray-500 uppercase tracking-wider mb-1.5">Start Date *</label>
                  <DatePickerInput value={form.startDate} onChange={val => setForm({ ...form, startDate: val })} className="w-full" />
                </div>
                <div>
                  <label className="block text-xs font-bold text-gray-500 uppercase tracking-wider mb-1.5">End Date *</label>
                  <DatePickerInput value={form.endDate} onChange={val => setForm({ ...form, endDate: val })} className="w-full" />
                </div>

                <div className="col-span-2">
                  <label className="block text-xs font-bold text-gray-500 uppercase tracking-wider mb-1.5">Related Diagnosis</label>
                  <select
                    value={form.diagnosisId}
                    onChange={e => setForm({ ...form, diagnosisId: e.target.value })}
                    className="w-full px-3 py-2 rounded-lg border border-gray-200 focus:ring-2 focus:ring-primary/20 bg-white"
                  >
                    <option value="">None / Unknown</option>
                    {rawDiagnoses.map(diag => (
                      <option key={diag._id} value={diag._id}>
                        {diag.disease?.name || diag.icdCode} ({format(parseISO(diag.diagnosisDate), 'MMM yyyy')})
                      </option>
                    ))}
                  </select>
                </div>

                <div className="col-span-2">
                  <label className="block text-xs font-bold text-gray-500 uppercase tracking-wider mb-1.5">Prescription ID (Optional)</label>
                  <input
                    type="text"
                    value={form.prescriptionId}
                    onChange={e => setForm({ ...form, prescriptionId: e.target.value })}
                    className="w-full px-3 py-2 rounded-lg border border-gray-200 focus:ring-2 focus:ring-primary/20"
                    placeholder="e.g. 4289TMXP"
                  />
                </div>
              </div>

              <button
                onClick={handleSubmit}
                disabled={processing}
                className="w-full flex items-center justify-center gap-2 bg-primary text-white py-2.5 rounded-lg font-bold shadow-md hover:bg-primary/90 mt-2 transition-all disabled:opacity-50"
              >
                {processing ? <div className="w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin" /> : <Save className="w-4 h-4" />}
                {processing ? 'Processing...' : editingId ? 'Update Prescription' : 'Save Prescription'}
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
