import React, { useMemo, useState, useEffect, useCallback } from 'react';
import {
  Plus, Edit2, Trash2, Calendar, MapPin, Users, Clock, X,
  ChevronLeft, ChevronRight, CalendarDays, Video, ExternalLink
} from 'lucide-react';
import api from '../services/api';
import { useSync } from '../contexts/SyncContext';

interface Evento {
  id: number;
  title: string;
  description: string;
  start_datetime: string;
  end_datetime: string;
  location: string;
  video_url: string;
  participants: string;
  creator_name: string;
  created_by: number;
}

const empty = { title: '', description: '', start_datetime: '', end_datetime: '', location: '', video_url: '', participants: '' };
const WEEKDAYS = ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb'];

function dateKey(date: Date | string) {
  const d = typeof date === 'string' ? new Date(date) : date;
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
}

function sameDay(a: Date, b: Date) {
  return dateKey(a) === dateKey(b);
}

function monthLabel(date: Date) {
  return date.toLocaleDateString('pt-BR', { month: 'long', year: 'numeric' });
}

function timeLabel(start: string, end?: string) {
  const startText = new Date(start).toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' });
  if (!end) return startText;
  const endText = new Date(end).toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' });
  return `${startText} - ${endText}`;
}

function normalizeUrl(url: string) {
  const trimmed = url.trim();
  if (!trimmed) return '';
  return /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
}

function buildMonthDays(anchor: Date) {
  const year = anchor.getFullYear();
  const month = anchor.getMonth();
  const first = new Date(year, month, 1);
  const start = new Date(year, month, 1 - first.getDay());
  return Array.from({ length: 42 }, (_, i) => {
    const d = new Date(start);
    d.setDate(start.getDate() + i);
    return d;
  });
}

