"use client";

import * as React from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useSession } from "next-auth/react";
import { Plus, Pencil, Ban, RotateCcw, Trash2 } from "lucide-react";
import { apiGet, apiSend } from "@/lib/api";
import type { UserDTO, DepartmentDTO } from "@/lib/types";
import { ROLE_LABELS, MARKETING_POSITIONS } from "@/lib/rbac";
import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Select } from "@/components/ui/select";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import { Dialog, DialogHeader, DialogBody, DialogFooter } from "@/components/ui/dialog";
import { PageHeader, Spinner, EmptyState } from "@/components/common";

const ROLES = ["SUPER_ADMIN", "ADMIN", "MANAGER", "STAFF"] as const;

export function UsersView() {
  const qc = useQueryClient();
  const { data: session } = useSession();
  const isSuperAdmin = session?.user?.role === "SUPER_ADMIN";
  const usersQuery = useQuery({ queryKey: ["users"], queryFn: () => apiGet<UserDTO[]>("/api/users") });
  const departmentsQuery = useQuery({
    queryKey: ["departments"],
    queryFn: () => apiGet<DepartmentDTO[]>("/api/departments"),
  });
  const [open, setOpen] = React.useState(false);
  const [editing, setEditing] = React.useState<UserDTO | null>(null);
  const [showInactive, setShowInactive] = React.useState(true);
  const [actionError, setActionError] = React.useState("");

  const refreshUsers = () => qc.invalidateQueries({ queryKey: ["users"] });

  const deactivate = useMutation({
    mutationFn: (id: string) => apiSend(`/api/users/${id}`, "DELETE"),
    onSuccess: refreshUsers,
  });
  const reactivate = useMutation({
    mutationFn: (id: string) => apiSend(`/api/users/${id}`, "PATCH", { active: true }),
    onSuccess: refreshUsers,
  });
  const hardDelete = useMutation({
    mutationFn: (id: string) => apiSend(`/api/users/${id}?hard=true`, "DELETE"),
    onSuccess: () => {
      setActionError("");
      refreshUsers();
    },
    onError: (e) => setActionError(e instanceof Error ? e.message : "Failed to delete user"),
  });

  const allUsers = usersQuery.data ?? [];
  const users = showInactive ? allUsers : allUsers.filter((u) => u.active);

  return (
    <div>
      <PageHeader title="Users" subtitle="Manage accounts, roles and staff positions">
        <label className="flex items-center gap-2 text-sm text-muted-foreground">
          <input
            type="checkbox"
            checked={showInactive}
            onChange={(e) => setShowInactive(e.target.checked)}
          />
          Show inactive
        </label>
        <Button
          onClick={() => {
            setEditing(null);
            setOpen(true);
          }}
        >
          <Plus className="size-4" /> New User
        </Button>
      </PageHeader>

      {actionError && (
        <div className="mb-4 rounded-md border border-destructive/40 bg-destructive/10 px-4 py-3 text-sm text-destructive">
          {actionError}
        </div>
      )}

      {usersQuery.isLoading ? (
        <Spinner />
      ) : users.length === 0 ? (
        <EmptyState title="No users" />
      ) : (
        <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">Name</th>
                  <th className="px-4 py-2.5">Email</th>
                  <th className="px-4 py-2.5">Role</th>
                  <th className="px-4 py-2.5">Department</th>
                  <th className="px-4 py-2.5">Position</th>
                  <th className="px-4 py-2.5">Status</th>
                  <th className="px-4 py-2.5 text-right">Actions</th>
                </tr>
              </thead>
              <tbody>
                {users.map((u) => (
                  <tr key={u.id} className="border-b border-border last:border-0">
                    <td className="px-4 py-2.5 font-medium">{u.name}</td>
                    <td className="px-4 py-2.5 text-muted-foreground">{u.email}</td>
                    <td className="px-4 py-2.5">
                      <Badge variant={u.role === "STAFF" ? "default" : "primary"}>
                        {ROLE_LABELS[u.role]}
                      </Badge>
                    </td>
                    <td className="px-4 py-2.5 text-muted-foreground">{u.department?.name ?? "—"}</td>
                    <td className="px-4 py-2.5 text-muted-foreground">{u.position ?? "—"}</td>
                    <td className="px-4 py-2.5">
                      <Badge variant={u.active ? "success" : "destructive"}>
                        {u.active ? "Active" : "Inactive"}
                      </Badge>
                    </td>
                    <td className="px-4 py-2.5">
                      <div className="flex justify-end gap-1">
                        <Button
                          variant="ghost"
                          size="icon"
                          onClick={() => {
                            setEditing(u);
                            setOpen(true);
                          }}
                          title="Edit"
                        >
                          <Pencil className="size-3.5" />
                        </Button>
                        {u.active ? (
                          <Button
                            variant="ghost"
                            size="icon"
                            onClick={() => deactivate.mutate(u.id)}
                            title="Deactivate"
                          >
                            <Ban className="size-3.5" />
                          </Button>
                        ) : (
                          <Button
                            variant="ghost"
                            size="icon"
                            onClick={() => reactivate.mutate(u.id)}
                            title="Reactivate"
                          >
                            <RotateCcw className="size-3.5" />
                          </Button>
                        )}
                        {isSuperAdmin && u.id !== session?.user?.id && (
                          <Button
                            variant="ghost"
                            size="icon"
                            className="text-destructive hover:text-destructive"
                            title="Delete permanently"
                            onClick={() => {
                              if (
                                window.confirm(
                                  `Permanently delete ${u.name}? This removes their account and cascades their assigned tasks, personal KPIs, authored posts and appraisals. This cannot be undone.`
                                )
                              ) {
                                hardDelete.mutate(u.id);
                              }
                            }}
                          >
                            <Trash2 className="size-3.5" />
                          </Button>
                        )}
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </Card>
      )}

      <UserDialog
        open={open}
        onClose={() => setOpen(false)}
        onSaved={() => qc.invalidateQueries({ queryKey: ["users"] })}
        user={editing}
        departments={departmentsQuery.data ?? []}
      />
    </div>
  );
}

function UserDialog({
  open,
  onClose,
  onSaved,
  user,
  departments,
}: {
  open: boolean;
  onClose: () => void;
  onSaved: () => void;
  user: UserDTO | null;
  departments: DepartmentDTO[];
}) {
  const activeDepartments = departments.filter((d) => d.active);
  const [form, setForm] = React.useState(() => initForm(user));
  const [error, setError] = React.useState("");

  React.useEffect(() => {
    setForm(initForm(user));
    setError("");
  }, [user, open]);

  const save = useMutation({
    mutationFn: async () => {
      const base = {
        name: form.name,
        email: form.email,
        role: form.role,
        position: form.role === "STAFF" ? form.position || null : null,
        departmentId: form.departmentId || null,
      };
      if (user) {
        const payload = form.password ? { ...base, password: form.password } : base;
        return apiSend(`/api/users/${user.id}`, "PATCH", payload);
      }
      return apiSend("/api/users", "POST", { ...base, password: form.password });
    },
    onSuccess: () => {
      onSaved();
      onClose();
    },
    onError: (e) => setError(e instanceof Error ? e.message : "Failed to save"),
  });

  function submit(e: React.FormEvent) {
    e.preventDefault();
    if (!form.name.trim() || !form.email.trim()) return setError("Name and email are required");
    if (!user && form.password.length < 6) return setError("Password must be at least 6 characters");
    if (form.role === "STAFF" && !form.position) return setError("Staff users need a position");
    save.mutate();
  }

  return (
    <Dialog open={open} onClose={onClose}>
      <DialogHeader title={user ? "Edit User" : "New User"} onClose={onClose} />
      <form onSubmit={submit}>
        <DialogBody>
          <div className="grid grid-cols-2 gap-3">
            <div className="space-y-1.5">
              <Label>Full name</Label>
              <Input value={form.name} onChange={(e) => setForm({ ...form, name: e.target.value })} />
            </div>
            <div className="space-y-1.5">
              <Label>Email</Label>
              <Input
                type="email"
                value={form.email}
                onChange={(e) => setForm({ ...form, email: e.target.value })}
              />
            </div>
            <div className="space-y-1.5">
              <Label>Role</Label>
              <Select value={form.role} onChange={(e) => setForm({ ...form, role: e.target.value })}>
                {ROLES.map((r) => (
                  <option key={r} value={r}>
                    {ROLE_LABELS[r]}
                  </option>
                ))}
              </Select>
            </div>
            <div className="space-y-1.5">
              <Label>Department</Label>
              <Select
                value={form.departmentId}
                onChange={(e) => setForm({ ...form, departmentId: e.target.value })}
              >
                <option value="">— No department —</option>
                {activeDepartments.map((d) => (
                  <option key={d.id} value={d.id}>
                    {d.name}
                  </option>
                ))}
              </Select>
              {activeDepartments.length === 0 && (
                <p className="text-[11px] text-muted-foreground">
                  Add departments on the KPI Indicators page.
                </p>
              )}
            </div>
            {form.role === "STAFF" && (
              <div className="space-y-1.5">
                <Label>Position</Label>
                <Input
                  list="user-positions"
                  value={form.position}
                  onChange={(e) => setForm({ ...form, position: e.target.value })}
                  placeholder="SEO Specialist"
                />
                <datalist id="user-positions">
                  {MARKETING_POSITIONS.map((p) => (
                    <option key={p} value={p} />
                  ))}
                </datalist>
              </div>
            )}
            <div className="col-span-2 space-y-1.5">
              <Label>{user ? "New password (leave blank to keep)" : "Password"}</Label>
              <Input
                type="password"
                value={form.password}
                onChange={(e) => setForm({ ...form, password: e.target.value })}
                placeholder="••••••••"
              />
            </div>
          </div>
          {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}>
            {user ? "Save changes" : "Create user"}
          </Button>
        </DialogFooter>
      </form>
    </Dialog>
  );
}

function initForm(user: UserDTO | null) {
  return {
    name: user?.name ?? "",
    email: user?.email ?? "",
    role: (user?.role ?? "STAFF") as string,
    position: user?.position ?? "",
    departmentId: user?.departmentId ?? "",
    password: "",
  };
}
