import { useState, useRef, useEffect, useCallback } from 'react';
import { X, Dumbbell, Pill, FileText, Plus, Pencil, Trash2, CheckCircle2, Circle } from 'lucide-react';
import { toast } from 'sonner';
import type { DayDetail, CalendarEvent as CalEvent } from '../../types/calendar';
import { upsertNote, deleteEvent } from '../../api/calendar';
import CalendarEventForm from './CalendarEventForm';

const MOOD_OPTIONS = [
  { value: 'great', emoji: '😄', label: 'Great' },
  { value: 'good', emoji: '🙂', label: 'Good' },
  { value: 'okay', emoji: '😐', label: 'Okay' },
  { value: 'bad', emoji: '😕', label: 'Bad' },
  { value: 'awful', emoji: '😞', label: 'Awful' },
];

function formatDate(dateStr: string): string {
  const [year, month, day] = dateStr.split('-').map(Number);
  return new Date(year, month - 1, day).toLocaleDateString('en-US', {
    weekday: 'long', year: 'numeric', month: 'long', day: 'numeric',
  });
}

function colorClass(color?: string): string {
  const map: Record<string, string> = {
    blue: 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-300',
    green: 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300',
    red: 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-300',
    purple: 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-300',
    orange: 'bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-300',
    pink: 'bg-pink-100 text-pink-700 dark:bg-pink-900/30 dark:text-pink-300',
  };
  return color && map[color] ? map[color] : 'bg-zinc-100 text-zinc-700 dark:bg-zinc-800 dark:text-zinc-300';
}

// ── Workout Tab ───────────────────────────────────────────────────────────────

