"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { Avatar } from "@/components/ui/Avatar";
import { Icon } from "@/components/ui/Icon";
import { confirmDialog, alertDialog } from "@/components/ui/Dialog";
import { respondMeetingAction, deleteMeetingAction } from "@/lib/meetings/actions";
import { MeetingDrawer, type UserOpt, type TeamOpt } from "./MeetingDrawer";
import type { CalEvent, CalEventKind } from "@/lib/calendar/queries";
import type { MeetingDTO } from "@/lib/meetings/queries";
import type { MeetingResponse } from "@prisma/client";

const MONTHS = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"];
const MONTHS_SHORT = ["Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"];
const WD = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"];
const KIND_ICON: Record<CalEventKind, string> = { absence: "absences", task: "kanban", meeting: "meetings" };
const KIND_LABEL: Record<CalEventKind, string> = { absence: "Abwesenheit", task: "Aufgabe", meeting: "Termin" };
const RESP: Record<MeetingResponse, { label: string; cls: string }> = {
  ACCEPTED: { label: "Zugesagt", cls: "ACTIVE" },
  DECLINED: { label: "Abgesagt", cls: "SUSPENDED" },
  TENTATIVE: { label: "Vielleicht", cls: "INVITED" },
  PENDING: { label: "Offen", cls: "" },
};

function pad(n: number) {
  return String(n).padStart(2, "0");
}
function isoDay(d: Date) {
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
}

