import { useState } from 'react';
import { useHealthStore } from '../store/useHealthStore';
import { formatDate, getStatusColor } from '../utils/helpers';
import { X, Plus, ChevronRight, Maximize2, Minimize2, Clock, User } from 'lucide-react';
import { format, isAfter, isBefore, startOfDay } from 'date-fns';
import { type WidgetType, WIDGET_DEFINITIONS, type Appointment, type LabResult, type VaccinationEvent } from '../types/medical';
import { motion, AnimatePresence } from 'framer-motion';
import { DeviceSummaryWidget } from '../devices/DeviceSummaryWidget';

const COLOR_MAP: Record<string, { bg: string; text: string }> = {
  red:     { bg: 'bg-red-50',     text: 'text-red-600' },
  blue:    { bg: 'bg-blue-50',    text: 'text-blue-600' },
  green:   { bg: 'bg-green-50',   text: 'text-green-600' },
  emerald: { bg: 'bg-emerald-50', text: 'text-emerald-600' },
  indigo:  { bg: 'bg-indigo-50',  text: 'text-indigo-600' },
  rose:    { bg: 'bg-rose-50',    text: 'text-rose-600' },
  amber:   { bg: 'bg-amber-50',   text: 'text-amber-600' },
  orange:  { bg: 'bg-orange-50',  text: 'text-orange-600' },
  teal:    { bg: 'bg-teal-50',    text: 'text-teal-600' },
  purple:  { bg: 'bg-purple-50',  text: 'text-purple-600' },
  slate:   { bg: 'bg-slate-50',   text: 'text-slate-600' },
};
const getColors = (c: string) => COLOR_MAP[c] ?? COLOR_MAP.blue;

// ─── Empty state ──────────────────────────────────────────────────────────────

function EmptyState({ message }: { message: string }) {
  return <p className="text-sm text-gray-400 py-2">{message}</p>;
}

// ─── Widget: Recent Blood Work ────────────────────────────────────────────────

const RecentBloodWork = ({ size }: { size: 'normal' | 'compact' }) => {
  const labResults = useHealthStore((s) => s.labResults);
  const latest = labResults[0];
  const limit = size === 'compact' ? 3 : 5;

  if (!latest) return <EmptyState message="No recent lab data." />;

  return (
    <div>
      <p className="text-[11px] text-gray-400 mb-3">
        Collected{' '}
        <span className="text-gray-500 font-medium">{formatDate(latest.date)}</span>
      </p>
      <div className="space-y-px">
        {latest.results.slice(0, limit).map((result) => (
          <div
            key={result.id}
            className={`py-2 border-b border-gray-50 last:border-0 ${size === 'normal' ? 'flex flex-col gap-1.5' : 'flex justify-between items-center'}`}
          >
            {size === 'compact' ? (
              <>
                <span className="text-sm text-gray-500">{result.name}</span>
                <span className={`text-sm font-semibold tabular-nums ${getStatusColor(result.status)}`}>
                  {result.value}{' '}
                  <span className="text-xs font-normal text-gray-400">{result.unit}</span>
                </span>
              </>
            ) : (
              <>
                <div className="flex justify-between items-start">
                  <span className="text-sm font-medium text-gray-700">{result.name}</span>
                  <span className={`text-sm font-bold tabular-nums ${getStatusColor(result.status)}`}>
                    {result.value}{' '}
                    <span className="text-xs font-normal text-gray-400">{result.unit}</span>
                  </span>
                </div>
                <div className="flex justify-between items-center bg-gray-50/50 rounded px-2 py-1">
                  <span className="text-[10px] text-gray-400 uppercase tracking-wide font-medium">Ref Range</span>
                  <span className="text-[11px] text-gray-500 font-mono bg-white border border-gray-100 px-1.5 py-0.5 rounded-sm">
                    {result.range !== 'Unknown' ? `${result.range} ${result.unit}` : 'N/A'}
                  </span>
                </div>
              </>
            )}
          </div>
        ))}
      </div>
    </div>
  );
};

// ─── Widget: Current Medications ─────────────────────────────────────────────

