import { useEffect, useMemo, useState } from 'react';
import { ChevronLeft, ChevronRight, Plus, Trash2, Pencil, Clock, User } from 'lucide-react';
import { api, fmt } from '../api';
import { Card, Badge, Btn, Field, inputCls, Modal, Spinner, ErrorBox } from '../components/ui';

const DAY_NAMES = ['ma', 'di', 'wo', 'do', 'vr', 'za', 'zo'];

const TYPE_LABELS = {
  meeting: 'Afspraak', call: 'Telefoongesprek', deadline: 'Deadline',
  workshop: 'Workshop', review: 'Review', other: 'Overig'
};
const TYPE_COLORS = {
  meeting: 'accent', call: 'blue', deadline: 'red',
  workshop: 'purple', review: 'yellow', other: 'muted'
};

// ---- datum-helpers ----
function pad(n) { return String(n).padStart(2, '0'); }
function dateKey(d) { return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`; }
function parseDT(v) {
  if (!v) return null;
  const d = new Date(String(v).replace(' ', 'T'));
  return isNaN(d) ? null : d;
}
function toLocalInput(v) {
  const d = parseDT(v);
  if (!d) return '';
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
}

// Bouw het maandraster: weken van maandag t/m zondag
function buildGrid(cursor) {
  const first = new Date(cursor.getFullYear(), cursor.getMonth(), 1);
  // maandag = 0 ... zondag = 6
  const offset = (first.getDay() + 6) % 7;
  const start = new Date(first);
  start.setDate(first.getDate() - offset);
  const days = [];
  const d = new Date(start);
  // altijd volledige weken; zorg dat de hele maand zichtbaar is
  do {
    days.push(new Date(d));
    d.setDate(d.getDate() + 1);
  } while (d.getMonth() === cursor.getMonth() || days.length % 7 !== 0);
  return days;
}

const EMPTY_FORM = {
  title: '', event_type: 'meeting', start_time: '', end_time: '',
  all_day: false, client_id: '', color: '#58a6ff', description: ''
};

function EventForm({ form, setForm, clients }) {
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  return (
    <div className="space-y-3">
      <Field label="Titel *">
        <input className={inputCls} value={form.title} onChange={e => set('title', e.target.value)} placeholder="Bijv. kickoff meeting" />
      </Field>
      <div className="grid grid-cols-2 gap-3">
        <Field label="Type">
          <select className={inputCls} value={form.event_type} onChange={e => set('event_type', e.target.value)}>
            {Object.entries(TYPE_LABELS).map(([k, l]) => <option key={k} value={k}>{l}</option>)}
          </select>
        </Field>
        <Field label="Cliënt (optioneel)">
          <select className={inputCls} value={form.client_id} onChange={e => set('client_id', e.target.value)}>
            <option value="">— Geen —</option>
            {clients.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
          </select>
        </Field>
      </div>
      <div className="grid grid-cols-2 gap-3">
        <Field label="Start *">
          <input type="datetime-local" className={inputCls} value={form.start_time} onChange={e => set('start_time', e.target.value)} />
        </Field>
        <Field label="Einde *">
          <input type="datetime-local" className={inputCls} value={form.end_time} onChange={e => set('end_time', e.target.value)} />
        </Field>
      </div>
      <div className="flex items-center gap-4">
        <label className="flex items-center gap-2 text-[13px] cursor-pointer">
          <input type="checkbox" checked={form.all_day} onChange={e => set('all_day', e.target.checked)} className="accent-[#00d4ff]" />
          Hele dag
        </label>
        <label className="flex items-center gap-2 text-[13px] cursor-pointer">
          Kleur
          <input type="color" value={form.color} onChange={e => set('color', e.target.value)} className="w-8 h-8 rounded cursor-pointer bg-transparent border border-border" />
        </label>
      </div>
      <Field label="Beschrijving">
        <textarea className={inputCls} rows={3} value={form.description} onChange={e => set('description', e.target.value)} />
      </Field>
    </div>
  );
}

export default function Calendar() {
  const [cursor, setCursor] = useState(() => { const d = new Date(); d.setDate(1); return d; });
  const [events, setEvents] = useState(null);
  const [clients, setClients] = useState([]);
  const [error, setError] = useState(null);

  const [formOpen, setFormOpen] = useState(false);
  const [form, setForm] = useState(EMPTY_FORM);
  const [editId, setEditId] = useState(null);
  const [saving, setSaving] = useState(false);
  const [formError, setFormError] = useState(null);
  const [detail, setDetail] = useState(null);

  const load = () => {
    setError(null);
    api.get('/calendar').then(setEvents).catch(setError);
  };
  useEffect(load, []);
  useEffect(() => { api.get('/clients').then(setClients).catch(() => {}); }, []);

  const days = useMemo(() => buildGrid(cursor), [cursor]);
  const weeks = days.length / 7;
  const todayKey = dateKey(new Date());

  const eventsByDay = useMemo(() => {
    const map = {};
    for (const ev of events || []) {
      const s = parseDT(ev.start_time);
      const e = parseDT(ev.end_time) || s;
      if (!s) continue;
      const cur = new Date(s.getFullYear(), s.getMonth(), s.getDate());
      const end = new Date(e.getFullYear(), e.getMonth(), e.getDate());
      while (cur <= end) {
        const k = dateKey(cur);
        (map[k] = map[k] || []).push(ev);
        cur.setDate(cur.getDate() + 1);
      }
    }
    return map;
  }, [events]);

  const shiftMonth = (n) => {
    const d = new Date(cursor);
    d.setMonth(d.getMonth() + n);
    setCursor(d);
  };
  const goToday = () => { const d = new Date(); d.setDate(1); setCursor(d); };

  const openCreate = (day) => {
    const k = dateKey(day);
    setEditId(null);
    setForm({ ...EMPTY_FORM, start_time: `${k}T09:00`, end_time: `${k}T10:00` });
    setFormError(null);
    setFormOpen(true);
  };

  const openEdit = (ev) => {
    setDetail(null);
    setEditId(ev.id);
    setForm({
      title: ev.title || '',
      event_type: ev.event_type || 'meeting',
      start_time: toLocalInput(ev.start_time),
      end_time: toLocalInput(ev.end_time),
      all_day: !!ev.all_day,
      client_id: ev.client_id || '',
      color: ev.color || '#58a6ff',
      description: ev.description || ''
    });
    setFormError(null);
    setFormOpen(true);
  };

  const save = async () => {
    if (!form.title.trim()) return setFormError('Titel is verplicht');
    if (!form.start_time || !form.end_time) return setFormError('Start- en eindtijd zijn verplicht');
    setSaving(true);
    setFormError(null);
    try {
      const body = { ...form, client_id: form.client_id || null };
      if (editId) await api.put(`/calendar/${editId}`, body);
      else await api.post('/calendar', body);
      setFormOpen(false);
      load();
    } catch (e) {
      setFormError(e.message);
    } finally {
      setSaving(false);
    }
  };

  const remove = async (ev) => {
    if (!window.confirm(`Event "${ev.title}" verwijderen?`)) return;
    try {
      await api.del(`/calendar/${ev.id}`);
      setDetail(null);
      load();
    } catch (e) {
      alert(e.message);
    }
  };

  if (error) return <ErrorBox error={error} onRetry={load} />;
  if (!events) return <Spinner />;

  const monthLabel = cursor.toLocaleDateString('nl-NL', { month: 'long', year: 'numeric' });

  return (
    <div className="space-y-4 fade-in">
      <div className="flex items-center justify-between flex-wrap gap-2">
        <div>
          <h1 className="text-xl font-bold tracking-tight">Kalender</h1>
          <p className="text-[13px] text-muted mt-0.5 capitalize">{monthLabel}</p>
        </div>
        <div className="flex items-center gap-2">
          <Btn variant="secondary" size="sm" onClick={() => shiftMonth(-1)}><ChevronLeft className="w-4 h-4" /></Btn>
          <Btn variant="secondary" size="sm" onClick={goToday}>Vandaag</Btn>
          <Btn variant="secondary" size="sm" onClick={() => shiftMonth(1)}><ChevronRight className="w-4 h-4" /></Btn>
          <Btn size="sm" onClick={() => openCreate(new Date())}><Plus className="w-3.5 h-3.5" /> Nieuw event</Btn>
        </div>
      </div>

      <Card padding={false} className="overflow-hidden">
        {/* dagnamen */}
        <div className="grid grid-cols-7 border-b border-border-soft">
          {DAY_NAMES.map(d => (
            <div key={d} className="px-2 py-2 text-[11px] font-medium text-muted text-center uppercase tracking-wide">{d}</div>
          ))}
        </div>
        {/* dagen */}
        <div className="grid grid-cols-7" style={{ gridTemplateRows: `repeat(${weeks}, minmax(96px, auto))` }}>
          {days.map((day) => {
            const k = dateKey(day);
            const dayEvents = eventsByDay[k] || [];
            const inMonth = day.getMonth() === cursor.getMonth();
            const isToday = k === todayKey;
            return (
              <div
                key={k}
                onClick={() => openCreate(day)}
                className={`border-b border-r border-border-soft/50 p-1.5 cursor-pointer hover:bg-card-hover transition-colors min-h-[96px] ${inMonth ? '' : 'bg-bg-soft/40'}`}
              >
                <div className="flex justify-end mb-1">
                  <span className={`text-[11px] w-6 h-6 flex items-center justify-center rounded-full ${
                    isToday ? 'ring-2 ring-accent text-accent font-bold' : inMonth ? 'text-text' : 'text-muted'
                  }`}>
                    {day.getDate()}
                  </span>
                </div>
                <div className="space-y-0.5">
                  {dayEvents.slice(0, 3).map(ev => (
                    <button
                      key={ev.id}
                      onClick={(e) => { e.stopPropagation(); setDetail(ev); }}
                      className="w-full flex items-center gap-1 px-1.5 py-0.5 rounded text-left text-[11px] leading-tight"
                      style={{ backgroundColor: `${ev.color || '#58a6ff'}33`, color: ev.color || '#58a6ff' }}
                    >
                      <span className="truncate flex-1">{ev.title}</span>
                      <span className="hidden xl:inline shrink-0">
                        <Badge color={TYPE_COLORS[ev.event_type] || 'muted'}>{TYPE_LABELS[ev.event_type] || ev.event_type}</Badge>
                      </span>
                    </button>
                  ))}
                  {dayEvents.length > 3 && (
                    <div className="text-[10px] text-muted px-1.5">+{dayEvents.length - 3} meer</div>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      </Card>

      {/* legenda */}
      <div className="flex items-center gap-3 flex-wrap">
        <span className="text-[12px] text-muted">Legenda:</span>
        {Object.entries(TYPE_LABELS).map(([k, l]) => (
          <Badge key={k} color={TYPE_COLORS[k]}>{l}</Badge>
        ))}
      </div>

      {/* Nieuw / bewerk event */}
      <Modal open={formOpen} onClose={() => setFormOpen(false)} title={editId ? 'Event bewerken' : 'Nieuw event'}>
        <EventForm form={form} setForm={setForm} clients={clients} />
        {formError && <div className="text-red text-[12px] mt-3">{formError}</div>}
        <div className="flex justify-end gap-2 mt-4">
          <Btn variant="secondary" onClick={() => setFormOpen(false)}>Annuleren</Btn>
          <Btn onClick={save} loading={saving}>{editId ? 'Opslaan' : 'Toevoegen'}</Btn>
        </div>
      </Modal>

      {/* Event-detail */}
      <Modal open={!!detail} onClose={() => setDetail(null)} title={detail?.title || ''}>
        {detail && (
          <div className="space-y-3">
            <div className="flex items-center gap-2 flex-wrap">
              <Badge color={TYPE_COLORS[detail.event_type] || 'muted'}>{TYPE_LABELS[detail.event_type] || detail.event_type}</Badge>
              {!!detail.all_day && <Badge color="blue">Hele dag</Badge>}
              <span className="inline-flex items-center gap-1.5 text-[12px] text-muted">
                <span className="w-3 h-3 rounded-full inline-block" style={{ backgroundColor: detail.color || '#58a6ff' }} />
                {detail.color}
              </span>
            </div>
            <div className="flex items-center gap-2 text-[13px] text-muted">
              <Clock className="w-4 h-4 shrink-0" />
              <span>{fmt.datetime(detail.start_time)} — {fmt.datetime(detail.end_time)}</span>
            </div>
            {detail.client_name && (
              <div className="flex items-center gap-2 text-[13px] text-muted">
                <User className="w-4 h-4 shrink-0" />
                <span>{detail.client_name}</span>
              </div>
            )}
            {detail.description && (
              <p className="text-[13px] whitespace-pre-wrap">{detail.description}</p>
            )}
            <div className="flex justify-between pt-2 border-t border-border-soft">
              <Btn variant="danger" size="sm" onClick={() => remove(detail)}><Trash2 className="w-3.5 h-3.5" /> Verwijderen</Btn>
              <Btn size="sm" onClick={() => openEdit(detail)}><Pencil className="w-3.5 h-3.5" /> Bewerken</Btn>
            </div>
          </div>
        )}
      </Modal>
    </div>
  );
}
