"use client";
import { useState, useEffect, useCallback } from "react";
import {
  Plus,
  Check,
  X,
  Clock,
  ShieldAlert,
  AlertTriangle,
  CheckCircle2,
  Lock,
  Loader2,
  CalendarDays,
  ArrowUpCircle,
  Info,
} from "lucide-react";
import { format } from "date-fns";
import Modal from "./ui/Modal";
import Badge from "./ui/Badge";
import Avatar from "./ui/Avatar";
import { cn } from "@/lib/utils";

interface Employee {
  id: number;
  firstName: string;
  lastName: string;
  rank: string | null;
  role: string;
  orgNodeId: number | null;
  avatarColor: string | null;
  isActive: boolean | null;
}

interface DayImpact {
  date: string;
  orgNodeName: string;
  shiftType: string;
  current: number;
  projected: number;
  required: number;
  requiredSupervisors: number;
  projectedSupervisors: number;
  breaches: boolean;
  supervisorBreach: boolean;
  allowSupervisorOverride: boolean;
  allowAdminOverride: boolean;
}

interface Impact {
  ok: boolean;
  blocked: boolean;
  supervisorCanApprove: boolean;
  adminCanOverride: boolean;
  daysEvaluated: number;
  breachDays: DayImpact[];
  allDays: DayImpact[];
  summary: string;
}

interface Request {
  id: number;
  employeeId: number;
  startDate: string;
  endDate: string;
  type: string | null;
  reason: string | null;
  status: string;
  reviewedBy: number | null;
  decisionNote: string | null;
  staffingBlocked: boolean;
  overrideReason: string | null;
  createdAt: string;
}

interface Props {
  employees: Employee[];
  currentUser: Employee | null;
  onChanged: () => void;
}

const LEAVE_TYPES = ["vacation", "sick", "personal", "comp time", "bereavement", "training", "military"];

const STATUS_STYLE: Record<string, { color: string; label: string }> = {
  pending: { color: "#F59E0B", label: "Pending" },
  approved: { color: "#10B981", label: "Approved" },
  denied: { color: "#EF4444", label: "Denied" },
};