const CurrentMedications = ({ size }: { size: 'normal' | 'compact' }) => {
  const allMedications = useHealthStore((s) => s.medications);
  const today = new Date().toISOString().split('T')[0];
  const medications = allMedications.filter((med) => !med.endDate || med.endDate >= today);
  const limit = size === 'compact' ? 2 : 3;

  if (!medications.length) return <EmptyState message="No active medications." />;

  return (
    <div className="space-y-2">
      {medications.slice(0, limit).map((med) => (
        <div
          key={med.id}
          className="flex items-start justify-between gap-3 p-3 bg-gray-50/60 rounded-lg border border-gray-100"
        >
          <div className="min-w-0">
            <p className="text-sm font-semibold text-gray-800 leading-tight truncate">{med.name}</p>
            <p className="text-xs text-gray-400 mt-0.5">{med.dosage}</p>
            {size === 'normal' && (
              <p className="text-xs text-primary/70 mt-0.5 truncate">{med.indication}</p>
            )}
          </div>
          <span className="text-[11px] font-medium text-gray-500 bg-white border border-gray-200 px-2 py-0.5 rounded-md shrink-0 leading-tight">
            {med.frequency}
          </span>
        </div>
      ))}
      {medications.length > limit && (
        <button className="w-full text-center text-xs text-gray-400 hover:text-gray-600 py-1 transition-colors">
          +{medications.length - limit} more
        </button>
      )}
    </div>
  );
};

// ─── Widget: Vital Signs ──────────────────────────────────────────────────────

const VitalSigns = ({ size }: { size: 'normal' | 'compact' }) => {
  const vitals = useHealthStore((s) => s.vitals);
  const latest = vitals[0];
  const limit = size === 'compact' ? 2 : 4;

  if (!latest) return <EmptyState message="No vital signs recorded." />;

  const items = [
    { label: 'Blood Pressure', value: `${latest.bloodPressure.systolic}/${latest.bloodPressure.diastolic}`, unit: 'mmHg', color: 'text-gray-800' },
    { label: 'Heart Rate',     value: latest.heartRate,          unit: 'bpm', color: 'text-emerald-600' },
    { label: 'SpO₂',           value: latest.oxygenSaturation,   unit: '%',   color: 'text-blue-600' },
    { label: 'Weight',         value: latest.weight,             unit: 'kg',  color: 'text-gray-800' },
  ];

  return (
    <div>
      <p className="text-[11px] text-gray-400 mb-3">
        Recorded{' '}
        <span className="text-gray-500 font-medium">{formatDate(latest.date)}</span>
      </p>
      <div className="space-y-px">
        {items.slice(0, limit).map((item, i) => (
          <div key={i} className="flex justify-between items-center py-1.5 border-b border-gray-50 last:border-0">
            <span className="text-sm text-gray-500">{item.label}</span>
            <span className={`text-sm font-semibold tabular-nums ${item.color}`}>
              {item.value}{' '}
              <span className="text-xs font-normal text-gray-400">{item.unit}</span>
            </span>
          </div>
        ))}
      </div>
    </div>
  );
};

// ─── Widget: Upcoming Schedule ───────────────────────────────────────────────

const UpcomingSchedule = ({ size }: { size: 'normal' | 'compact' }) => {
  const appointments = useHealthStore((s) => s.appointments);
  const today = startOfDay(new Date());
  
  const upcomingAppointments = appointments
    .filter((e) => isAfter(new Date(e.date), today))
    .sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());

  const [displayLimit, setDisplayLimit] = useState(size === 'compact' ? 3 : 5);

  if (!upcomingAppointments.length) return <EmptyState message="No upcoming appointments." />;

  const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {
    const bottom = e.currentTarget.scrollHeight - e.currentTarget.scrollTop <= e.currentTarget.clientHeight + 10;
    if (bottom && displayLimit < upcomingAppointments.length) {
      setDisplayLimit((prev) => prev + 5);
    }
  };

  return (
    <div className="space-y-1 max-h-[250px] overflow-y-auto pr-1" onScroll={handleScroll}>
      {upcomingAppointments.slice(0, displayLimit).map((event) => (
        <div key={event.id} className="flex gap-3 py-2 border-b border-slate-50 last:border-0 group">
          <div className="flex flex-col items-center justify-start w-10 pt-0.5">
            <div className="text-[9px] font-bold text-gray-400 uppercase tracking-wider mb-0.5">
              {format(new Date(event.date), "MMM")}
            </div>
            <div className="text-base font-light text-gray-700 leading-none">
              {format(new Date(event.date), "dd")}
            </div>
          </div>
          <div className="flex-1 min-w-0">
            <div className="flex justify-between items-start mb-0.5">
              <div>
                <h4 className="font-medium text-gray-900 text-sm truncate">{event.reason}</h4>
                {size === 'normal' && (
                  <p className="text-xs text-gray-500 mt-0.5 line-clamp-1">{event.notes}</p>
                )}
              </div>
            </div>
            <div className="flex items-center gap-3 text-[10px] text-gray-400 mt-1">
              <span className="flex items-center gap-1">
                <Clock size={10} className="text-gray-300" />
                {event.time}
              </span>
              <span className="flex items-center gap-1 truncate">
                <User size={10} className="text-gray-300" />
                {event.doctor}
              </span>
            </div>
          </div>
        </div>
      ))}
    </div>
  );
};