export function CalendarView({
  events,
  meetings,
  users,
  teams,
  year,
  month,
  currentUserId,
  canCreate,
  canManageAll,
}: {
  events: CalEvent[];
  meetings: MeetingDTO[];
  users: UserOpt[];
  teams: TeamOpt[];
  year: number;
  month: number;
  currentUserId: string;
  canCreate: boolean;
  canManageAll: boolean;
}) {
  const router = useRouter();
  const todayISO = isoDay(new Date());
  const [view, setView] = useState<"month" | "week">("month");
  const [selected, setSelected] = useState<string | null>(null);
  const [navOpen, setNavOpen] = useState(false);
  const [editing, setEditing] = useState<MeetingDTO | "new" | null>(null);
  const [drawerDate, setDrawerDate] = useState<string | undefined>(undefined);

  const meetingsById = new Map(meetings.map((m) => [m.id, m]));
  const isMine = (m: MeetingDTO) => m.createdById === currentUserId || canManageAll;

  const eventsOn = (iso: string) =>
    events
      .filter((e) => iso >= e.startDate && iso <= e.endDate)
      .sort((a, b) => (a.time ?? "").localeCompare(b.time ?? "") || a.title.localeCompare(b.title));

  const first = new Date(year, month, 1);
  const offset = (first.getDay() + 6) % 7;
  const daysInMonth = new Date(year, month + 1, 0).getDate();
  const weeks = Math.ceil((offset + daysInMonth) / 7);
  const gridStart = new Date(year, month, 1 - offset);
  const cells = Array.from({ length: weeks * 7 }, (_, i) => {
    const d = new Date(gridStart);
    d.setDate(gridStart.getDate() + i);
    return d;
  });

  const initialWeek = () => {
    const t = new Date();
    if (t.getFullYear() === year && t.getMonth() === month) return Math.floor((offset + t.getDate() - 1) / 7);
    return 0;
  };
  const [weekIdx, setWeekIdx] = useState(initialWeek);
  const weekDays = cells.slice(weekIdx * 7, weekIdx * 7 + 7);

  const goMonth = (y: number, m: number) => router.push(`/calendar?m=${y}-${m + 1}`);
  const stepMonth = (delta: number) => {
    const d = new Date(year, month + delta, 1);
    goMonth(d.getFullYear(), d.getMonth());
  };
  const stepWeek = (delta: number) => {
    const next = weekIdx + delta;
    if (next < 0) return stepMonth(-1);
    if (next >= weeks) return stepMonth(1);
    setWeekIdx(next);
  };
  const goToday = () => {
    const d = new Date();
    goMonth(d.getFullYear(), d.getMonth());
  };
  const planFor = (iso: string) => {
    setDrawerDate(iso);
    setEditing("new");
  };

  const respond = async (id: string, r: MeetingResponse) => {
    await respondMeetingAction(id, r);
    router.refresh();
  };
  const removeMeeting = async (m: MeetingDTO) => {
    if (!(await confirmDialog({ title: "Termin absagen?", message: `„${m.title}" wird für alle abgesagt.`, danger: true }))) return;
    const res = await deleteMeetingAction(m.id);
    if (res.error) await alertDialog({ title: "Fehler", message: res.error, danger: true });
    else router.refresh();
  };

  const selectedEvents = selected ? eventsOn(selected) : [];

  return (
    <div className="flex flex-col gap-4">
      <div className="flex flex-wrap items-center justify-between gap-3" data-reveal>
        <div className="flex items-center gap-1">
          <button className="icon-btn" onClick={() => (view === "month" ? stepMonth(-1) : stepWeek(-1))} aria-label="Zurück">
            <Icon name="chevron" size={16} style={{ transform: "rotate(180deg)" }} />
          </button>
          <div className="relative">
            <button className="cal-title" onClick={() => setNavOpen((o) => !o)}>
              {MONTHS[month]} {year}
              <Icon name="chevron" size={13} style={{ transform: "rotate(90deg)", opacity: 0.6 }} />
            </button>
            {navOpen ? (
              <>
                <div className="pop-backdrop" onClick={() => setNavOpen(false)} />
                <div className="card-sm pop-solid cal-navpop">
                  <div className="cal-navpop-year">
                    <button className="icon-btn" style={{ width: 28, height: 28 }} onClick={() => goMonth(year - 1, month)} aria-label="Jahr zurück"><Icon name="chevron" size={14} style={{ transform: "rotate(180deg)" }} /></button>
                    <span className="font-bold">{year}</span>
                    <button className="icon-btn" style={{ width: 28, height: 28 }} onClick={() => goMonth(year + 1, month)} aria-label="Jahr vor"><Icon name="chevron" size={14} /></button>
                  </div>
                  <div className="cal-navpop-months">
                    {MONTHS_SHORT.map((mo, i) => (
                      <button key={mo} className="cal-navpop-month" data-active={i === month} onClick={() => { goMonth(year, i); setNavOpen(false); }}>{mo}</button>
                    ))}
                  </div>
                </div>
              </>
            ) : null}
          </div>
          <button className="icon-btn" onClick={() => (view === "month" ? stepMonth(1) : stepWeek(1))} aria-label="Weiter">
            <Icon name="chevron" size={16} />
          </button>
        </div>
        <div className="flex items-center gap-2">
          <div className="seg">
            <button className="seg-btn" data-active={view === "month"} onClick={() => setView("month")}>Monat</button>
            <button className="seg-btn" data-active={view === "week"} onClick={() => setView("week")}>Woche</button>
          </div>
          <button className="btn btn-ghost btn-sm" onClick={goToday}>Heute</button>
          {canCreate ? (
            <button className="btn btn-primary btn-sm" onClick={() => { setDrawerDate(undefined); setEditing("new"); }}>
              <Icon name="plus" size={15} /> Termin
            </button>
          ) : null}
        </div>
      </div>

      <div className="flex flex-wrap items-center gap-3 text-xs" data-reveal>
        {(["absence", "task", "meeting"] as CalEventKind[]).map((k) => (
          <span key={k} className="inline-flex items-center gap-1.5 text-muted">
            <span className="cal-legend-dot" data-kind={k} /> {KIND_LABEL[k]}
          </span>
        ))}
      </div>

      <div className="card" data-reveal style={{ padding: 14 }}>
        <div className="cal-weekdays">{WD.map((w) => <span key={w} className="cal-wd">{w}</span>)}</div>
        <div className="cal-grid">
          {(view === "month" ? cells : weekDays).map((d, i) => {
            const iso = isoDay(d);
            const other = d.getMonth() !== month;
            const dayEvents = eventsOn(iso);
            return (
              <button
                key={i}
                className="cal-cell"
                data-other={other}
                data-today={iso === todayISO}
                data-selected={selected === iso}
                data-week={view === "week"}
                onClick={() => setSelected(iso === selected ? null : iso)}
              >
                <span className="cal-daynum">{view === "week" ? `${WD[i]} ${d.getDate()}` : d.getDate()}</span>
                <span className="cal-events">
                  {dayEvents.slice(0, view === "week" ? 10 : 3).map((e) => (
                    <span key={e.id} className="cal-chip" style={{ background: `${e.color}26`, color: e.color, borderColor: `${e.color}55` }}>
                      <span className="cal-chip-dot" style={{ background: e.color }} />
                      <span className="truncate">{e.time ? `${e.time} ` : ""}{e.title}</span>
                    </span>
                  ))}
                  {view === "month" && dayEvents.length > 3 ? <span className="cal-more">+{dayEvents.length - 3}</span> : null}
                </span>
              </button>
            );
          })}
        </div>
      </div>

      {selected ? (
        <div className="card cal-detail" data-reveal>
          <div className="mb-4 flex items-center justify-between gap-3">
            <div className="flex items-center gap-3">
              <span className="cal-detail-date">
                <span className="cal-detail-day">{new Date(`${selected}T12:00`).getDate()}</span>
                <span className="cal-detail-wd">{new Date(`${selected}T12:00`).toLocaleDateString("de-DE", { weekday: "short" })}</span>
              </span>
              <div>
                <h3 className="leading-tight">{new Date(`${selected}T12:00`).toLocaleDateString("de-DE", { day: "2-digit", month: "long", year: "numeric" })}</h3>
                <div className="text-muted text-xs">{selectedEvents.length} Einträge</div>
              </div>
            </div>
            {canCreate ? (
              <button className="btn btn-primary btn-sm" onClick={() => planFor(selected)}><Icon name="plus" size={14} /> Termin planen</button>
            ) : null}
          </div>

          {selectedEvents.length === 0 ? (
            <p className="text-muted text-sm">Keine Einträge an diesem Tag.</p>
          ) : (
            <div className="flex flex-col gap-2">
              {selectedEvents.map((ev) => {
                const meeting = ev.kind === "meeting" ? meetingsById.get(ev.id.replace("mtg-", "")) : undefined;
                if (meeting) {
                  const mine = isMine(meeting);
                  return (
                    <div key={ev.id} className="cal-meeting" style={{ borderLeft: `3px solid ${ev.color}` }}>
                      <div className="flex items-start justify-between gap-2">
                        <div className="min-w-0">
                          <div className="font-bold">{meeting.title}</div>
                          <div className="text-muted text-xs">
                            {new Date(meeting.startAt).toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" })}–{new Date(meeting.endAt).toLocaleTimeString("de-DE", { hour: "2-digit", minute: "2-digit" })}
                            {meeting.location ? ` · ${meeting.location}` : ""} · {meeting.creatorName}
                          </div>
                        </div>
                        {mine ? <span className="badge meeting-own">Dein Termin</span> : null}
                      </div>
                      {meeting.description ? <p className="text-muted mt-1 text-sm">{meeting.description}</p> : null}
                      <div className="mt-2 flex items-center justify-between gap-2">
                        <div className="assignee-stack">
                          {meeting.participants.slice(0, 6).map((p) => <Avatar key={p.id} name={p.name} src={p.avatarUrl} size={24} status={null} />)}
                          {meeting.participants.length > 6 ? <span className="badge" style={{ marginLeft: -8 }}>+{meeting.participants.length - 6}</span> : null}
                        </div>
                        {mine ? (
                          <div className="flex items-center gap-1">
                            <button className="btn btn-ghost btn-sm" onClick={() => { setDrawerDate(undefined); setEditing(meeting); }}><Icon name="edit" size={13} /> Verlegen</button>
                            <button className="icon-btn" style={{ width: 30, height: 30 }} onClick={() => removeMeeting(meeting)} aria-label="Absagen"><Icon name="trash" size={14} /></button>
                          </div>
                        ) : meeting.myResponse ? (
                          <div className="flex items-center gap-1">
                            <button className="pill btn-sm" data-active={meeting.myResponse === "ACCEPTED"} onClick={() => respond(meeting.id, "ACCEPTED")}>Zusagen</button>
                            <button className="pill btn-sm" data-active={meeting.myResponse === "TENTATIVE"} onClick={() => respond(meeting.id, "TENTATIVE")}>Vielleicht</button>
                            <button className="pill btn-sm" data-active={meeting.myResponse === "DECLINED"} onClick={() => respond(meeting.id, "DECLINED")}>Absagen</button>
                          </div>
                        ) : null}
                      </div>
                    </div>
                  );
                }
                return (
                  <a key={ev.id} href={ev.href ?? "#"} className="cal-event-row" style={{ borderLeft: `3px solid ${ev.color}` }}>
                    <span className="cal-event-icon" style={{ color: ev.color, background: `${ev.color}18` }}><Icon name={KIND_ICON[ev.kind]} size={16} /></span>
                    <div className="min-w-0 flex-1">
                      <div className="truncate font-bold">{ev.title}</div>
                      <div className="text-muted text-xs">{KIND_LABEL[ev.kind]}{ev.startDate !== ev.endDate ? ` · ${ev.startDate.slice(8)}.–${ev.endDate.slice(8)}.` : ""}</div>
                    </div>
                    <Icon name="chevron" size={15} style={{ opacity: 0.5 }} />
                  </a>
                );
              })}
            </div>
          )}
        </div>
      ) : null}

      {editing ? (
        <MeetingDrawer
          meeting={editing === "new" ? null : editing}
          users={users}
          teams={teams}
          defaultDate={drawerDate}
          onClose={() => setEditing(null)}
        />
      ) : null}
    </div>
  );
}