export default function TimeOffCenter({ employees, currentUser, onChanged }: Props) {
  const [requests, setRequests] = useState<Request[]>([]);
  const [loading, setLoading] = useState(true);
  const [tab, setTab] = useState<"queue" | "mine">("queue");
  const [showRequest, setShowRequest] = useState(false);
  const [reviewing, setReviewing] = useState<Request | null>(null);
  const [reviewImpact, setReviewImpact] = useState<Impact | null>(null);
  const [reviewLoading, setReviewLoading] = useState(false);
  const [overrideReason, setOverrideReason] = useState("");
  const [decisionNote, setDecisionNote] = useState("");
  const [blockMessage, setBlockMessage] = useState<string | null>(null);
  const [busy, setBusy] = useState(false);
  const [toast, setToast] = useState<{ kind: "ok" | "err"; msg: string } | null>(null);

  const role = currentUser?.role ?? "officer";
  const canReview = role === "supervisor" || role === "admin";
  const isAdmin = role === "admin";

  const [form, setForm] = useState({
    employeeId: currentUser?.id ?? 0,
    startDate: format(new Date(), "yyyy-MM-dd"),
    endDate: format(new Date(), "yyyy-MM-dd"),
    type: "vacation",
    reason: "",
  });
  const [formImpact, setFormImpact] = useState<Impact | null>(null);
  const [checkingImpact, setCheckingImpact] = useState(false);

  const flash = (kind: "ok" | "err", msg: string) => {
    setToast({ kind, msg });
    setTimeout(() => setToast(null), 6000);
  };

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const res = await fetch("/api/time-off");
      const data = await res.json();
      setRequests(Array.isArray(data) ? data : []);
    } finally {
      setLoading(false);
    }
  }, []);

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

  useEffect(() => {
    if (currentUser) setForm((f) => ({ ...f, employeeId: currentUser.id }));
  }, [currentUser]);

  // Live staffing preview while composing
  useEffect(() => {
    if (!showRequest || !form.employeeId) return;
    const t = setTimeout(async () => {
      setCheckingImpact(true);
      try {
        const res = await fetch("/api/time-off/impact", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(form),
        });
        setFormImpact(await res.json());
      } finally {
        setCheckingImpact(false);
      }
    }, 400);
    return () => clearTimeout(t);
  }, [showRequest, form.employeeId, form.startDate, form.endDate]);

  const submitRequest = async () => {
    setBusy(true);
    try {
      const res = await fetch("/api/time-off", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(form),
      });
      const data = await res.json();
      if (res.ok) {
        setShowRequest(false);
        setFormImpact(null);
        await load();
        onChanged();
        flash(
          "ok",
          data.impact?.blocked
            ? "Request submitted — flagged as a minimum-staffing conflict for review."
            : "Request submitted for supervisor approval."
        );
      } else {
        flash("err", data.error ?? "Could not submit request.");
      }
    } finally {
      setBusy(false);
    }
  };

  const openReview = async (r: Request) => {
    setReviewing(r);
    setReviewImpact(null);
    setBlockMessage(null);
    setOverrideReason("");
    setDecisionNote("");
    setReviewLoading(true);
    try {
      const res = await fetch("/api/time-off/impact", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          employeeId: r.employeeId,
          startDate: r.startDate,
          endDate: r.endDate,
          excludeRequestId: r.id,
        }),
      });
      setReviewImpact(await res.json());
    } finally {
      setReviewLoading(false);
    }
  };

  const decide = async (status: "approved" | "denied") => {
    if (!reviewing) return;
    setBusy(true);
    setBlockMessage(null);
    try {
      const res = await fetch("/api/time-off", {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          id: reviewing.id,
          status,
          actorId: currentUser?.id,
          overrideReason: overrideReason.trim() || undefined,
          decisionNote: decisionNote.trim() || undefined,
        }),
      });
      const data = await res.json();

      if (res.status === 409) {
        setBlockMessage(data.message);
        if (data.impact) setReviewImpact(data.impact);
        return;
      }
      if (!res.ok) {
        setBlockMessage(data.error ?? "Could not record decision.");
        return;
      }

      setReviewing(null);
      await load();
      onChanged();
      flash(
        "ok",
        status === "approved"
          ? data.overridden
            ? "Approved with a documented minimum-staffing override."
            : "Request approved."
          : "Request denied."
      );
    } finally {
      setBusy(false);
    }
  };

  const empById = (id: number) => employees.find((e) => e.id === id);
  const pending = requests.filter((r) => r.status === "pending");
  const mine = requests.filter((r) => r.employeeId === currentUser?.id);
  const visible = tab === "queue" ? (canReview ? requests : pending) : mine;

  // -------------------------------------------------------------- impact panel
  const ImpactPanel = ({ impact, compact }: { impact: Impact; compact?: boolean }) => (
    <div
      className={cn(
        "rounded-xl border p-3",
        impact.blocked ? "border-red-200 bg-red-50" : "border-green-200 bg-green-50"
      )}
    >
      <div className="flex items-start gap-2 mb-2">
        {impact.blocked ? (
          <ShieldAlert size={16} className="text-red-500 mt-0.5 flex-shrink-0" />
        ) : (
          <CheckCircle2 size={16} className="text-green-600 mt-0.5 flex-shrink-0" />
        )}
        <div>
          <p className={cn("text-sm font-semibold", impact.blocked ? "text-red-800" : "text-green-800")}>
            {impact.blocked ? "Minimum staffing conflict" : "Minimum staffing satisfied"}
          </p>
          <p className={cn("text-xs", impact.blocked ? "text-red-700" : "text-green-700")}>{impact.summary}</p>
        </div>
      </div>

      {impact.allDays.length > 0 && !compact && (
        <div className="mt-2 max-h-44 overflow-y-auto rounded-lg bg-white/70 divide-y divide-slate-100">
          {impact.allDays.map((d) => (
            <div key={`${d.date}-${d.shiftType}`} className="flex items-center gap-2 px-2.5 py-1.5 text-xs">
              <span className="font-medium text-slate-700 w-20">
                {format(new Date(d.date + "T00:00:00"), "EEE MMM d")}
              </span>
              <span className="text-slate-500 flex-1 truncate">
                {d.orgNodeName} · <span className="capitalize">{d.shiftType}</span>
              </span>
              <span className={cn("font-bold tabular-nums", d.breaches ? "text-red-600" : "text-slate-600")}>
                {d.current} → {d.projected}
              </span>
              <span className="text-slate-400">/ {d.required} req</span>
              {d.breaches && <Badge color="#EF4444">short {d.required - d.projected}</Badge>}
              {d.supervisorBreach && <Badge color="#F59E0B">no supervisor</Badge>}
            </div>
          ))}
        </div>
      )}

      {impact.blocked && (
        <div className="mt-2 flex flex-wrap gap-2">
          <span
            className={cn(
              "text-[11px] px-2 py-0.5 rounded-full font-medium",
              impact.supervisorCanApprove ? "bg-amber-100 text-amber-700" : "bg-red-100 text-red-700"
            )}
          >
            {impact.supervisorCanApprove ? "Supervisor override permitted" : "Supervisor cannot approve"}
          </span>
          <span
            className={cn(
              "text-[11px] px-2 py-0.5 rounded-full font-medium",
              impact.adminCanOverride ? "bg-blue-100 text-blue-700" : "bg-slate-200 text-slate-600"
            )}
          >
            {impact.adminCanOverride ? "Admin may override with justification" : "Absolute floor — no override"}
          </span>
        </div>
      )}
    </div>
  );

  return (
    <div>
      {toast && (
        <div
          className={cn(
            "mb-4 flex items-start gap-2 rounded-xl px-4 py-3 text-sm border",
            toast.kind === "ok" ? "bg-green-50 border-green-200 text-green-800" : "bg-red-50 border-red-200 text-red-800"
          )}
        >
          {toast.kind === "ok" ? <CheckCircle2 size={16} className="mt-0.5" /> : <AlertTriangle size={16} className="mt-0.5" />}
          {toast.msg}
        </div>
      )}

      <div className="flex flex-wrap items-center justify-between gap-3 mb-5">
        <div className="flex bg-slate-100 rounded-xl p-1">
          <button
            onClick={() => setTab("queue")}
            className={cn(
              "px-4 py-1.5 rounded-lg text-sm font-medium transition-colors",
              tab === "queue" ? "bg-white text-blue-600 shadow-sm" : "text-slate-500"
            )}
          >
            {canReview ? "Approval Queue" : "All Requests"}
            {pending.length > 0 && (
              <span className="ml-1.5 text-xs bg-amber-500 text-white rounded-full px-1.5">{pending.length}</span>
            )}
          </button>
          <button
            onClick={() => setTab("mine")}
            className={cn(
              "px-4 py-1.5 rounded-lg text-sm font-medium transition-colors",
              tab === "mine" ? "bg-white text-blue-600 shadow-sm" : "text-slate-500"
            )}
          >
            My Requests
          </button>
        </div>

        <button
          onClick={() => setShowRequest(true)}
          disabled={!currentUser}
          className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-xl text-sm font-medium hover:bg-blue-700 disabled:opacity-40"
        >
          <Plus size={16} />
          Request Time Off
        </button>
      </div>

      {loading ? (
        <div className="flex justify-center py-14">
          <Loader2 className="animate-spin text-blue-500" size={28} />
        </div>
      ) : visible.length === 0 ? (
        <div className="text-center py-14 border-2 border-dashed border-slate-200 rounded-2xl text-slate-400">
          <CalendarDays size={36} className="mx-auto mb-3 opacity-30" />
          <p className="font-medium">No requests here</p>
        </div>
      ) : (
        <div className="space-y-2.5">
          {visible.map((r) => {
            const emp = empById(r.employeeId);
            const st = STATUS_STYLE[r.status];
            const reviewer = r.reviewedBy ? empById(r.reviewedBy) : null;
            return (
              <div key={r.id} className="rounded-xl border border-slate-200 bg-white p-4 flex flex-wrap items-center gap-3">
                {emp && (
                  <Avatar firstName={emp.firstName} lastName={emp.lastName} color={emp.avatarColor ?? "#3B82F6"} size="md" />
                )}
                <div className="flex-1 min-w-[200px]">
                  <div className="flex items-center gap-2 flex-wrap">
                    <span className="font-semibold text-slate-800">
                      {emp ? `${emp.firstName} ${emp.lastName}` : "Unknown"}
                    </span>
                    <Badge color={st.color}>{st.label}</Badge>
                    <Badge color="#64748B">{r.type}</Badge>
                    {r.staffingBlocked && r.status === "pending" && (
                      <span className="inline-flex items-center gap-1 text-xs font-medium text-red-600">
                        <ShieldAlert size={12} /> staffing conflict
                      </span>
                    )}
                    {r.overrideReason && (
                      <span className="inline-flex items-center gap-1 text-xs font-medium text-amber-600">
                        <ArrowUpCircle size={12} /> overridden
                      </span>
                    )}
                  </div>
                  <p className="text-sm text-slate-500 mt-0.5">
                    {format(new Date(r.startDate + "T00:00:00"), "MMM d, yyyy")} –{" "}
                    {format(new Date(r.endDate + "T00:00:00"), "MMM d, yyyy")}
                    {emp?.rank ? ` · ${emp.rank}` : ""}
                  </p>
                  {r.reason && <p className="text-xs text-slate-400 italic mt-0.5">&ldquo;{r.reason}&rdquo;</p>}
                  {r.overrideReason && (
                    <p className="text-xs text-amber-700 mt-1 bg-amber-50 rounded px-2 py-1">
                      Override justification: {r.overrideReason}
                    </p>
                  )}
                  {reviewer && (
                    <p className="text-[11px] text-slate-400 mt-1">
                      Reviewed by {reviewer.firstName} {reviewer.lastName}
                      {r.decisionNote ? ` — ${r.decisionNote}` : ""}
                    </p>
                  )}
                </div>

                {r.status === "pending" && canReview && (
                  <button
                    onClick={() => openReview(r)}
                    className="px-4 py-2 rounded-xl bg-blue-600 text-white text-sm font-medium hover:bg-blue-700"
                  >
                    Review
                  </button>
                )}
              </div>
            );
          })}
        </div>
      )}

      {/* ----------------------------------------------------- request modal */}
      <Modal isOpen={showRequest} onClose={() => setShowRequest(false)} title="Request Time Off" size="lg">
        <div className="space-y-4">
          {canReview && (
            <div>
              <label className="block text-sm font-medium text-slate-700 mb-1">Officer</label>
              <select
                value={form.employeeId}
                onChange={(e) => setForm({ ...form, employeeId: parseInt(e.target.value) })}
                className="w-full border border-slate-300 rounded-xl px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
              >
                {employees
                  .filter((e) => e.isActive !== false)
                  .map((e) => (
                    <option key={e.id} value={e.id}>
                      {e.lastName}, {e.firstName} {e.rank ? `(${e.rank})` : ""}
                    </option>
                  ))}
              </select>
            </div>
          )}

          <div className="grid grid-cols-2 gap-4">
            <div>
              <label className="block text-sm font-medium text-slate-700 mb-1">Start date</label>
              <input
                type="date"
                value={form.startDate}
                onChange={(e) =>
                  setForm({ ...form, startDate: e.target.value, endDate: e.target.value > form.endDate ? e.target.value : form.endDate })
                }
                className="w-full border border-slate-300 rounded-xl px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
              />
            </div>
            <div>
              <label className="block text-sm font-medium text-slate-700 mb-1">End date</label>
              <input
                type="date"
                min={form.startDate}
                value={form.endDate}
                onChange={(e) => setForm({ ...form, endDate: e.target.value })}
                className="w-full border border-slate-300 rounded-xl px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
              />
            </div>
          </div>

          <div>
            <label className="block text-sm font-medium text-slate-700 mb-1">Leave type</label>
            <div className="flex flex-wrap gap-2">
              {LEAVE_TYPES.map((t) => (
                <button
                  key={t}
                  onClick={() => setForm({ ...form, type: t })}
                  className={cn(
                    "px-3 py-1.5 rounded-xl text-xs font-medium capitalize transition-colors",
                    form.type === t ? "bg-blue-600 text-white" : "bg-slate-100 text-slate-600 hover:bg-slate-200"
                  )}
                >
                  {t}
                </button>
              ))}
            </div>
          </div>

          <div>
            <label className="block text-sm font-medium text-slate-700 mb-1">Reason (optional)</label>
            <textarea
              rows={2}
              value={form.reason}
              onChange={(e) => setForm({ ...form, reason: e.target.value })}
              className="w-full border border-slate-300 rounded-xl px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
            />
          </div>

          {checkingImpact && (
            <div className="flex items-center gap-2 text-sm text-slate-500">
              <Loader2 size={14} className="animate-spin" /> Checking minimum staffing…
            </div>
          )}
          {formImpact && !checkingImpact && <ImpactPanel impact={formImpact} />}

          {formImpact?.blocked && (
            <div className="flex items-start gap-2 text-xs text-slate-500 bg-slate-50 rounded-xl p-3">
              <Info size={14} className="mt-0.5 flex-shrink-0" />
              You can still submit — your supervisor will see this conflict. If the rule forbids supervisor override
              it must be escalated to an administrator, or you can pick different dates.
            </div>
          )}

          <div className="flex gap-3">
            <button
              onClick={submitRequest}
              disabled={busy || !form.employeeId}
              className="flex-1 py-2.5 bg-blue-600 text-white rounded-xl font-medium hover:bg-blue-700 disabled:opacity-50"
            >
              {busy ? "Submitting…" : "Submit Request"}
            </button>
            <button onClick={() => setShowRequest(false)} className="px-4 py-2.5 border border-slate-200 rounded-xl text-slate-600 hover:bg-slate-50">
              Cancel
            </button>
          </div>
        </div>
      </Modal>

      {/* ----------------------------------------------------- review modal */}
      <Modal isOpen={!!reviewing} onClose={() => setReviewing(null)} title="Review Leave Request" size="xl">
        {reviewing && (
          <div className="space-y-4">
            {(() => {
              const emp = empById(reviewing.employeeId);
              return (
                <div className="flex items-center gap-3 pb-3 border-b border-slate-100">
                  {emp && (
                    <Avatar firstName={emp.firstName} lastName={emp.lastName} color={emp.avatarColor ?? "#3B82F6"} size="lg" />
                  )}
                  <div>
                    <p className="font-bold text-slate-800">
                      {emp ? `${emp.firstName} ${emp.lastName}` : "Unknown"}
                    </p>
                    <p className="text-sm text-slate-500">
                      {emp?.rank} · {reviewing.type} ·{" "}
                      {format(new Date(reviewing.startDate + "T00:00:00"), "MMM d")} –{" "}
                      {format(new Date(reviewing.endDate + "T00:00:00"), "MMM d, yyyy")}
                    </p>
                    {reviewing.reason && <p className="text-sm text-slate-400 italic mt-0.5">&ldquo;{reviewing.reason}&rdquo;</p>}
                  </div>
                </div>
              );
            })()}

            {reviewLoading && (
              <div className="flex items-center gap-2 text-sm text-slate-500 py-4">
                <Loader2 size={16} className="animate-spin" /> Evaluating minimum staffing…
              </div>
            )}

            {reviewImpact && !reviewLoading && <ImpactPanel impact={reviewImpact} />}

            {blockMessage && (
              <div className="rounded-xl border-2 border-red-300 bg-red-50 p-4">
                <div className="flex items-start gap-2">
                  <Lock size={18} className="text-red-500 mt-0.5 flex-shrink-0" />
                  <div>
                    <p className="font-semibold text-red-800 text-sm mb-1">Approval blocked</p>
                    <p className="text-sm text-red-700">{blockMessage}</p>
                  </div>
                </div>
              </div>
            )}

            {/* Admin override */}
            {reviewImpact?.blocked && isAdmin && reviewImpact.adminCanOverride && (
              <div className="rounded-xl border border-amber-300 bg-amber-50 p-3">
                <label className="block text-sm font-semibold text-amber-800 mb-1">
                  Administrator override justification (required)
                </label>
                <textarea
                  rows={2}
                  value={overrideReason}
                  onChange={(e) => setOverrideReason(e.target.value)}
                  placeholder="e.g., Backfill arranged via mutual aid; Chief authorised on 5/12."
                  className="w-full border border-amber-300 rounded-xl px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-amber-500"
                />
                <p className="text-xs text-amber-700 mt-1">
                  This justification is written to the permanent audit trail.
                </p>
              </div>
            )}

            {/* Supervisor lockout notice */}
            {reviewImpact?.blocked && !isAdmin && !reviewImpact.supervisorCanApprove && (
              <div className="rounded-xl border border-slate-300 bg-slate-50 p-3 flex items-start gap-2">
                <ShieldAlert size={16} className="text-slate-500 mt-0.5 flex-shrink-0" />
                <div className="text-sm text-slate-600">
                  <strong>Supervisors cannot approve this request.</strong> Minimum staffing takes precedence.
                  {reviewImpact.adminCanOverride
                    ? " An administrator may override it with written justification."
                    : " This is an absolute floor that nobody may override."}{" "}
                  You may still deny it or ask the officer to choose different dates.
                </div>
              </div>
            )}

            <div>
              <label className="block text-sm font-medium text-slate-700 mb-1">Decision note (optional)</label>
              <input
                value={decisionNote}
                onChange={(e) => setDecisionNote(e.target.value)}
                className="w-full border border-slate-300 rounded-xl px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
              />
            </div>

            {(() => {
              const blocked = reviewImpact?.blocked ?? false;
              const supervisorLocked = blocked && !isAdmin && !reviewImpact?.supervisorCanApprove;
              const adminNeedsReason = blocked && isAdmin && reviewImpact?.adminCanOverride && !overrideReason.trim();
              const hardFloor = blocked && !reviewImpact?.adminCanOverride && !reviewImpact?.supervisorCanApprove;
              const approveDisabled = busy || reviewLoading || supervisorLocked || adminNeedsReason || hardFloor;

              return (
                <div className="flex flex-wrap gap-3">
                  <button
                    onClick={() => decide("approved")}
                    disabled={approveDisabled}
                    title={
                      supervisorLocked
                        ? "Minimum staffing prevents supervisor approval"
                        : adminNeedsReason
                        ? "Enter an override justification first"
                        : undefined
                    }
                    className={cn(
                      "flex-1 min-w-[150px] flex items-center justify-center gap-2 py-2.5 rounded-xl font-medium transition-colors",
                      approveDisabled
                        ? "bg-slate-200 text-slate-400 cursor-not-allowed"
                        : blocked
                        ? "bg-amber-500 text-white hover:bg-amber-600"
                        : "bg-green-600 text-white hover:bg-green-700"
                    )}
                  >
                    {supervisorLocked || hardFloor ? <Lock size={16} /> : <Check size={16} />}
                    {hardFloor
                      ? "Approval not permitted"
                      : supervisorLocked
                      ? "Blocked by minimum staffing"
                      : blocked
                      ? "Approve with override"
                      : "Approve"}
                  </button>
                  <button
                    onClick={() => decide("denied")}
                    disabled={busy}
                    className="flex-1 min-w-[120px] flex items-center justify-center gap-2 py-2.5 rounded-xl bg-red-50 text-red-600 font-medium hover:bg-red-100 disabled:opacity-50"
                  >
                    <X size={16} /> Deny
                  </button>
                  <button onClick={() => setReviewing(null)} className="px-4 py-2.5 border border-slate-200 rounded-xl text-slate-600 hover:bg-slate-50">
                    Close
                  </button>
                </div>
              );
            })()}
          </div>
        )}
      </Modal>
    </div>
  );
}
