'use client';

import { useCallback, useEffect, useState } from 'react';
import type { ComponentType } from 'react';
import FullCalendarBase from '@fullcalendar/react';
import type { DatesSetArg, EventClickArg, EventContentArg, EventInput } from '@fullcalendar/core';
import dayGridPlugin from '@fullcalendar/daygrid';
import timeGridPlugin from '@fullcalendar/timegrid';
import trLocale from '@fullcalendar/core/locales/tr.js';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { apiFetchJson } from '@/lib/auth';
import { BookOpen, CalendarDays, X } from 'lucide-react';

const FullCalendar = FullCalendarBase as unknown as ComponentType<Record<string, unknown>>;

type ApiActivity = {
  id: string;
  classroomId: string;
  classroom?: { id: string; name: string; branch?: { name: string } | null } | null;
  title: string;
  description: string | null;
  startsOn: string;
  endsOn: string;
};

type Classroom = {
  id: string;
  name: string;
  branch?: { name: string } | null;
};

interface FcEvent extends EventInput {
  id: string;
  extendedProps: { description: string; classroomName: string };
}

function toYmdLocal(d: Date): string {
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, '0');
  const day = String(d.getDate()).padStart(2, '0');
  return `${y}-${m}-${day}`;
}

function defaultVisibleRange() {
  const n = new Date();
  const from = new Date(n.getFullYear(), n.getMonth() - 1, 1);
  const to = new Date(n.getFullYear(), n.getMonth() + 2, 0);
  return { from: toYmdLocal(from), to: toYmdLocal(to) };
}

function addOneDayYmd(iso: string): string {
  const d = new Date(`${iso}T12:00:00`);
  d.setDate(d.getDate() + 1);
  return toYmdLocal(d);
}

function apiRowToFcEvent(a: ApiActivity): FcEvent {
  const description = a.description ?? '';
  const classroomName = a.classroom
    ? (a.classroom.branch?.name ? `${a.classroom.branch.name} / ${a.classroom.name}` : a.classroom.name)
    : '';
  const base = { backgroundColor: 'transparent', borderColor: 'transparent', textColor: 'inherit' };
  if (a.startsOn === a.endsOn) {
    return { id: a.id, title: a.title, start: a.startsOn, allDay: true, extendedProps: { description, classroomName }, ...base };
  }
  return { id: a.id, title: a.title, start: a.startsOn, end: addOneDayYmd(a.endsOn), allDay: true, extendedProps: { description, classroomName }, ...base };
}

const TONE_COUNT = 8;
function toneIndex(id: string): number {
  let h = 2166136261;
  for (let i = 0; i < id.length; i += 1) { h ^= id.charCodeAt(i); h = Math.imul(h, 16777619); }
  return Math.abs(h >>> 0) % TONE_COUNT;
}

function renderEventContent(eventInfo: EventContentArg) {
  const id = String(eventInfo.event.id ?? '');
  const tone = toneIndex(id);
  return (
    <div className={`calendar-event-pill calendar-event-tone-${tone} fc-event-main`}>
      <span className="calendar-event-accent" aria-hidden />
      <div className="calendar-event-body">
        {eventInfo.timeText ? <span className="calendar-event-time">{eventInfo.timeText}</span> : null}
        <span className="calendar-event-title">{eventInfo.event.title}</span>
      </div>
    </div>
  );
}