// ─── Widget: Recent History ──────────────────────────────────────────────────

const RecentHistory = ({ size }: { size: 'normal' | 'compact' }) => {
  const appointments = useHealthStore((s) => s.appointments);
  const labResults = useHealthStore((s) => s.labResults);
  const vaccinations = useHealthStore((s) => s.vaccinations);
  const today = startOfDay(new Date());

  const pastEvents = [...appointments, ...labResults, ...(vaccinations || [])]
    .filter(
      (e) =>
        isBefore(new Date(e.date), today) ||
        e.date === format(today, "yyyy-MM-dd")
    )
    .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());

  const [displayLimit, setDisplayLimit] = useState(size === 'compact' ? 3 : 5);

  if (!pastEvents.length) return <EmptyState message="No past events." />;

  const handleScroll = (e: React.UIEvent<HTMLDivElement>) => {
    const bottom = e.currentTarget.scrollHeight - e.currentTarget.scrollTop <= e.currentTarget.clientHeight + 10;
    if (bottom && displayLimit < pastEvents.length) {
      setDisplayLimit((prev) => prev + 5);
    }
  };

  return (
    <div className="max-h-[250px] overflow-y-auto pr-1" onScroll={handleScroll}>
      <div className="pl-3 pb-1">
        <div className="relative border-l-2 border-gray-100/80 space-y-4 pl-4 py-1">
          {pastEvents.slice(0, displayLimit).map((event) => (
            <div key={event.id} className="relative group">
              <div
                className={`absolute -left-[23px] top-1.5 w-3 h-3 rounded-full border-[2px] bg-white transition-colors ${
                  event.type === "labs" ? "border-rose-400"
                  : event.type === "vaccinations" ? "border-purple-400"
                  : "border-blue-400"
                }`}
              />
          <div>
            <div className="flex items-baseline gap-2 mb-0.5">
              <span className="text-[10px] font-semibold text-gray-400 uppercase tracking-wide">
                {format(new Date(event.date), "MMM d")}
              </span>
            </div>
            <h4 className="text-sm font-medium text-gray-800 mb-0.5 truncate">
              {event.type === "appointments" ? (event as Appointment).reason
               : event.type === "vaccinations" ? (event as VaccinationEvent).name
               : (event as LabResult).testName}
            </h4>
            {size === 'normal' && (
              <p className="text-xs text-gray-500 leading-snug line-clamp-1">
                {event.type === "appointments" ? (event as Appointment).notes
                 : event.type === "vaccinations" ? "Vaccination"
                 : "Lab Test Results"}
              </p>
            )}
          </div>
        </div>
      ))}
        </div>
      </div>
    </div>
  );
};

// ─── Main Component ───────────────────────────────────────────────────────────

interface ActiveWidget {
  instanceId: string;
  type: WidgetType;
  size: 'normal' | 'compact';
}