export default function Agenda() {
  const [events, setEvents] = useState<Evento[]>([]);
  const [visibleMonth, setVisibleMonth] = useState(() => new Date());
  const [selectedDate, setSelectedDate] = useState(() => new Date());
  const [modal, setModal] = useState(false);
  const [editing, setEditing] = useState<Evento | null>(null);
  const [form, setForm] = useState(empty);
  const [error, setError] = useState('');

  const load = useCallback(async () => {
    try {
      const res = await api.get('/agenda');
      setEvents(res.data);
    } catch {
      /* interceptor handles */
    }
  }, []);

  useEffect(() => { load(); }, [load]);
  useSync((event) => {
    if (['agenda:created', 'agenda:updated', 'agenda:deleted'].includes(event)) load();
  });

  const eventsByDay = useMemo(() => {
    return events.reduce<Record<string, Evento[]>>((acc, ev) => {
      const key = dateKey(ev.start_datetime);
      acc[key] = [...(acc[key] || []), ev].sort((a, b) => a.start_datetime.localeCompare(b.start_datetime));
      return acc;
    }, {});
  }, [events]);

  const monthDays = useMemo(() => buildMonthDays(visibleMonth), [visibleMonth]);
  const selectedEvents = eventsByDay[dateKey(selectedDate)] || [];
  const upcoming = useMemo(() => events
    .filter(ev => new Date(ev.start_datetime) >= new Date())
    .sort((a, b) => a.start_datetime.localeCompare(b.start_datetime))
    .slice(0, 5), [events]);

  const openNew = (date = selectedDate) => {
    const start = new Date(date);
    start.setHours(9, 0, 0, 0);
    setEditing(null);
    setForm({ ...empty, start_datetime: start.toISOString().slice(0, 16) });
    setError('');
    setModal(true);
  };

  const openEdit = (ev: Evento) => {
    setEditing(ev);
    setForm({
      title: ev.title,
      description: ev.description || '',
      start_datetime: ev.start_datetime?.slice(0, 16) || '',
      end_datetime: ev.end_datetime?.slice(0, 16) || '',
      location: ev.location || '',
      video_url: ev.video_url || '',
      participants: ev.participants || '',
    });
    setError('');
    setModal(true);
  };

  const moveMonth = (amount: number) => {
    setVisibleMonth(prev => new Date(prev.getFullYear(), prev.getMonth() + amount, 1));
  };

  const goToday = () => {
    const today = new Date();
    setSelectedDate(today);
    setVisibleMonth(today);
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setError('');
    try {
      if (editing) await api.put(`/agenda/${editing.id}`, form);
      else await api.post('/agenda', form);
      setModal(false);
      load();
    } catch (err: unknown) {
      const e = err as { response?: { data?: { error?: string } } };
      setError(e.response?.data?.error || 'Erro ao salvar evento');
    }
  };

  const handleDelete = async (id: number) => {
    if (!confirm('Remover este evento?')) return;
    try {
      await api.delete(`/agenda/${id}`);
      load();
    } catch (err: unknown) {
      const e = err as { response?: { data?: { error?: string } } };
      alert(e.response?.data?.error || 'Erro ao remover evento');
    }
  };

  return (
    <div className="space-y-5 max-w-7xl">
      <div className="flex flex-wrap items-center justify-between gap-3">
        <div className="flex items-center gap-3">
          <div className="w-10 h-10 rounded-xl bg-brand-cyan/10 border border-brand-cyan/20 flex items-center justify-center">
            <CalendarDays size={19} className="text-brand-cyan" />
          </div>
          <div>
            <h2 className="text-white font-semibold text-lg capitalize">{monthLabel(visibleMonth)}</h2>
            <p className="text-gray-600 text-sm">
              {selectedDate.toLocaleDateString('pt-BR', { weekday: 'long', day: '2-digit', month: 'long' })}
            </p>
          </div>
        </div>

        <div className="flex items-center gap-2">
          <button type="button" onClick={() => moveMonth(-1)} className="icon-btn bg-surface-card border border-surface-border hover:text-white">
            <ChevronLeft size={17} />
          </button>
          <button type="button" onClick={goToday} className="btn-secondary px-3 py-2 text-sm">Hoje</button>
          <button type="button" onClick={() => moveMonth(1)} className="icon-btn bg-surface-card border border-surface-border hover:text-white">
            <ChevronRight size={17} />
          </button>
          <button type="button" onClick={() => openNew()} className="btn-primary ml-1">
            <Plus size={16} /> Novo Evento
          </button>
        </div>
      </div>

      <div className="grid grid-cols-1 xl:grid-cols-[minmax(0,1fr)_360px] gap-5">
        <section className="card p-0 overflow-hidden">
          <div className="grid grid-cols-7 border-b border-surface-border bg-surface-border/20">
            {WEEKDAYS.map(day => (
              <div key={day} className="px-3 py-3 text-xs font-semibold uppercase tracking-wider text-gray-500">
                {day}
              </div>
            ))}
          </div>

          <div className="grid grid-cols-7">
            {monthDays.map(day => {
              const key = dateKey(day);
              const dayEvents = eventsByDay[key] || [];
              const outsideMonth = day.getMonth() !== visibleMonth.getMonth();
              const selected = sameDay(day, selectedDate);
              const today = sameDay(day, new Date());

              return (
                <button
                  type="button"
                  key={key}
                  onClick={() => setSelectedDate(day)}
                  onDoubleClick={() => openNew(day)}
                  className={`min-h-[112px] border-r border-b border-surface-border/50 p-3 text-left transition-colors hover:bg-surface-hover/40 ${
                    selected ? 'bg-brand-cyan/10 ring-1 ring-inset ring-brand-cyan/50' : ''
                  } ${outsideMonth ? 'opacity-35' : ''}`}
                >
                  <div className="flex items-center justify-between">
                    <span className={`w-7 h-7 rounded-full flex items-center justify-center text-sm ${
                      today ? 'bg-brand-cyan text-white font-semibold' : 'text-gray-300'
                    }`}>
                      {day.getDate()}
                    </span>
                    {dayEvents.length > 0 && <span className="text-[11px] text-brand-cyan">{dayEvents.length}</span>}
                  </div>

                  <div className="mt-2 space-y-1">
                    {dayEvents.slice(0, 2).map(ev => (
                      <div key={ev.id} className="truncate rounded-md bg-surface-dark/70 px-2 py-1 text-[11px] text-gray-300">
                        {timeLabel(ev.start_datetime)} {ev.title}
                      </div>
                    ))}
                    {dayEvents.length > 2 && (
                      <div className="text-[11px] text-gray-600 px-1">+{dayEvents.length - 2} evento(s)</div>
                    )}
                  </div>
                </button>
              );
            })}
          </div>
        </section>

        <aside className="space-y-5">
          <section className="card">
            <div className="flex items-center justify-between gap-3 mb-4">
              <div>
                <p className="text-gray-500 text-xs uppercase tracking-wider font-semibold">Dia selecionado</p>
                <h3 className="text-white font-semibold mt-1">
                  {selectedDate.toLocaleDateString('pt-BR', { day: '2-digit', month: 'long' })}
                </h3>
              </div>
              <button type="button" onClick={() => openNew(selectedDate)} className="icon-btn hover:text-brand-cyan hover:bg-brand-cyan/10" title="Novo evento neste dia">
                <Plus size={16} />
              </button>
            </div>

            {selectedEvents.length === 0 ? (
              <EmptyAgenda compact />
            ) : (
              <div className="space-y-3">
                {selectedEvents.map(ev => (
                  <EventCard
                    key={ev.id}
                    ev={ev}
                    onEdit={openEdit}
                    onDelete={handleDelete}
                    showEdit
                    showDelete
                  />
                ))}
              </div>
            )}
          </section>

          <section className="card">
            <p className="text-gray-500 text-xs uppercase tracking-wider font-semibold mb-4">Próximos eventos</p>
            {upcoming.length === 0 ? (
              <EmptyAgenda compact />
            ) : (
              <div className="space-y-3">
                {upcoming.map(ev => (
                  <EventCard
                    key={ev.id}
                    ev={ev}
                    onEdit={openEdit}
                    onDelete={handleDelete}
                    showEdit
                    showDelete
                  />
                ))}
              </div>
            )}
          </section>
        </aside>
      </div>

      {modal && (
        <div className="fixed inset-0 bg-black/60 backdrop-blur-sm flex items-start justify-center z-50 p-4 overflow-y-auto">
          <div className="card w-full max-w-lg animate-fade-in my-8">
            <div className="flex items-center justify-between mb-5">
              <h3 className="text-white font-semibold text-lg">{editing ? 'Editar Evento' : 'Novo Evento'}</h3>
              <button onClick={() => setModal(false)} className="icon-btn hover:text-white"><X size={18} /></button>
            </div>
            {error && <div className="bg-red-900/20 border border-red-700/50 text-red-400 rounded-xl px-4 py-3 text-sm mb-4">{error}</div>}
            <form onSubmit={handleSubmit} className="space-y-4">
              <div>
                <label className="text-gray-400 text-sm block mb-1.5">Título *</label>
                <input value={form.title} onChange={e => setForm(f => ({ ...f, title: e.target.value }))} className="input-field" required />
              </div>
              <div>
                <label className="text-gray-400 text-sm block mb-1.5">Descrição</label>
                <textarea value={form.description} onChange={e => setForm(f => ({ ...f, description: e.target.value }))} className="input-field h-20 resize-none" />
              </div>
              <div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
                <div>
                  <label className="text-gray-400 text-sm block mb-1.5">Início *</label>
                  <input type="datetime-local" value={form.start_datetime} onChange={e => setForm(f => ({ ...f, start_datetime: e.target.value }))} className="input-field" required />
                </div>
                <div>
                  <label className="text-gray-400 text-sm block mb-1.5">Término</label>
                  <input type="datetime-local" value={form.end_datetime} onChange={e => setForm(f => ({ ...f, end_datetime: e.target.value }))} className="input-field" />
                </div>
              </div>
              <div>
                <label className="text-gray-400 text-sm block mb-1.5">Local</label>
                <input value={form.location} onChange={e => setForm(f => ({ ...f, location: e.target.value }))} className="input-field" placeholder="Sala, endereço ou local físico..." />
              </div>
              <div>
                <div className="flex items-center justify-between gap-3 mb-1.5">
                  <label className="text-gray-400 text-sm">Videochamada</label>
                  <div className="flex gap-1">
                    {[
                      ['Meet', 'https://meet.google.com/'],
                      ['Teams', 'https://teams.microsoft.com/l/meetup-join/'],
                      ['Zoom', 'https://zoom.us/j/'],
                    ].map(([label, value]) => (
                      <button
                        key={label}
                        type="button"
                        onClick={() => setForm(f => ({ ...f, video_url: value }))}
                        className="px-2 py-1 rounded-md border border-surface-border text-[11px] text-gray-300 hover:text-white hover:bg-surface-hover transition-colors"
                      >
                        {label}
                      </button>
                    ))}
                  </div>
                </div>
                <input value={form.video_url} onChange={e => setForm(f => ({ ...f, video_url: e.target.value }))} className="input-field" placeholder="Cole o link do Meet, Teams, Zoom..." />
              </div>
              <div>
                <label className="text-gray-400 text-sm block mb-1.5">Participantes</label>
                <input value={form.participants} onChange={e => setForm(f => ({ ...f, participants: e.target.value }))} className="input-field" placeholder="Ana, João, equipe..." />
              </div>
              <div className="flex gap-3 pt-1">
                <button type="submit" className="btn-primary flex-1">{editing ? 'Salvar' : 'Criar Evento'}</button>
                <button type="button" onClick={() => setModal(false)} className="btn-secondary flex-1">Cancelar</button>
              </div>
            </form>
          </div>
        </div>
      )}
    </div>
  );
}