export function TeacherEventsCalendar() {
  const [classrooms, setClassrooms] = useState<Classroom[]>([]);
  const [selectedClassroomId, setSelectedClassroomId] = useState('');
  const [events, setEvents] = useState<FcEvent[]>([]);
  const [loading, setLoading] = useState(false);
  const [visibleRange, setVisibleRange] = useState(defaultVisibleRange);
  const [detailEvent, setDetailEvent] = useState<{ title: string; description: string; startsOn: string; endsOn: string; classroomName: string } | null>(null);

  // Öğretmenin sınıflarını yükle
  useEffect(() => {
    apiFetchJson<Classroom[]>('/v1/teacher/attendance/my-classrooms').then((res) => {
      const cls = res.data ?? [];
      setClassrooms(cls);
      if (cls.length === 1) setSelectedClassroomId(cls[0].id);
    });
  }, []);

  const loadActivities = useCallback(async () => {
    if (!selectedClassroomId) {
      setEvents([]);
      return;
    }
    setLoading(true);
    const q = new URLSearchParams({ classroomId: selectedClassroomId, from: visibleRange.from, to: visibleRange.to });
    const res = await apiFetchJson<ApiActivity[]>(`/v1/teacher/attendance/classroom-activities?${q.toString()}`);
    const rows = Array.isArray(res.data) ? res.data : [];
    setEvents(rows.map(apiRowToFcEvent));
    setLoading(false);
  }, [selectedClassroomId, visibleRange.from, visibleRange.to]);

  useEffect(() => { loadActivities(); }, [loadActivities]);

  const onDatesSet = useCallback((arg: DatesSetArg) => {
    const from = toYmdLocal(arg.start);
    const last = new Date(arg.end); last.setDate(last.getDate() - 1);
    setVisibleRange({ from, to: toYmdLocal(last) });
  }, []);

  const handleEventClick = useCallback((clickInfo: EventClickArg) => {
    const ev = clickInfo.event;
    const row = events.find((e) => e.id === ev.id);
    const startStr = ev.start ? toYmdLocal(ev.start) : '';
    let endStr = startStr;
    if (ev.allDay && ev.end) {
      const inc = new Date(ev.end); inc.setDate(inc.getDate() - 1);
      endStr = toYmdLocal(inc);
    }
    setDetailEvent({
      title: ev.title,
      description: row?.extendedProps?.description ?? '',
      startsOn: startStr,
      endsOn: endStr,
      classroomName: row?.extendedProps?.classroomName ?? '',
    });
  }, [events]);

  const fmtDate = (ymd: string) =>
    new Date(`${ymd}T12:00:00`).toLocaleDateString('tr-TR', { day: 'numeric', month: 'long', year: 'numeric' });

  const selectedClassroom = classrooms.find((c) => c.id === selectedClassroomId);

  return (
    <>
      {/* Filtre / Bilgi bandı */}
      <div className="border-b border-zinc-200/90 px-5 py-4 dark:border-zinc-800/90">
        <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
          <div>
            {classrooms.length > 1 ? (
              <div className="flex items-center gap-2">
                <BookOpen size={15} className="shrink-0 text-primary dark:text-teal-400" />
                <select
                  value={selectedClassroomId}
                  onChange={(e) => setSelectedClassroomId(e.target.value)}
                  className="h-9 rounded-lg border border-zinc-200 bg-white px-3 text-sm font-medium text-zinc-800 focus:outline-none focus:ring-2 focus:ring-primary/30 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-200"
                >
                  <option value="">Sınıf seçin…</option>
                  {classrooms.map((c) => (
                    <option key={c.id} value={c.id}>
                      {c.branch?.name ? `${c.branch.name} / ` : ''}{c.name}
                    </option>
                  ))}
                </select>
              </div>
            ) : selectedClassroom ? (
              <div className="flex items-center gap-2">
                <BookOpen size={15} className="text-primary dark:text-teal-400" />
                <span className="text-sm font-semibold text-zinc-800 dark:text-zinc-200">
                  {selectedClassroom.branch?.name ? `${selectedClassroom.branch.name} / ` : ''}{selectedClassroom.name}
                </span>
              </div>
            ) : (
              <p className="text-sm text-zinc-400 dark:text-zinc-500">Henüz bir sınıfa atanmadınız.</p>
            )}
          </div>
          {loading && (
            <span className="text-xs text-zinc-400 dark:text-zinc-500">Yükleniyor…</span>
          )}
        </div>
        {!selectedClassroomId && classrooms.length > 1 && (
          <p className="mt-2 text-xs text-zinc-400 dark:text-zinc-500">Etkinlikleri görmek için sınıf seçin.</p>
        )}
      </div>

      {/* Takvim */}
      <div className="custom-calendar">
        <FullCalendar
          plugins={[dayGridPlugin, timeGridPlugin]}
          initialView="dayGridMonth"
          locale={trLocale}
          headerToolbar={{
            left: 'prev,next',
            center: 'title',
            right: 'dayGridMonth,timeGridWeek',
          }}
          buttonText={{ today: 'bugün', month: 'ay', week: 'hafta' }}
          titleFormat={{ year: 'numeric', month: 'long' }}
          events={events}
          selectable={false}
          eventClick={handleEventClick}
          eventContent={renderEventContent}
          datesSet={onDatesSet}
          height="auto"
        />
      </div>

      {/* Etkinlik detay dialog (salt okunur) */}
      <Dialog open={!!detailEvent} onOpenChange={(o) => !o && setDetailEvent(null)}>
        <DialogContent className="max-w-md gap-0 p-6">
          <DialogHeader className="flex-row items-start justify-between gap-2 space-y-0">
            <DialogTitle className="text-lg leading-snug dark:text-white">{detailEvent?.title}</DialogTitle>
            <button
              type="button"
              onClick={() => setDetailEvent(null)}
              className="mt-0.5 flex h-7 w-7 shrink-0 items-center justify-center rounded-lg text-zinc-400 hover:bg-zinc-100 hover:text-zinc-600 dark:hover:bg-zinc-800 dark:hover:text-zinc-300"
            >
              <X size={15} />
            </button>
          </DialogHeader>

          {detailEvent && (
            <div className="mt-4 space-y-3">
              {detailEvent.classroomName && (
                <div className="flex items-center gap-2 rounded-lg bg-teal-50 px-3 py-2 dark:bg-teal-950/30">
                  <BookOpen size={13} className="text-teal-600 dark:text-teal-400" />
                  <span className="text-sm font-medium text-teal-800 dark:text-teal-300">{detailEvent.classroomName}</span>
                </div>
              )}
              <div className="flex items-center gap-2 text-sm text-zinc-600 dark:text-zinc-400">
                <CalendarDays size={13} className="shrink-0 text-zinc-400" />
                {detailEvent.startsOn === detailEvent.endsOn
                  ? fmtDate(detailEvent.startsOn)
                  : `${fmtDate(detailEvent.startsOn)} – ${fmtDate(detailEvent.endsOn)}`}
              </div>
              {detailEvent.description && (
                <p className="rounded-lg bg-zinc-50 px-3 py-2.5 text-sm text-zinc-700 dark:bg-zinc-800/60 dark:text-zinc-300">
                  {detailEvent.description}
                </p>
              )}
            </div>
          )}
        </DialogContent>
      </Dialog>
    </>
  );
}