export function DataDashboard() {
  const [activeWidgets, setActiveWidgets] = useState<ActiveWidget[]>([
    { instanceId: 'init-1', type: 'recent-blood-work',   size: 'normal' },
    { instanceId: 'init-2', type: 'current-medications', size: 'normal' },
    { instanceId: 'init-3', type: 'recent-history',         size: 'normal' },
  ]);
  const [isAddMenuOpen, setIsAddMenuOpen] = useState(false);

  const removeWidget = (index: number) =>
    setActiveWidgets((prev) => prev.filter((_, i) => i !== index));

  const addWidget = (type: WidgetType) => {
    setActiveWidgets((prev) => [
      ...prev,
      { instanceId: `widget-${Date.now()}`, type, size: 'normal' },
    ]);
    setIsAddMenuOpen(false);
  };

  const toggleSize = (index: number) =>
    setActiveWidgets((prev) =>
      prev.map((w, i) =>
        i === index ? { ...w, size: w.size === 'normal' ? 'compact' : 'normal' } : w
      )
    );

  const availableWidgets = (Object.keys(WIDGET_DEFINITIONS) as WidgetType[]).filter(
    (id) => !activeWidgets.some((w) => w.type === id)
  );

  return (
    <div className="mb-8">
      {/* Section label */}
      <p className="text-xs font-semibold text-gray-400 uppercase tracking-wider mb-4">
        Health Overview
      </p>

      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
        <AnimatePresence mode="popLayout">
          {activeWidgets.map((widget, index) => {
            const def = WIDGET_DEFINITIONS[widget.type];
            const Icon = def.icon;
            const colors = getColors(def.color);

            return (
              <motion.div
                key={widget.instanceId}
                layout
                initial={{ opacity: 0, y: 6 }}
                animate={{ opacity: 1, y: 0 }}
                exit={{ opacity: 0, scale: 0.97 }}
                transition={{ duration: 0.16, ease: 'easeOut' }}
                className="card p-5 group"
              >
                {/* Widget header */}
                <div className="flex items-center gap-2.5 mb-3">
                  <div
                    className={`w-8 h-8 rounded-lg flex items-center justify-center shrink-0 ${colors.bg} ${colors.text}`}
                  >
                    <Icon size={15} />
                  </div>
                  <h3 className="text-sm font-semibold text-gray-700 select-none flex-1 leading-none">
                    {def.title}
                  </h3>

                  {/* Controls — visible on hover */}
                  <div className="flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity duration-150">
                    <button
                      onClick={() => toggleSize(index)}
                      className="p-1.5 text-gray-300 hover:text-gray-500 hover:bg-gray-50 rounded-md transition-all"
                      title={widget.size === 'normal' ? 'Compact' : 'Expand'}
                    >
                      {widget.size === 'normal' ? <Minimize2 size={13} /> : <Maximize2 size={13} />}
                    </button>
                    <button
                      onClick={() => removeWidget(index)}
                      className="p-1.5 text-gray-300 hover:text-red-400 hover:bg-red-50 rounded-md transition-all"
                      title="Remove widget"
                    >
                      <X size={13} />
                    </button>
                  </div>
                </div>

                {/* Divider */}
                <div className="h-px bg-gray-100 mb-3" />

                {/* Content */}
                <div
                  className={`transition-all duration-200 overflow-hidden ${
                    widget.size === 'compact' ? 'min-h-[60px]' : 'min-h-[140px]'
                  }`}
                >
                  {widget.type === 'recent-blood-work'   && <RecentBloodWork   size={widget.size} />}
                  {widget.type === 'current-medications' && <CurrentMedications size={widget.size} />}
                  {widget.type === 'vital-signs'         && <VitalSigns         size={widget.size} />}
                  {widget.type === 'device-summary'      && <DeviceSummaryWidget size={widget.size} />}
                  {widget.type === 'recent-history'      && <RecentHistory      size={widget.size} />}
                  {widget.type === 'upcoming-schedule'   && <UpcomingSchedule   size={widget.size} />}
                </div>
              </motion.div>
            );
          })}
        </AnimatePresence>

        {/* Add widget cell */}
        <div
          className="min-h-[180px] rounded-xl border border-dashed border-gray-200 flex flex-col items-center justify-center p-6 cursor-pointer hover:border-primary/40 hover:bg-blue-50/20 transition-all relative group"
          onClick={() => !isAddMenuOpen && setIsAddMenuOpen(true)}
        >
          {!isAddMenuOpen ? (
            <div className="flex flex-col items-center gap-2 text-gray-400 group-hover:text-primary transition-colors select-none">
              <div className="w-9 h-9 rounded-xl border border-gray-200 group-hover:border-primary/30 flex items-center justify-center bg-white transition-colors">
                <Plus size={16} />
              </div>
              <span className="text-sm font-medium">Add Widget</span>
            </div>
          ) : (
            <div
              className="absolute inset-0 card p-4 flex flex-col z-10"
              onClick={(e) => e.stopPropagation()}
            >
              <div className="flex justify-between items-center mb-3 pb-2 border-b border-gray-100">
                <span className="text-sm font-semibold text-gray-700">Add Widget</span>
                <button
                  onClick={() => setIsAddMenuOpen(false)}
                  className="p-1 text-gray-400 hover:text-gray-600 rounded-md hover:bg-gray-50 transition-colors"
                >
                  <X size={13} />
                </button>
              </div>
              <div className="flex-1 overflow-y-auto space-y-0.5">
                {availableWidgets.map((widgetId) => {
                  const wDef = WIDGET_DEFINITIONS[widgetId];
                  const wColors = getColors(wDef.color);
                  return (
                    <button
                      key={widgetId}
                      onClick={() => addWidget(widgetId)}
                      className="w-full text-left flex items-center gap-3 p-2 hover:bg-gray-50 rounded-lg transition-colors group/item"
                    >
                      <div className={`p-1.5 rounded-md ${wColors.bg} ${wColors.text}`}>
                        <wDef.icon size={13} />
                      </div>
                      <span className="text-sm text-gray-600 group-hover/item:text-gray-800 font-medium">
                        {wDef.title}
                      </span>
                      <ChevronRight size={12} className="ml-auto text-gray-300" />
                    </button>
                  );
                })}
                {availableWidgets.length === 0 && (
                  <p className="text-center text-xs text-gray-400 py-4">All widgets active</p>
                )}
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
