"use client";

import { useMemo, useState, useTransition } from "react";
import { useRouter } from "next/navigation";

import { BulkDeleteButton } from "@/components/admin/common/BulkDeleteButton";
import { ADMIN_PERMISSION_GROUPS } from "@/lib/admin-rbac";

type AdminUserRow = {
  id: string;
  name: string | null;
  email: string;
  role: "ADMIN" | "MODERATOR";
  permissions: string[];
  isActive: boolean;
  lastLoginAt: Date | string | null;
  createdAt: Date | string;
};

type UserListManagerProps = {
  items: AdminUserRow[];
};

type UserFormState = {
  id?: string;
  name: string;
  email: string;
  role: "ADMIN" | "MODERATOR";
  permissions: string[];
  isActive: boolean;
  password?: string;
};

const emptyUserForm: UserFormState = {
  name: "",
  email: "",
  role: "MODERATOR",
  permissions: ["dashboard:view"],
  isActive: true,
  password: "",
};

function normalizeUserForm(user: AdminUserRow): UserFormState {
  return {
    id: user.id,
    name: user.name ?? "",
    email: user.email,
    role: user.role,
    permissions: user.permissions,
    isActive: user.isActive,
    password: "",
  };
}

function formatDate(value?: Date | string | null) {
  if (!value) {
    return "Nikada";
  }

  return new Intl.DateTimeFormat("sr-Latn-RS", {
    day: "2-digit",
    month: "long",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
  }).format(new Date(value));
}

function buildNextItems(items: AdminUserRow[], updated: AdminUserRow) {
  const exists = items.some((item) => item.id === updated.id);
  if (!exists) {
    return [updated, ...items];
  }

  return items.map((item) => (item.id === updated.id ? updated : item));
}

