"use client";

import * as React from "react";
import Link from "next/link";
import { useParams } from "next/navigation";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useSession } from "next-auth/react";
import { ArrowLeft, Printer, Send, Check, RotateCcw, CheckCheck } from "lucide-react";
import { apiGet, apiSend } from "@/lib/api";
import type { AppraisalDTO, AppraisalCompetencyDTO } from "@/lib/types";
import { can } from "@/lib/rbac";
import {
  APPRAISAL_HALF_LABEL,
  APPRAISAL_STATUS_LABEL,
  APPRAISAL_STATUS_BADGE,
  APPRAISAL_BAND_LABEL,
  APPRAISAL_BANDS_HELP,
} from "@/lib/labels";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { Select } from "@/components/ui/select";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import { StatCard, Spinner } from "@/components/common";

const BANDS = ["OUTSTANDING", "EXCEEDS", "MEETS", "BELOW"];

export function AppraisalDetailView() {
  const params = useParams();
  const id = params.id as string;
  const { data: session } = useSession();
  const qc = useQueryClient();

  const q = useQuery({
    queryKey: ["appraisal", id],
    queryFn: () => apiGet<AppraisalDTO>(`/api/appraisals/${id}`),
  });

  const a = q.data;
  const isManager = can(session?.user?.role, "appraisals:manage");
  const isSubject = a?.user.id === session?.user?.id;
  const locked = a?.status === "ACKNOWLEDGED";
  const canEditManager = isManager && !locked;
  const canEditSelf = !!isSubject && !["FINALIZED", "ACKNOWLEDGED"].includes(a?.status ?? "");
  const showManagerReview = isManager || ["FINALIZED", "ACKNOWLEDGED"].includes(a?.status ?? "");

  // Editable form state, hydrated from the loaded appraisal.
  const [m, setM] = React.useState(blankManager());
  const [self, setSelf] = React.useState({ selfRating: "", selfComments: "" });
  const [comps, setComps] = React.useState<AppraisalCompetencyDTO[]>([]);
  const [error, setError] = React.useState("");

  React.useEffect(() => {
    if (!a) return;
    setM({
      overallBand: a.overallBand ?? "",
      strengths: a.strengths ?? "",
      improvements: a.improvements ?? "",
      goalsReview: a.goalsReview ?? "",
      goalsNext: a.goalsNext ?? "",
      remarks: a.remarks ?? "",
      managerComments: a.managerComments ?? "",
    });
    setSelf({ selfRating: a.selfRating ? String(a.selfRating) : "", selfComments: a.selfComments ?? "" });
    setComps(a.competencies);
  }, [a]);

  const onSaved = () => qc.invalidateQueries({ queryKey: ["appraisal", id] });

  const saveManager = useMutation({
    mutationFn: () =>
      apiSend(`/api/appraisals/${id}`, "PATCH", {
        overallBand: m.overallBand || null,
        strengths: m.strengths || null,
        improvements: m.improvements || null,
        goalsReview: m.goalsReview || null,
        goalsNext: m.goalsNext || null,
        remarks: m.remarks || null,
        managerComments: m.managerComments || null,
        competencies: comps.map((c) => ({ id: c.id, score: c.score, note: c.note })),
      }),
    onSuccess: onSaved,
    onError: (e) => setError(e instanceof Error ? e.message : "Failed to save"),
  });
  const saveSelf = useMutation({
    mutationFn: () =>
      apiSend(`/api/appraisals/${id}`, "PATCH", {
        selfComments: self.selfComments || null,
        selfRating: self.selfRating ? Number(self.selfRating) : null,
      }),
    onSuccess: onSaved,
    onError: (e) => setError(e instanceof Error ? e.message : "Failed to save"),
  });
  const act = useMutation({
    mutationFn: (action: string) => apiSend(`/api/appraisals/${id}`, "PATCH", { action }),
    onSuccess: onSaved,
    onError: (e) => setError(e instanceof Error ? e.message : "Action failed"),
  });

  if (q.isLoading || !a) return <Spinner />;

  function setComp(cid: string, patch: Partial<AppraisalCompetencyDTO>) {
    setComps((cs) => cs.map((c) => (c.id === cid ? { ...c, ...patch } : c)));
  }

  return (
    <div>
      {/* Header */}
      <div className="mb-5 flex flex-wrap items-start justify-between gap-3">
        <div>
          <Link href="/appraisals" className="no-print mb-1 inline-flex items-center gap-1 text-xs text-muted-foreground hover:underline">
            <ArrowLeft className="size-3.5" /> All appraisals
          </Link>
          <h1 className="text-xl font-bold tracking-tight">{a.user.name}</h1>
          <p className="text-sm text-muted-foreground">
            {a.user.position ?? "—"} · {APPRAISAL_HALF_LABEL[a.half]} {a.year}
          </p>
        </div>
        <div className="flex flex-wrap items-center gap-2">
          <Badge variant={APPRAISAL_STATUS_BADGE[a.status]}>{APPRAISAL_STATUS_LABEL[a.status]}</Badge>
          <Button variant="secondary" className="no-print" onClick={() => window.print()}>
            <Printer className="size-4" /> Print
          </Button>
        </div>
      </div>

      {error && <p className="no-print mb-3 text-sm text-destructive">{error}</p>}

      <div className="print-area space-y-5">
        {/* Auto performance snapshot */}
        <Card className="break-inside-avoid">
          <CardHeader>
            <CardTitle>Performance Snapshot · {APPRAISAL_HALF_LABEL[a.half]} {a.year}</CardTitle>
            <p className="text-xs text-muted-foreground">Pulled automatically from the system.</p>
          </CardHeader>
          <CardContent>
            <div className="grid grid-cols-2 gap-3 lg:grid-cols-4">
              <StatCard label="KPI Attainment" value={a.snapshot.kpiAttainment === null ? "—" : `${a.snapshot.kpiAttainment}%`} hint={`${a.snapshot.kpiCount} personal KPIs`} accent="primary" />
              <StatCard label="Tasks Completed" value={`${a.snapshot.tasksCompleted}/${a.snapshot.tasksTotal}`} accent="success" />
              <StatCard label="Posts Published" value={a.snapshot.postsPublished} />
              <StatCard label="Competency Avg" value={a.snapshot.competencyAvg === null ? "—" : `${a.snapshot.competencyAvg}/5`} accent="primary" />
            </div>
          </CardContent>
        </Card>

        {/* Competencies */}
        <Card className="break-inside-avoid">
          <CardHeader>
            <CardTitle>Competency Ratings</CardTitle>
            <p className="text-xs text-muted-foreground">Rated 1 (poor) – 5 (excellent) by the manager.</p>
          </CardHeader>
          <CardContent className="space-y-3">
            {comps.map((c) => (
              <div key={c.id} className="grid grid-cols-1 gap-2 border-b border-border pb-3 last:border-0 last:pb-0 sm:grid-cols-[1fr_auto]">
                <div>
                  <div className="text-sm font-medium">{c.name}</div>
                  {canEditManager ? (
                    <Input
                      className="mt-1"
                      placeholder="Note (optional)"
                      value={c.note ?? ""}
                      onChange={(e) => setComp(c.id, { note: e.target.value })}
                    />
                  ) : (
                    c.note && <div className="mt-0.5 text-xs text-muted-foreground">{c.note}</div>
                  )}
                </div>
                <div className="flex items-center gap-2">
                  {canEditManager ? (
                    <Select
                      className="w-20"
                      value={c.score === null ? "" : String(c.score)}
                      onChange={(e) => setComp(c.id, { score: e.target.value === "" ? null : Number(e.target.value) })}
                    >
                      <option value="">—</option>
                      {[1, 2, 3, 4, 5].map((n) => (
                        <option key={n} value={n}>{n}</option>
                      ))}
                    </Select>
                  ) : (
                    <Badge variant={c.score ? "primary" : "outline"}>{c.score ? `${c.score}/5` : "—"}</Badge>
                  )}
                </div>
              </div>
            ))}
            {canEditManager && (
              <div className="no-print flex justify-end">
                <Button onClick={() => saveManager.mutate()} disabled={saveManager.isPending}>
                  Save ratings &amp; review
                </Button>
              </div>
            )}
          </CardContent>
        </Card>

        {/* Self-assessment */}
        <Card className="break-inside-avoid">
          <CardHeader>
            <CardTitle>Staff Self-Assessment</CardTitle>
          </CardHeader>
          <CardContent className="space-y-3">
            <div className="grid gap-3 sm:grid-cols-[160px_1fr]">
              <div className="space-y-1.5">
                <Label>Self rating (1–5)</Label>
                {canEditSelf ? (
                  <Select value={self.selfRating} onChange={(e) => setSelf({ ...self, selfRating: e.target.value })}>
                    <option value="">—</option>
                    {[1, 2, 3, 4, 5].map((n) => (
                      <option key={n} value={n}>{n}</option>
                    ))}
                  </Select>
                ) : (
                  <div className="text-sm">{a.selfRating ? `${a.selfRating}/5` : "—"}</div>
                )}
              </div>
              <div className="space-y-1.5">
                <Label>Your comments</Label>
                {canEditSelf ? (
                  <Textarea value={self.selfComments} onChange={(e) => setSelf({ ...self, selfComments: e.target.value })} placeholder="Your reflections on the half-year…" />
                ) : (
                  <div className="whitespace-pre-wrap text-sm text-muted-foreground">{a.selfComments || "—"}</div>
                )}
              </div>
            </div>
            {canEditSelf && (
              <div className="no-print flex justify-end">
                <Button onClick={() => saveSelf.mutate()} disabled={saveSelf.isPending}>
                  Save self-assessment
                </Button>
              </div>
            )}
          </CardContent>
        </Card>

        {/* Manager review */}
        {showManagerReview && (
          <Card className="break-inside-avoid">
            <CardHeader>
              <CardTitle>Manager Review</CardTitle>
            </CardHeader>
            <CardContent className="space-y-3">
              <div className="space-y-1.5">
                <Label>Overall rating</Label>
                {canEditManager ? (
                  <Select value={m.overallBand} onChange={(e) => setM({ ...m, overallBand: e.target.value })}>
                    <option value="">— Select —</option>
                    {BANDS.map((b) => (
                      <option key={b} value={b}>{APPRAISAL_BAND_LABEL[b]}</option>
                    ))}
                  </Select>
                ) : (
                  <div className="text-sm font-medium">{a.overallBand ? APPRAISAL_BAND_LABEL[a.overallBand] : "—"}</div>
                )}
                {canEditManager && <p className="text-[11px] text-muted-foreground">{APPRAISAL_BANDS_HELP}</p>}
              </div>
              <ReviewField label="Strengths" value={m.strengths} ro={a.strengths} edit={canEditManager} onChange={(v) => setM({ ...m, strengths: v })} />
              <ReviewField label="Areas to improve" value={m.improvements} ro={a.improvements} edit={canEditManager} onChange={(v) => setM({ ...m, improvements: v })} />
              <ReviewField label="Goals — review of this period" value={m.goalsReview} ro={a.goalsReview} edit={canEditManager} onChange={(v) => setM({ ...m, goalsReview: v })} />
              <ReviewField label="Goals — next period" value={m.goalsNext} ro={a.goalsNext} edit={canEditManager} onChange={(v) => setM({ ...m, goalsNext: v })} />
              <ReviewField label="Manager comments" value={m.managerComments} ro={a.managerComments} edit={canEditManager} onChange={(v) => setM({ ...m, managerComments: v })} />
              <ReviewField label="Remarks / notes" value={m.remarks} ro={a.remarks} edit={canEditManager} onChange={(v) => setM({ ...m, remarks: v })} />
              {canEditManager && (
                <div className="no-print flex justify-end">
                  <Button onClick={() => saveManager.mutate()} disabled={saveManager.isPending}>
                    Save review
                  </Button>
                </div>
              )}
            </CardContent>
          </Card>
        )}

        {a.acknowledgedAt && (
          <p className="text-xs text-muted-foreground">
            ✓ Acknowledged by {a.user.name} on {new Date(a.acknowledgedAt).toLocaleDateString()}
          </p>
        )}
      </div>

      {/* Workflow actions */}
      <div className="no-print mt-5 flex flex-wrap gap-2 border-t border-border pt-4">
        {isManager && a.status === "DRAFT" && (
          <Button variant="secondary" onClick={() => act.mutate("request_self")} disabled={act.isPending}>
            <Send className="size-4" /> Send for self-assessment
          </Button>
        )}
        {isSubject && a.status === "SELF_REVIEW" && (
          <Button onClick={() => act.mutate("submit_self")} disabled={act.isPending}>
            <Send className="size-4" /> Submit self-assessment
          </Button>
        )}
        {isManager && ["DRAFT", "SELF_REVIEW", "MANAGER_REVIEW"].includes(a.status) && (
          <Button onClick={() => act.mutate("finalize")} disabled={act.isPending}>
            <Check className="size-4" /> Finalize appraisal
          </Button>
        )}
        {isSubject && a.status === "FINALIZED" && (
          <Button variant="success" onClick={() => act.mutate("acknowledge")} disabled={act.isPending}>
            <CheckCheck className="size-4" /> Acknowledge &amp; sign off
          </Button>
        )}
        {isManager && ["FINALIZED", "ACKNOWLEDGED"].includes(a.status) && (
          <Button variant="outline" onClick={() => act.mutate("reopen")} disabled={act.isPending}>
            <RotateCcw className="size-4" /> Reopen
          </Button>
        )}
      </div>
    </div>
  );
}

function ReviewField({
  label,
  value,
  ro,
  edit,
  onChange,
}: {
  label: string;
  value: string;
  ro: string | null;
  edit: boolean;
  onChange: (v: string) => void;
}) {
  return (
    <div className="space-y-1.5">
      <Label>{label}</Label>
      {edit ? (
        <Textarea value={value} onChange={(e) => onChange(e.target.value)} />
      ) : (
        <div className="whitespace-pre-wrap text-sm text-muted-foreground">{ro || "—"}</div>
      )}
    </div>
  );
}

function blankManager() {
  return {
    overallBand: "",
    strengths: "",
    improvements: "",
    goalsReview: "",
    goalsNext: "",
    remarks: "",
    managerComments: "",
  };
}