function WorkoutTab({ detail, onRefresh }: { detail: DayDetail; onRefresh: () => void }) {
  const [showForm, setShowForm] = useState(false);
  const [editEvent, setEditEvent] = useState<CalEvent | null>(null);

  const workoutEvents = detail.events.filter(e => e.event_type === 'workout');

  const handleDelete = async (id: number) => {
    try {
      await deleteEvent(id);
      toast.success('Event deleted');
      onRefresh();
    } catch {
      toast.error('Failed to delete event');
    }
  };

  if (showForm || editEvent) {
    return (
      <div>
        <h3 className="text-sm font-medium text-zinc-500 dark:text-zinc-400 mb-3">
          {editEvent ? 'Edit Event' : 'Add Workout Event'}
        </h3>
        <CalendarEventForm
          date={detail.date}
          existing={editEvent ?? undefined}
          defaultType="workout"
          onSuccess={() => { setShowForm(false); setEditEvent(null); onRefresh(); }}
          onCancel={() => { setShowForm(false); setEditEvent(null); }}
        />
      </div>
    );
  }

  return (
    <div className="space-y-4">
      {/* Kettlebell sessions */}
      {detail.kettlebell_sessions.length > 0 && (
        <div>
          <h3 className="text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400 mb-2">
            Kettlebell Sessions
          </h3>
          <div className="space-y-2">
            {detail.kettlebell_sessions.map(kb => (
              <div key={kb.id} className="rounded-lg border border-zinc-200 dark:border-zinc-700 p-3">
                <div className="flex items-start justify-between">
                  <div>
                    <p className="text-sm font-medium text-zinc-900 dark:text-zinc-100">{kb.title}</p>
                    <p className="text-xs text-zinc-500 dark:text-zinc-400 mt-0.5">
                      {kb.focus} · {kb.total_duration_min} min · {kb.difficulty}
                    </p>
                  </div>
                  <span className={`text-xs px-2 py-0.5 rounded-full font-medium ${
                    kb.status === 'completed'
                      ? 'bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300'
                      : 'bg-zinc-100 text-zinc-600 dark:bg-zinc-800 dark:text-zinc-400'
                  }`}>
                    {kb.status}
                  </span>
                </div>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Workout events */}
      {workoutEvents.length > 0 && (
        <div>
          <h3 className="text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400 mb-2">
            Workout Events
          </h3>
          <div className="space-y-2">
            {workoutEvents.map(ev => (
              <div key={ev.id} className={`rounded-lg p-3 ${colorClass(ev.color)}`}>
                <div className="flex items-start justify-between gap-2">
                  <div className="min-w-0 flex-1">
                    <div className="flex items-center gap-1.5">
                      {ev.is_completed ? <CheckCircle2 size={14} /> : <Circle size={14} />}
                      <p className="text-sm font-medium truncate">{ev.title}</p>
                    </div>
                    {ev.description && (
                      <p className="text-xs mt-0.5 opacity-75 truncate">{ev.description}</p>
                    )}
                    {ev.start_time && (
                      <p className="text-xs mt-0.5 opacity-60">{ev.start_time}</p>
                    )}
                  </div>
                  <div className="flex gap-1 shrink-0">
                    <button onClick={() => setEditEvent(ev)} className="p-1 rounded hover:opacity-75 transition-opacity">
                      <Pencil size={13} />
                    </button>
                    <button onClick={() => ev.id && handleDelete(ev.id)} className="p-1 rounded hover:opacity-75 transition-opacity">
                      <Trash2 size={13} />
                    </button>
                  </div>
                </div>
              </div>
            ))}
          </div>
        </div>
      )}

      {detail.kettlebell_sessions.length === 0 && workoutEvents.length === 0 && (
        <p className="text-sm text-zinc-400 dark:text-zinc-500 text-center py-6">No workouts logged for this day.</p>
      )}

      <button
        onClick={() => setShowForm(true)}
        className="flex items-center gap-2 text-sm text-primary hover:text-primary/80 transition-colors"
      >
        <Plus size={15} /> Add workout event
      </button>
    </div>
  );
}

// ── Supplements Tab ───────────────────────────────────────────────────────────

function SupplementsTab({ detail }: { detail: DayDetail }) {
  const taken = detail.supplements.filter(s => s.taken_today);
  const notTaken = detail.supplements.filter(s => !s.taken_today);
  const compliance = detail.supplements.length > 0
    ? Math.round((taken.length / detail.supplements.length) * 100)
    : null;

  return (
    <div className="space-y-4">
      {compliance !== null && (
        <div className="rounded-lg bg-zinc-50 dark:bg-zinc-800/50 p-3 flex items-center gap-3">
          <div className="flex-1">
            <div className="flex justify-between text-xs text-zinc-500 dark:text-zinc-400 mb-1">
              <span>Compliance</span>
              <span>{taken.length}/{detail.supplements.length}</span>
            </div>
            <div className="h-2 rounded-full bg-zinc-200 dark:bg-zinc-700 overflow-hidden">
              <div
                className={`h-full rounded-full transition-all ${compliance >= 80 ? 'bg-green-500' : compliance >= 50 ? 'bg-yellow-500' : 'bg-red-500'}`}
                style={{ width: `${compliance}%` }}
              />
            </div>
          </div>
          <span className="text-lg font-bold text-zinc-900 dark:text-zinc-100">{compliance}%</span>
        </div>
      )}

      {detail.supplements.length === 0 && (
        <p className="text-sm text-zinc-400 dark:text-zinc-500 text-center py-6">No active supplements.</p>
      )}

      {taken.length > 0 && (
        <div>
          <h3 className="text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400 mb-2">Taken</h3>
          <div className="space-y-1.5">
            {taken.map(s => (
              <div key={s.id} className="flex items-center gap-2 rounded-md bg-green-50 dark:bg-green-900/20 px-3 py-2">
                <CheckCircle2 size={15} className="text-green-500 shrink-0" />
                <span className="text-sm text-zinc-900 dark:text-zinc-100">{s.name}</span>
                <span className="text-xs text-zinc-500 dark:text-zinc-400 ml-auto">{s.dosage} {s.unit}</span>
              </div>
            ))}
          </div>
        </div>
      )}

      {notTaken.length > 0 && (
        <div>
          <h3 className="text-xs font-semibold uppercase tracking-wide text-zinc-500 dark:text-zinc-400 mb-2">Not Taken</h3>
          <div className="space-y-1.5">
            {notTaken.map(s => (
              <div key={s.id} className="flex items-center gap-2 rounded-md bg-zinc-50 dark:bg-zinc-800/50 px-3 py-2">
                <Circle size={15} className="text-zinc-400 shrink-0" />
                <span className="text-sm text-zinc-500 dark:text-zinc-400">{s.name}</span>
                <span className="text-xs text-zinc-400 ml-auto">{s.dosage} {s.unit}</span>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
}

// ── Notes Tab ─────────────────────────────────────────────────────────────────

function NotesTab({ detail, onRefresh }: { detail: DayDetail; onRefresh: () => void }) {
  const [content, setContent] = useState(detail.note?.content ?? '');
  const [mood, setMood] = useState(detail.note?.mood ?? '');
  const [energyLevel, setEnergyLevel] = useState(detail.note?.energy_level ?? 5);
  const [saveStatus, setSaveStatus] = useState<'idle' | 'saving' | 'saved'>('idle');
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  const save = useCallback(async (c: string, m: string, e: number) => {
    setSaveStatus('saving');
    try {
      await upsertNote(detail.date, {
        content: c,
        mood: m || undefined,
        energy_level: e,
      });
      setSaveStatus('saved');
      onRefresh();
    } catch {
      setSaveStatus('idle');
      toast.error('Failed to save note');
    }
  }, [detail.date, onRefresh]);

  const scheduleAutosave = (c: string, m: string, e: number) => {
    if (debounceRef.current) clearTimeout(debounceRef.current);
    debounceRef.current = setTimeout(() => save(c, m, e), 1500);
  };

  useEffect(() => {
    return () => {
      if (debounceRef.current) clearTimeout(debounceRef.current);
    };
  }, []);

  const handleContentChange = (val: string) => {
    if (val.length > 10000) return;
    setContent(val);
    setSaveStatus('idle');
    scheduleAutosave(val, mood, energyLevel);
  };

  const handleMoodChange = (val: string) => {
    const newMood = mood === val ? '' : val;
    setMood(newMood);
    setSaveStatus('idle');
    scheduleAutosave(content, newMood, energyLevel);
  };

  const handleEnergyChange = (val: number) => {
    setEnergyLevel(val);
    setSaveStatus('idle');
    scheduleAutosave(content, mood, val);
  };

  return (
    <div className="space-y-4">
      <div>
        <div className="flex items-center justify-between mb-1">
          <label className="text-sm font-medium text-zinc-700 dark:text-zinc-300">Notes</label>
          <span className="text-xs text-zinc-400">
            {saveStatus === 'saving' && 'Saving...'}
            {saveStatus === 'saved' && <span className="text-green-500">Saved</span>}
            {saveStatus === 'idle' && `${content.length}/10000`}
          </span>
        </div>
        <textarea
          value={content}
          onChange={e => handleContentChange(e.target.value)}
          rows={6}
          maxLength={10000}
          className="w-full rounded-md border border-zinc-300 dark:border-zinc-600 bg-white dark:bg-zinc-800 px-3 py-2 text-sm text-zinc-900 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-primary resize-none"
          placeholder="How did your day go? Any notes about your health, workouts, or wellbeing..."
        />
      </div>

      <div>
        <label className="text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2 block">Mood</label>
        <div className="flex gap-2">
          {MOOD_OPTIONS.map(opt => (
            <button
              key={opt.value}
              type="button"
              onClick={() => handleMoodChange(opt.value)}
              className={`flex flex-col items-center gap-0.5 rounded-lg p-2 text-xs transition-colors border-2 ${
                mood === opt.value
                  ? 'border-primary bg-primary/10'
                  : 'border-transparent hover:border-zinc-300 dark:hover:border-zinc-600'
              }`}
              title={opt.label}
            >
              <span className="text-xl">{opt.emoji}</span>
              <span className="text-zinc-500 dark:text-zinc-400">{opt.label}</span>
            </button>
          ))}
        </div>
      </div>

      <div>
        <div className="flex items-center justify-between mb-2">
          <label className="text-sm font-medium text-zinc-700 dark:text-zinc-300">Energy Level</label>
          <span className="text-sm font-bold text-primary">{energyLevel}/10</span>
        </div>
        <input
          type="range"
          min={1}
          max={10}
          value={energyLevel}
          onChange={e => handleEnergyChange(Number(e.target.value))}
          className="w-full accent-primary"
        />
        <div className="flex justify-between text-xs text-zinc-400 mt-1">
          <span>Low</span><span>High</span>
        </div>
      </div>
    </div>
  );
}

// ── DayModal ──────────────────────────────────────────────────────────────────

type Tab = 'workout' | 'supplements' | 'notes';

interface Props {
  date: string;
  detail: DayDetail | null;
  loading: boolean;
  onClose: () => void;
  onRefresh: () => void;
}

export default function DayModal({ date, detail, loading, onClose, onRefresh }: Props) {
  const [activeTab, setActiveTab] = useState<Tab>('notes');

  const tabs: { id: Tab; label: string; icon: React.ReactNode }[] = [
    { id: 'workout', label: 'Workout', icon: <Dumbbell size={15} /> },
    { id: 'supplements', label: 'Supplements', icon: <Pill size={15} /> },
    { id: 'notes', label: 'Notes', icon: <FileText size={15} /> },
  ];

  return (
    <div className="fixed inset-0 z-50 flex items-end sm:items-center justify-center">
      {/* Backdrop */}
      <div className="absolute inset-0 bg-black/50" onClick={onClose} />

      {/* Panel */}
      <div className="relative z-10 w-full sm:max-w-lg sm:mx-4 bg-white dark:bg-zinc-900 rounded-t-2xl sm:rounded-2xl shadow-2xl max-h-[90vh] flex flex-col">
        {/* Header */}
        <div className="flex items-center justify-between px-5 py-4 border-b border-zinc-200 dark:border-zinc-800">
          <h2 className="text-base font-semibold text-zinc-900 dark:text-zinc-100">
            {formatDate(date)}
          </h2>
          <button
            onClick={onClose}
            className="text-zinc-500 hover:text-zinc-700 dark:hover:text-zinc-300 transition-colors rounded-md p-1"
            aria-label="Close"
          >
            <X size={18} />
          </button>
        </div>

        {/* Tabs */}
        <div className="flex border-b border-zinc-200 dark:border-zinc-800 px-2">
          {tabs.map(tab => (
            <button
              key={tab.id}
              onClick={() => setActiveTab(tab.id)}
              className={`flex items-center gap-1.5 px-4 py-3 text-sm font-medium border-b-2 transition-colors ${
                activeTab === tab.id
                  ? 'border-primary text-primary'
                  : 'border-transparent text-zinc-500 dark:text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-300'
              }`}
            >
              {tab.icon}
              {tab.label}
            </button>
          ))}
        </div>

        {/* Content */}
        <div className="flex-1 overflow-y-auto p-5">
          {loading && (
            <div className="flex items-center justify-center py-12">
              <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary" />
            </div>
          )}
          {!loading && detail && (
            <>
              {activeTab === 'workout' && <WorkoutTab detail={detail} onRefresh={onRefresh} />}
              {activeTab === 'supplements' && <SupplementsTab detail={detail} />}
              {activeTab === 'notes' && <NotesTab detail={detail} onRefresh={onRefresh} />}
            </>
          )}
          {!loading && !detail && (
            <p className="text-sm text-zinc-400 text-center py-12">Failed to load day details.</p>
          )}
        </div>
      </div>
    </div>
  );
}