export function UserListManager({ items: initialItems }: UserListManagerProps) {
  const router = useRouter();
  const [items, setItems] = useState(initialItems);
  const [createForm, setCreateForm] = useState<UserFormState>(emptyUserForm);
  const [drafts, setDrafts] = useState<Record<string, UserFormState>>(
    Object.fromEntries(initialItems.map((item) => [item.id, normalizeUserForm(item)])),
  );
  const [selectedIds, setSelectedIds] = useState<string[]>([]);
  const [bulkRole, setBulkRole] = useState<"" | "ADMIN" | "MODERATOR">("");
  const [bulkActive, setBulkActive] = useState<"" | "true" | "false">("");
  const [resetPasswords, setResetPasswords] = useState<Record<string, string>>({});
  const [message, setMessage] = useState<string | null>(null);
  const [isPending, startTransition] = useTransition();

  const summary = useMemo(
    () => ({
      total: items.length,
      active: items.filter((item) => item.isActive).length,
      admins: items.filter((item) => item.role === "ADMIN").length,
      moderators: items.filter((item) => item.role === "MODERATOR").length,
    }),
    [items],
  );

  function updateDraft(id: string, patch: Partial<UserFormState>) {
    setDrafts((current) => ({
      ...current,
      [id]: {
        ...current[id],
        ...patch,
      },
    }));
  }

  function togglePermissions(
    target: "create" | string,
    permission: string,
    checked: boolean,
  ) {
    if (target === "create") {
      setCreateForm((current) => ({
        ...current,
        permissions: checked
          ? [...new Set([...current.permissions, permission])]
          : current.permissions.filter((item) => item !== permission),
      }));
      return;
    }

    setDrafts((current) => ({
      ...current,
      [target]: {
        ...current[target],
        permissions: checked
          ? [...new Set([...(current[target]?.permissions ?? []), permission])]
          : (current[target]?.permissions ?? []).filter((item) => item !== permission),
      },
    }));
  }

  function toggleSelection(id: string) {
    setSelectedIds((current) =>
      current.includes(id) ? current.filter((item) => item !== id) : [...current, id],
    );
  }

  async function submitUser(payload: UserFormState, successMessage: string) {
    const response = await fetch("/api/admin/users", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify(payload),
    });

    const result = (await response.json()) as {
      item?: AdminUserRow;
      message?: string;
    };

    if (!response.ok || !result.item) {
      throw new Error(result.message || "Čuvanje korisnika nije uspelo.");
    }

    setItems((current) => buildNextItems(current, result.item!));
    setDrafts((current) => ({
      ...current,
      [result.item!.id]: normalizeUserForm(result.item!),
    }));
    setMessage(successMessage);
    router.refresh();
  }

  function handleCreate() {
    startTransition(async () => {
      try {
        await submitUser(createForm, `Korisnik ${createForm.email} je sačuvan.`);
        setCreateForm(emptyUserForm);
      } catch (error) {
        setMessage(error instanceof Error ? error.message : "Kreiranje korisnika nije uspelo.");
      }
    });
  }

  function handleSaveUser(id: string) {
    const draft = drafts[id];
    if (!draft) {
      return;
    }

    startTransition(async () => {
      try {
        await submitUser({ ...draft, id }, `Izmene za korisnika ${draft.email} su sačuvane.`);
      } catch (error) {
        setMessage(error instanceof Error ? error.message : "Izmena korisnika nije uspela.");
      }
    });
  }

  function handleBulkApply() {
    startTransition(async () => {
      try {
        const response = await fetch("/api/admin/users/bulk", {
          method: "POST",
          headers: { "content-type": "application/json" },
          body: JSON.stringify({
            ids: selectedIds,
            changes: {
              ...(bulkRole ? { role: bulkRole } : {}),
              ...(bulkActive ? { isActive: bulkActive === "true" } : {}),
            },
          }),
        });

        const result = (await response.json()) as {
          items?: AdminUserRow[];
          message?: string;
        };

        if (!response.ok || !result.items) {
          throw new Error(result.message || "Masovna izmena korisnika nije uspela.");
        }

        setItems(result.items);
        setDrafts(
          Object.fromEntries(result.items.map((item) => [item.id, normalizeUserForm(item)])),
        );
        setSelectedIds([]);
        setBulkRole("");
        setBulkActive("");
        setMessage(`Masovna izmena je sačuvana za ${result.items.length} korisnika.`);
        router.refresh();
      } catch (error) {
        setMessage(error instanceof Error ? error.message : "Masovna izmena nije uspela.");
      }
    });
  }

  function handlePasswordReset(id: string) {
    const password = resetPasswords[id]?.trim();
    if (!password) {
      setMessage("Unesite novu lozinku pre resetovanja.");
      return;
    }

    startTransition(async () => {
      try {
        const response = await fetch(`/api/admin/users/${id}/password`, {
          method: "POST",
          headers: { "content-type": "application/json" },
          body: JSON.stringify({ password }),
        });

        const result = (await response.json()) as { message?: string };

        if (!response.ok) {
          throw new Error(result.message || "Reset lozinke nije uspeo.");
        }

        setResetPasswords((current) => ({ ...current, [id]: "" }));
        setMessage("Lozinka je uspešno resetovana.");
      } catch (error) {
        setMessage(error instanceof Error ? error.message : "Reset lozinke nije uspeo.");
      }
    });
  }

  return (
    <div className="space-y-6">
      <section className="admin-command-shell">
        <div className="admin-command-header">
          <div>
            <p className="eyebrow">RBAC komandni centar</p>
            <h3 className="mt-3 font-display text-3xl font-semibold text-foreground">
              Korisnici, role i granularne dozvole
            </h3>
            <p className="mt-3 max-w-3xl text-sm leading-7 text-muted-foreground">
              Kreiraj nove admin naloge, podešavaj pristup po sekcijama i resetuj lozinke bez
              ulaska u detalje svakog naloga.
            </p>
          </div>
          <div className="admin-kpi-grid sm:max-w-[540px]">
            <div className="admin-kpi-card">
              <div className="admin-kpi-label">Ukupno</div>
              <div className="admin-kpi-value">{summary.total}</div>
            </div>
            <div className="admin-kpi-card">
              <div className="admin-kpi-label">Aktivni</div>
              <div className="admin-kpi-value">{summary.active}</div>
            </div>
            <div className="admin-kpi-card">
              <div className="admin-kpi-label">Admin</div>
              <div className="admin-kpi-value">{summary.admins}</div>
            </div>
            <div className="admin-kpi-card">
              <div className="admin-kpi-label">Moderatori</div>
              <div className="admin-kpi-value">{summary.moderators}</div>
            </div>
          </div>
        </div>
      </section>

      <section className="admin-command-shell">
        <div className="grid gap-4 lg:grid-cols-2">
          <label className="text-sm font-medium text-foreground">
            Ime i prezime
            <input
              className="mt-3 h-12 w-full rounded-2xl border border-border bg-white px-4"
              value={createForm.name}
              onChange={(event) => setCreateForm((current) => ({ ...current, name: event.target.value }))}
            />
          </label>
          <label className="text-sm font-medium text-foreground">
            Email
            <input
              className="mt-3 h-12 w-full rounded-2xl border border-border bg-white px-4"
              value={createForm.email}
              onChange={(event) => setCreateForm((current) => ({ ...current, email: event.target.value }))}
            />
          </label>
          <label className="text-sm font-medium text-foreground">
            Rola
            <select
              className="mt-3 h-12 w-full rounded-2xl border border-border bg-white px-4"
              value={createForm.role}
              onChange={(event) =>
                setCreateForm((current) => ({
                  ...current,
                  role: event.target.value as "ADMIN" | "MODERATOR",
                }))
              }
            >
              <option value="MODERATOR">MODERATOR</option>
              <option value="ADMIN">ADMIN</option>
            </select>
          </label>
          <label className="text-sm font-medium text-foreground">
            Početna lozinka
            <input
              type="password"
              className="mt-3 h-12 w-full rounded-2xl border border-border bg-white px-4"
              value={createForm.password}
              onChange={(event) =>
                setCreateForm((current) => ({ ...current, password: event.target.value }))
              }
            />
          </label>
        </div>

        <div className="mt-5 rounded-[1.5rem] border border-border bg-white/70 p-4">
          <p className="text-sm font-semibold text-foreground">Dozvole za novi nalog</p>
          <div className="mt-4 grid gap-4 lg:grid-cols-3">
            {ADMIN_PERMISSION_GROUPS.map((group) => (
              <div key={group.label} className="rounded-[1.2rem] bg-muted/40 p-4">
                <p className="text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground">
                  {group.label}
                </p>
                <div className="mt-3 space-y-3">
                  {group.items.map((permission) => (
                    <label key={permission.key} className="flex items-start gap-3 text-sm">
                      <input
                        type="checkbox"
                        checked={createForm.permissions.includes(permission.key)}
                        onChange={(event) =>
                          togglePermissions("create", permission.key, event.target.checked)
                        }
                        className="mt-1 size-4"
                      />
                      <span>
                        <span className="font-medium text-foreground">{permission.label}</span>
                        <span className="mt-1 block text-xs text-muted-foreground">
                          {permission.key}
                        </span>
                      </span>
                    </label>
                  ))}
                </div>
              </div>
            ))}
          </div>
        </div>

        <div className="mt-5 flex flex-wrap items-center justify-between gap-3">
          <label className="flex items-center gap-3 text-sm font-medium text-foreground">
            <input
              type="checkbox"
              checked={createForm.isActive}
              onChange={(event) =>
                setCreateForm((current) => ({ ...current, isActive: event.target.checked }))
              }
              className="size-4"
            />
            Aktivan nalog
          </label>
          <button type="button" onClick={handleCreate} className="primary-button" disabled={isPending}>
            Kreiraj korisnika
          </button>
        </div>
      </section>

      <section className="admin-command-shell">
        <div className="grid gap-3 border-b border-border/80 pb-5 lg:grid-cols-[repeat(2,minmax(0,1fr))_auto]">
          <select
            value={bulkRole}
            onChange={(event) => setBulkRole(event.target.value as "" | "ADMIN" | "MODERATOR")}
            aria-label="Bulk rola za korisnike"
            className="inline-select"
          >
            <option value="">Bulk rola</option>
            <option value="ADMIN">ADMIN</option>
            <option value="MODERATOR">MODERATOR</option>
          </select>
          <select
            value={bulkActive}
            onChange={(event) => setBulkActive(event.target.value as "" | "true" | "false")}
            aria-label="Bulk aktivnost za korisnike"
            className="inline-select"
          >
            <option value="">Bulk aktivnost</option>
            <option value="true">Aktivan</option>
            <option value="false">Neaktivan</option>
          </select>
          <button
            type="button"
            className="primary-button justify-center disabled:cursor-not-allowed disabled:opacity-60"
            onClick={handleBulkApply}
            disabled={isPending || !selectedIds.length || (!bulkRole && !bulkActive)}
          >
            Primeni na označene
          </button>
          <BulkDeleteButton
            endpoint="/api/admin/users/bulk"
            ids={selectedIds}
            itemLabel="korisnika"
            onDeleted={(ids) => {
              setItems((current) => current.filter((row) => !ids.includes(row.id)));
              setSelectedIds([]);
              router.refresh();
            }}
          />
        </div>

        {message ? (
          <div className="mt-5 rounded-[1.2rem] border border-secondary/16 bg-accent/55 px-4 py-3 text-sm font-medium text-primary">
            {message}
          </div>
        ) : null}

        <div className="mt-5 divide-y divide-border overflow-hidden rounded-[1.5rem] border border-border bg-white/62">
          {items.map((item) => {
            const draft = drafts[item.id] ?? normalizeUserForm(item);

            return (
              <article key={item.id} className="admin-list-card">
                <div className="flex flex-col gap-4 xl:flex-row xl:items-start xl:justify-between">
                  <div className="flex min-w-0 flex-1 items-start gap-4">
                    <input
                      type="checkbox"
                      aria-label={`Označi korisnika ${item.email}`}
                      checked={selectedIds.includes(item.id)}
                      onChange={() => toggleSelection(item.id)}
                      className="mt-2 size-4"
                    />
                    <div>
                      <p className="admin-list-card-title">
                        {item.name || "Bez imena"}
                      </p>
                      <p className="admin-list-card-subtitle">{item.email}</p>
                      <div className="mt-3 flex flex-wrap gap-2">
                        <span className="admin-chip">{item.role}</span>
                        <span className="admin-chip">
                          {item.isActive ? "Aktivan" : "Neaktivan"}
                        </span>
                        <span className="admin-chip">
                          Poslednja prijava: {formatDate(item.lastLoginAt)}
                        </span>
                      </div>
                      <div className="admin-kpi-grid mt-4">
                        <div className="admin-kpi-card">
                          <div className="admin-kpi-label">Dozvole</div>
                          <div className="admin-kpi-value">{item.permissions.length}</div>
                        </div>
                        <div className="admin-kpi-card">
                          <div className="admin-kpi-label">Rola</div>
                          <div className="admin-kpi-value">{item.role}</div>
                        </div>
                        <div className="admin-kpi-card">
                          <div className="admin-kpi-label">Status</div>
                          <div className="admin-kpi-value">{item.isActive ? "Aktivan" : "Neaktivan"}</div>
                        </div>
                        <div className="admin-kpi-card">
                          <div className="admin-kpi-label">Kreiran</div>
                          <div className="admin-kpi-value">{formatDate(item.createdAt)}</div>
                        </div>
                      </div>
                    </div>
                  </div>

                  <div className="admin-list-card-actions">
                    <button
                      type="button"
                      onClick={() => handleSaveUser(item.id)}
                      className="primary-button"
                      disabled={isPending}
                    >
                      Sačuvaj izmene
                    </button>
                  </div>
                </div>

                <div className="mt-5 grid gap-4 lg:grid-cols-2">
                  <label className="text-sm font-medium text-foreground">
                    Ime
                    <input
                      className="mt-3 h-12 w-full rounded-2xl border border-border bg-white px-4"
                      value={draft.name}
                      onChange={(event) => updateDraft(item.id, { name: event.target.value })}
                    />
                  </label>
                  <label className="text-sm font-medium text-foreground">
                    Email
                    <input
                      className="mt-3 h-12 w-full rounded-2xl border border-border bg-white px-4"
                      value={draft.email}
                      onChange={(event) => updateDraft(item.id, { email: event.target.value })}
                    />
                  </label>
                  <label className="text-sm font-medium text-foreground">
                    Rola
                    <select
                      className="mt-3 h-12 w-full rounded-2xl border border-border bg-white px-4"
                      value={draft.role}
                      onChange={(event) =>
                        updateDraft(item.id, { role: event.target.value as "ADMIN" | "MODERATOR" })
                      }
                    >
                      <option value="ADMIN">ADMIN</option>
                      <option value="MODERATOR">MODERATOR</option>
                    </select>
                  </label>
                  <label className="flex items-center gap-3 rounded-[1.5rem] border border-border bg-white px-4 py-4 text-sm font-medium text-foreground">
                    <input
                      type="checkbox"
                      checked={draft.isActive}
                      onChange={(event) => updateDraft(item.id, { isActive: event.target.checked })}
                      className="size-4"
                    />
                    Aktivan nalog
                  </label>
                </div>

                <div className="mt-5 grid gap-4 lg:grid-cols-3">
                  {ADMIN_PERMISSION_GROUPS.map((group) => (
                    <div key={group.label} className="rounded-[1.4rem] border border-border bg-white/80 p-4">
                      <p className="text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground">
                        {group.label}
                      </p>
                      <div className="mt-3 space-y-3">
                        {group.items.map((permission) => (
                          <label key={permission.key} className="flex items-start gap-3 text-sm">
                            <input
                              type="checkbox"
                              checked={draft.permissions.includes(permission.key)}
                              onChange={(event) =>
                                togglePermissions(item.id, permission.key, event.target.checked)
                              }
                              className="mt-1 size-4"
                            />
                            <span>
                              <span className="font-medium text-foreground">{permission.label}</span>
                              <span className="mt-1 block text-xs text-muted-foreground">
                                {permission.key}
                              </span>
                            </span>
                          </label>
                        ))}
                      </div>
                    </div>
                  ))}
                </div>

                <div className="mt-5 grid gap-3 lg:grid-cols-[minmax(0,1fr)_auto]">
                  <input
                    type="password"
                    className="h-12 rounded-2xl border border-border bg-white px-4"
                    placeholder="Nova lozinka za reset"
                    value={resetPasswords[item.id] ?? ""}
                    onChange={(event) =>
                      setResetPasswords((current) => ({
                        ...current,
                        [item.id]: event.target.value,
                      }))
                    }
                  />
                  <button
                    type="button"
                    className="ghost-button justify-center"
                    onClick={() => handlePasswordReset(item.id)}
                    disabled={isPending}
                  >
                    Resetuj lozinku
                  </button>
                </div>
              </article>
            );
          })}
        </div>
      </section>
    </div>
  );
}
