"use client";

import * as React from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useSession } from "next-auth/react";
import { Plus, Pencil, Trash2, LayoutGrid, List as ListIcon } from "lucide-react";
import { apiGet, apiSend } from "@/lib/api";
import type { TaskDTO, UserDTO } from "@/lib/types";
import { isManagerTier } from "@/lib/rbac";
import { cn, formatMetric } from "@/lib/utils";
import {
  STATUS_ORDER,
  STATUS_LABEL,
  STATUS_BADGE,
  PRIORITY_LABEL,
  PRIORITY_BADGE,
  PRIORITY_BORDER,
  CHANNEL_LABEL,
} from "@/lib/labels";
import { Button } from "@/components/ui/button";
import { Select } from "@/components/ui/select";
import { Badge } from "@/components/ui/badge";
import { Card } from "@/components/ui/card";
import { PageHeader, Spinner, EmptyState } from "@/components/common";
import { TaskDialog } from "@/components/task-dialog";

const CHANNELS = ["META", "GOOGLE", "TIKTOK", "OFFLINE", "SEO", "EMAIL", "OTHER"];

export function TasksView() {
  const { data: session } = useSession();
  const role = session?.user?.role;
  const myId = session?.user?.id;
  const manager = isManagerTier(role);
  const qc = useQueryClient();

  const [view, setView] = React.useState<"board" | "list">("board");
  const [staffFilter, setStaffFilter] = React.useState("");
  const [channelFilter, setChannelFilter] = React.useState("");
  const [dialogOpen, setDialogOpen] = React.useState(false);
  const [editing, setEditing] = React.useState<TaskDTO | null>(null);

  const staffQuery = useQuery({
    queryKey: ["users"],
    queryFn: () => apiGet<UserDTO[]>("/api/users"),
  });
  const staff = (staffQuery.data ?? []).filter((u) => u.role === "STAFF");

  const params = new URLSearchParams();
  if (manager && staffFilter) params.set("userId", staffFilter);
  if (channelFilter) params.set("channel", channelFilter);
  const qs = params.toString();

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

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

  const statusMutation = useMutation({
    mutationFn: (v: { id: string; status: string }) =>
      apiSend(`/api/tasks/${v.id}`, "PATCH", { status: v.status }),
    onSuccess: invalidate,
  });
  const deleteMutation = useMutation({
    mutationFn: (id: string) => apiSend(`/api/tasks/${id}`, "DELETE"),
    onSuccess: invalidate,
  });

  const tasks = tasksQuery.data ?? [];

  function openNew() {
    setEditing(null);
    setDialogOpen(true);
  }
  function openEdit(t: TaskDTO) {
    setEditing(t);
    setDialogOpen(true);
  }

  return (
    <div>
      <PageHeader title="Tasks" subtitle="Work item board — log, assign and track marketing tasks">
        <div className="flex items-center rounded-md border border-border p-0.5">
          <button
            onClick={() => setView("board")}
            className={cn("flex items-center gap-1 rounded px-2 py-1 text-xs", view === "board" && "bg-secondary")}
          >
            <LayoutGrid className="size-3.5" /> Board
          </button>
          <button
            onClick={() => setView("list")}
            className={cn("flex items-center gap-1 rounded px-2 py-1 text-xs", view === "list" && "bg-secondary")}
          >
            <ListIcon className="size-3.5" /> List
          </button>
        </div>
        <Button onClick={openNew}>
          <Plus className="size-4" /> New Task
        </Button>
      </PageHeader>

      {/* Filters */}
      <div className="mb-4 flex flex-wrap items-center gap-2">
        {manager && (
          <Select
            className="h-8 w-auto text-xs"
            value={staffFilter}
            onChange={(e) => setStaffFilter(e.target.value)}
          >
            <option value="">All staff</option>
            {staff.map((s) => (
              <option key={s.id} value={s.id}>
                {s.name}
                {s.position ? ` (${s.position})` : ""}
              </option>
            ))}
          </Select>
        )}
        <Select
          className="h-8 w-auto text-xs"
          value={channelFilter}
          onChange={(e) => setChannelFilter(e.target.value)}
        >
          <option value="">All channels</option>
          {CHANNELS.map((c) => (
            <option key={c} value={c}>
              {CHANNEL_LABEL[c]}
            </option>
          ))}
        </Select>
        <span className="text-xs text-muted-foreground">{tasks.length} tasks</span>
      </div>

      {tasksQuery.isLoading ? (
        <Spinner />
      ) : tasks.length === 0 ? (
        <EmptyState title="No tasks" description="Create your first task to get started.">
          <Button onClick={openNew}>
            <Plus className="size-4" /> New Task
          </Button>
        </EmptyState>
      ) : view === "board" ? (
        <div className="grid grid-cols-1 gap-3 sm:grid-cols-2 xl:grid-cols-5">
          {STATUS_ORDER.map((status) => {
            const col = tasks.filter((t) => t.status === status);
            return (
              <div key={status} className="rounded-lg border border-border bg-secondary/40 p-2">
                <div className="mb-2 flex items-center justify-between px-1">
                  <span className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                    {STATUS_LABEL[status]}
                  </span>
                  <span className="rounded-full bg-card px-2 text-[11px] text-muted-foreground">
                    {col.length}
                  </span>
                </div>
                <div className="space-y-2">
                  {col.map((t) => (
                    <TaskCard
                      key={t.id}
                      task={t}
                      onEdit={() => openEdit(t)}
                      onDelete={() => deleteMutation.mutate(t.id)}
                      onStatus={(s) => statusMutation.mutate({ id: t.id, status: s })}
                      showAssignee={manager}
                    />
                  ))}
                </div>
              </div>
            );
          })}
        </div>
      ) : (
        <Card className="overflow-hidden">
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-border text-left text-xs uppercase text-muted-foreground">
                  <th className="px-4 py-2.5">Task</th>
                  {manager && <th className="px-4 py-2.5">Assignee</th>}
                  <th className="px-4 py-2.5">Status</th>
                  <th className="px-4 py-2.5">Priority</th>
                  <th className="px-4 py-2.5">Channel</th>
                  <th className="px-4 py-2.5">Week</th>
                  <th className="px-4 py-2.5">KPI Δ</th>
                  <th className="px-4 py-2.5 text-right">Actions</th>
                </tr>
              </thead>
              <tbody>
                {tasks.map((t) => {
                  const delta = t.contributions.reduce((s, c) => s + c.metricDelta, 0);
                  return (
                    <tr key={t.id} className="border-b border-border last:border-0">
                      <td className="px-4 py-2.5 font-medium">{t.title}</td>
                      {manager && (
                        <td className="px-4 py-2.5 text-muted-foreground">{t.user.name}</td>
                      )}
                      <td className="px-4 py-2.5">
                        <Select
                          className="h-7 w-auto text-xs"
                          value={t.status}
                          onChange={(e) => statusMutation.mutate({ id: t.id, status: e.target.value })}
                        >
                          {STATUS_ORDER.map((s) => (
                            <option key={s} value={s}>
                              {STATUS_LABEL[s]}
                            </option>
                          ))}
                        </Select>
                      </td>
                      <td className="px-4 py-2.5">
                        <Badge variant={PRIORITY_BADGE[t.priority]}>{PRIORITY_LABEL[t.priority]}</Badge>
                      </td>
                      <td className="px-4 py-2.5 text-muted-foreground">
                        {t.channel ? CHANNEL_LABEL[t.channel] : "—"}
                      </td>
                      <td className="px-4 py-2.5 text-muted-foreground">
                        W{t.weekNumber}
                      </td>
                      <td className="px-4 py-2.5 text-muted-foreground">
                        {delta ? formatMetric(delta) : "—"}
                      </td>
                      <td className="px-4 py-2.5">
                        <div className="flex justify-end gap-1">
                          <Button variant="ghost" size="icon" onClick={() => openEdit(t)}>
                            <Pencil className="size-3.5" />
                          </Button>
                          <Button variant="ghost" size="icon" onClick={() => deleteMutation.mutate(t.id)}>
                            <Trash2 className="size-3.5" />
                          </Button>
                        </div>
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </Card>
      )}

      <TaskDialog
        open={dialogOpen}
        onClose={() => setDialogOpen(false)}
        onSaved={invalidate}
        task={editing}
        staff={staff}
        canAssign={manager}
        defaultUserId={myId}
      />
    </div>
  );
}

function TaskCard({
  task,
  onEdit,
  onDelete,
  onStatus,
  showAssignee,
}: {
  task: TaskDTO;
  onEdit: () => void;
  onDelete: () => void;
  onStatus: (s: string) => void;
  showAssignee: boolean;
}) {
  return (
    <div
      className={cn(
        "rounded-md border border-border border-l-[3px] bg-card p-2.5 shadow-sm",
        PRIORITY_BORDER[task.priority]
      )}
    >
      <div className="mb-1.5 flex items-start justify-between gap-2">
        <span className="text-sm font-medium leading-snug">{task.title}</span>
        <div className="flex shrink-0 gap-0.5">
          <button onClick={onEdit} className="text-muted-foreground hover:text-foreground">
            <Pencil className="size-3.5" />
          </button>
          <button onClick={onDelete} className="text-muted-foreground hover:text-destructive">
            <Trash2 className="size-3.5" />
          </button>
        </div>
      </div>
      <div className="mb-2 flex flex-wrap items-center gap-1.5">
        <Badge variant={PRIORITY_BADGE[task.priority]}>{PRIORITY_LABEL[task.priority]}</Badge>
        {task.channel && <Badge variant="outline">{CHANNEL_LABEL[task.channel]}</Badge>}
        {task.contributions.length > 0 && (
          <Badge variant="primary">{task.contributions.length} KPI</Badge>
        )}
      </div>
      <div className="flex items-center justify-between gap-2">
        <Select
          className="h-7 w-auto text-xs"
          value={task.status}
          onChange={(e) => onStatus(e.target.value)}
        >
          {STATUS_ORDER.map((s) => (
            <option key={s} value={s}>
              {STATUS_LABEL[s]}
            </option>
          ))}
        </Select>
        {showAssignee && (
          <span className="truncate text-[11px] text-muted-foreground">{task.user.name}</span>
        )}
      </div>
    </div>
  );
}