function EmptyAgenda({ compact = false }: { compact?: boolean }) {
  return (
    <div className={`flex flex-col items-center justify-center text-gray-700 ${compact ? 'py-7' : 'py-14'}`}>
      <Calendar size={compact ? 28 : 42} className="mb-2 opacity-30" />
      <p className="text-sm">Nenhum evento</p>
    </div>
  );
}

function EventCard({ ev, onEdit, onDelete, showEdit, showDelete }: {
  ev: Evento;
  onEdit: (e: Evento) => void;
  onDelete: (id: number) => void;
  showEdit: boolean;
  showDelete: boolean;
}) {
  const date = new Date(ev.start_datetime);
  return (
    <div className="rounded-xl border border-surface-border bg-surface-dark/45 p-3 hover:border-brand-cyan/25 transition-colors">
      <div className="flex items-start justify-between gap-3">
        <div className="min-w-0">
          <p className="text-white text-sm font-semibold leading-tight truncate">{ev.title}</p>
          <div className="flex items-center gap-1.5 text-brand-cyan text-xs mt-2">
            <Clock size={12} />
            <span>{date.toLocaleDateString('pt-BR', { day: '2-digit', month: '2-digit' })} às {timeLabel(ev.start_datetime, ev.end_datetime)}</span>
          </div>
        </div>
        <div className="flex gap-1 flex-shrink-0">
          {showEdit && <button onClick={() => onEdit(ev)} className="icon-btn hover:text-brand-cyan hover:bg-brand-cyan/10"><Edit2 size={14} /></button>}
          {showDelete && <button onClick={() => onDelete(ev.id)} className="icon-btn hover:text-red-400 hover:bg-red-400/10"><Trash2 size={14} /></button>}
        </div>
      </div>

      {ev.description && <p className="text-gray-500 text-xs mt-2 line-clamp-2">{ev.description}</p>}
      {(ev.location || ev.participants) && (
        <div className="flex flex-wrap gap-3 mt-3 text-xs text-gray-600">
          {ev.location && <span className="flex items-center gap-1"><MapPin size={11} />{ev.location}</span>}
          {ev.participants && <span className="flex items-center gap-1"><Users size={11} />{ev.participants}</span>}
        </div>
      )}
      {ev.video_url && (
        <a
          href={normalizeUrl(ev.video_url)}
          target="_blank"
          rel="noreferrer"
          className="mt-3 inline-flex items-center gap-1.5 rounded-lg bg-brand-cyan/15 px-3 py-1.5 text-xs font-medium text-brand-cyan hover:bg-brand-cyan/25 transition-colors"
        >
          <Video size={12} /> Entrar na reunião <ExternalLink size={11} />
        </a>
      )}
      {ev.creator_name && <p className="text-gray-700 text-[11px] mt-3">por {ev.creator_name}</p>}
    </div>
  );
}

