"use client";

import * as React from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useSession } from "next-auth/react";
import { Link2, CheckCircle2, Trash2 } from "lucide-react";
import { apiGet, apiSend } from "@/lib/api";
import type { TaskDTO, KpiDTO, UserDTO, DepartmentDTO } from "@/lib/types";
import { isManagerTier } from "@/lib/rbac";
import { currentIsoWeek, recentIsoWeeks, formatIsoWeek } from "@/lib/week";
import { formatMetric } from "@/lib/utils";
import { STATUS_LABEL, STATUS_BADGE } from "@/lib/labels";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Select } from "@/components/ui/select";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import { Textarea } from "@/components/ui/textarea";
import { Dialog, DialogHeader, DialogBody, DialogFooter } from "@/components/ui/dialog";
import { PageHeader, Spinner, EmptyState } from "@/components/common";

export function WeeklyView() {
  const { data: session } = useSession();
  const position = session?.user?.position ?? null;
  const manager = isManagerTier(session?.user?.role);
  const qc = useQueryClient();

  const weeks = React.useMemo(() => recentIsoWeeks(8), []);
  const cur = React.useMemo(() => currentIsoWeek(), []);
  const [sel, setSel] = React.useState(`${cur.year}-${cur.week}`);
  const [year, week] = sel.split("-").map(Number);

  // Manager-tier can view a specific staff member OR a whole department.
  // These two are mutually exclusive display modes.
  const [userId, setUserId] = React.useState("");
  const [departmentId, setDepartmentId] = React.useState("");

  const usersQuery = useQuery({
    queryKey: ["users"],
    queryFn: () => apiGet<UserDTO[]>("/api/users"),
    enabled: manager,
  });
  const departmentsQuery = useQuery({
    queryKey: ["departments"],
    queryFn: () => apiGet<DepartmentDTO[]>("/api/departments"),
    enabled: manager,
  });

  const params = new URLSearchParams({ weekNumber: String(week), weekYear: String(year) });
  if (manager && userId) params.set("userId", userId);
  if (manager && departmentId) params.set("departmentId", departmentId);
  const qs = params.toString();

  const tasksQuery = useQuery({
    queryKey: ["tasks", "weekly", qs],
    queryFn: () => apiGet<TaskDTO[]>(`/api/tasks?${qs}`),
  });
  const kpisQuery = useQuery({ queryKey: ["kpis"], queryFn: () => apiGet<KpiDTO[]>("/api/kpis") });

  // Staff picker: scoped to the selected department (plus cross-cutting/HQ staff),
  // mirroring the API's department filter.
  const spanIds = (departmentsQuery.data ?? []).filter((d) => d.spansAll).map((d) => d.id);
  const staffUsers = (usersQuery.data ?? []).filter((u) => u.role === "STAFF");
  const usersForPicker = !departmentId
    ? staffUsers
    : spanIds.includes(departmentId)
      ? staffUsers.filter((u) => u.departmentId === departmentId)
      : staffUsers.filter(
          (u) => u.departmentId === departmentId || (u.departmentId && spanIds.includes(u.departmentId))
        );

  const [logTask, setLogTask] = React.useState<TaskDTO | null>(null);

  const invalidate = () => {
    qc.invalidateQueries({ queryKey: ["tasks"] });
    qc.invalidateQueries({ queryKey: ["kpis"] });
    qc.invalidateQueries({ queryKey: ["me"] });
    qc.invalidateQueries({ queryKey: ["reports"] });
  };

  const delContribution = useMutation({
    mutationFn: (id: string) => apiSend(`/api/contributions/${id}`, "DELETE"),
    onSuccess: invalidate,
  });

  const tasks = tasksQuery.data ?? [];
  const myId = session?.user?.id;
  const deptKpis = (kpisQuery.data ?? []).filter((k) => k.type === "DEPARTMENT");
  // Personal KPIs the current user can log against: those assigned directly to
  // them (assignedUserId), plus legacy position-matched ones with no assignee.
  const personalKpis = (kpisQuery.data ?? []).filter(
    (k) =>
      k.type === "PERSONAL" &&
      (k.assignedUserId === myId ||
        (!k.assignedUserId && (!position || k.assignedPosition === position)))
  );

  return (
    <div>
      <PageHeader title="Weekly Log" subtitle="Mark tasks complete and attribute their KPI impact">
        {manager && (
          <>
            <Select
              className="w-auto"
              value={departmentId}
              onChange={(e) => {
                setDepartmentId(e.target.value);
                setUserId("");
              }}
            >
              <option value="">All departments</option>
              {(departmentsQuery.data ?? []).map((d) => (
                <option key={d.id} value={d.id}>
                  {d.name}
                </option>
              ))}
            </Select>
            <Select
              className="w-auto"
              value={userId}
              onChange={(e) => {
                setUserId(e.target.value);
                setDepartmentId("");
              }}
            >
              <option value="">All staff</option>
              {usersForPicker.map((u) => (
                <option key={u.id} value={u.id}>
                  {u.name}
                  {u.position ? ` · ${u.position}` : ""}
                </option>
              ))}
            </Select>
          </>
        )}
        <Select className="w-auto" value={sel} onChange={(e) => setSel(e.target.value)}>
          {weeks.map((w) => (
            <option key={`${w.year}-${w.week}`} value={`${w.year}-${w.week}`}>
              {w.label}
            </option>
          ))}
        </Select>
      </PageHeader>

      <div className="mb-4 rounded-md border border-border bg-accent px-4 py-3 text-sm text-accent-foreground">
        {formatIsoWeek(week, year)}
      </div>

      {tasksQuery.isLoading ? (
        <Spinner />
      ) : tasks.length === 0 ? (
        <EmptyState
          title="No tasks this week"
          description="Tasks are grouped by their due-date week. Create tasks under the Tasks page."
        />
      ) : (
        <div className="space-y-3">
          {tasks.map((t) => (
            <Card key={t.id}>
              <CardContent className="p-4">
                <div className="flex flex-wrap items-start justify-between gap-3">
                  <div className="min-w-0">
                    <div className="flex flex-wrap items-center gap-2">
                      <span className="font-medium">{t.title}</span>
                      <Badge variant={STATUS_BADGE[t.status]}>{STATUS_LABEL[t.status]}</Badge>
                      {manager && <Badge variant="outline">{t.user.name}</Badge>}
                    </div>
                    {t.contributions.length > 0 && (
                      <div className="mt-2 space-y-1">
                        {t.contributions.map((c) => (
                          <div
                            key={c.id}
                            className="flex items-center gap-2 text-xs text-muted-foreground"
                          >
                            <Link2 className="size-3" />
                            <span className="font-medium text-foreground">
                              {c.kpiIndicator.name}
                            </span>
                            <span>
                              +{formatMetric(c.metricDelta, c.kpiIndicator.unit)}
                            </span>
                            {c.impactDescription && <span>· {c.impactDescription}</span>}
                            <button
                              onClick={() => delContribution.mutate(c.id)}
                              className="ml-1 hover:text-destructive"
                            >
                              <Trash2 className="size-3" />
                            </button>
                          </div>
                        ))}
                      </div>
                    )}
                  </div>
                  <Button variant="secondary" size="sm" onClick={() => setLogTask(t)}>
                    <Link2 className="size-3.5" /> Log KPI impact
                  </Button>
                </div>
              </CardContent>
            </Card>
          ))}
        </div>
      )}

      {logTask && (
        <ContributionDialog
          task={logTask}
          deptKpis={deptKpis}
          personalKpis={personalKpis}
          onClose={() => setLogTask(null)}
          onSaved={invalidate}
        />
      )}
    </div>
  );
}

function ContributionDialog({
  task,
  deptKpis,
  personalKpis,
  onClose,
  onSaved,
}: {
  task: TaskDTO;
  deptKpis: KpiDTO[];
  personalKpis: KpiDTO[];
  onClose: () => void;
  onSaved: () => void;
}) {
  const [deptKpi, setDeptKpi] = React.useState("");
  const [personalKpi, setPersonalKpi] = React.useState("");
  const [delta, setDelta] = React.useState("0");
  const [impact, setImpact] = React.useState("");
  const [complete, setComplete] = React.useState(task.status !== "COMPLETED");
  const [error, setError] = React.useState("");

  const save = useMutation({
    mutationFn: async () => {
      if (!deptKpi && !personalKpi) throw new Error("Select at least one KPI to attribute");
      const d = Number(delta) || 0;
      const targets = [deptKpi, personalKpi].filter(Boolean);
      for (const kpiIndicatorId of targets) {
        await apiSend("/api/contributions", "POST", {
          taskId: task.id,
          kpiIndicatorId,
          metricDelta: d,
          impactDescription: impact || null,
        });
      }
      if (complete && task.status !== "COMPLETED") {
        await apiSend(`/api/tasks/${task.id}`, "PATCH", { status: "COMPLETED" });
      }
    },
    onSuccess: () => {
      onSaved();
      onClose();
    },
    onError: (e) => setError(e instanceof Error ? e.message : "Failed to save"),
  });

  return (
    <Dialog open onClose={onClose}>
      <DialogHeader title="Attribute KPI Impact" onClose={onClose} />
      <form
        onSubmit={(e) => {
          e.preventDefault();
          setError("");
          save.mutate();
        }}
      >
        <DialogBody>
          <p className="text-sm text-muted-foreground">
            Task: <span className="font-medium text-foreground">{task.title}</span>
          </p>
          <div className="space-y-1.5">
            <Label>Department KPI supported</Label>
            <Select value={deptKpi} onChange={(e) => setDeptKpi(e.target.value)}>
              <option value="">— None —</option>
              {deptKpis.map((k) => (
                <option key={k.id} value={k.id}>
                  {k.name} ({k.unit})
                </option>
              ))}
            </Select>
          </div>
          <div className="space-y-1.5">
            <Label>Personal KPI satisfied</Label>
            <Select value={personalKpi} onChange={(e) => setPersonalKpi(e.target.value)}>
              <option value="">— None —</option>
              {personalKpis.map((k) => (
                <option key={k.id} value={k.id}>
                  {k.name} ({k.unit})
                </option>
              ))}
            </Select>
            {personalKpis.length === 0 && (
              <p className="text-xs text-muted-foreground">
                No personal KPIs are assigned to you yet.
              </p>
            )}
          </div>
          <div className="space-y-1.5">
            <Label>Metric value added (Δ)</Label>
            <Input
              type="number"
              step="any"
              value={delta}
              onChange={(e) => setDelta(e.target.value)}
              placeholder="e.g. 500 (clicks added)"
            />
            <p className="text-xs text-muted-foreground">
              Added to each selected KPI&apos;s current value.
            </p>
          </div>
          <div className="space-y-1.5">
            <Label>Impact description</Label>
            <Textarea
              value={impact}
              onChange={(e) => setImpact(e.target.value)}
              placeholder="How did this task move the metric?"
            />
          </div>
          <label className="flex items-center gap-2 text-sm">
            <input
              type="checkbox"
              checked={complete}
              onChange={(e) => setComplete(e.target.checked)}
            />
            <CheckCircle2 className="size-4 text-success" />
            Mark task as Completed
          </label>
          {error && <p className="text-sm text-destructive">{error}</p>}
        </DialogBody>
        <DialogFooter>
          <Button type="button" variant="secondary" onClick={onClose}>
            Cancel
          </Button>
          <Button type="submit" disabled={save.isPending}>
            Save contribution
          </Button>
        </DialogFooter>
      </form>
    </Dialog>
  );
}
