"use client";

import { RoleUpsertFormView } from "@/components/dashboard/users/role-upsert-form-view";
import type { DashboardUserLanguage } from "@/components/dashboard/users/users-types";
import {
  createRole,
  updateRole,
  useRole,
  usePermissionsCatalog,
} from "@/lib/api/dashboard/roles-api";
import { useLocale } from "next-intl";
import { useRouter } from "next/navigation";
import { useEffect, useMemo, useState } from "react";

interface RoleUpsertFormProps {
  mode: "create" | "edit";
  roleId?: string;
}

export function RoleUpsertForm({ mode, roleId }: RoleUpsertFormProps) {
  const locale = useLocale();
  const router = useRouter();
  const isRtl = locale === "ar";

  const { catalog, isLoading: isCatalogLoading } = usePermissionsCatalog();
  const { role } = useRole(mode === "edit" ? roleId : undefined);

  const [name, setName] = useState("");
  const [language, setLanguage] = useState<DashboardUserLanguage>(isRtl ? "ar" : "en");
  const [isActive, setIsActive] = useState(true);
  const [selected, setSelected] = useState<Set<number>>(new Set());
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [seeded, setSeeded] = useState(false);

  // Seed once when the edit role arrives.
  useEffect(() => {
    if (mode !== "edit" || seeded || !role) {
      return;
    }
    setName(role.name);
    setLanguage(role.language);
    setIsActive(role.is_active);
    setSelected(new Set(role.permissions.map((permission) => permission.id)));
    setSeeded(true);
  }, [mode, role, seeded]);

  const allIds = useMemo(() => {
    if (!catalog) {
      return [] as number[];
    }
    return Object.values(catalog).flat().map((permission) => permission.id);
  }, [catalog]);

  const isPermissionChecked = (id: number) => selected.has(id);

  const isModuleChecked = (module: string) => {
    const ids = (catalog?.[module] ?? []).map((permission) => permission.id);
    return ids.length > 0 && ids.every((id) => selected.has(id));
  };

  const allPermissionsChecked = allIds.length > 0 && allIds.every((id) => selected.has(id));

  const togglePermission = (id: number, checked: boolean) => {
    setSelected((previous) => {
      const next = new Set(previous);
      if (checked) {
        next.add(id);
      } else {
        next.delete(id);
      }
      return next;
    });
  };

  const toggleModule = (module: string, checked: boolean) => {
    const ids = (catalog?.[module] ?? []).map((permission) => permission.id);
    setSelected((previous) => {
      const next = new Set(previous);
      ids.forEach((id) => (checked ? next.add(id) : next.delete(id)));
      return next;
    });
  };

  const toggleAll = (checked: boolean) => {
    setSelected(checked ? new Set(allIds) : new Set());
  };

  const handleSubmit = async () => {
    setIsSubmitting(true);
    try {
      const values = {
        name,
        language,
        is_active: isActive,
        permissions: Array.from(selected),
      };
      if (mode === "edit" && roleId) {
        await updateRole(roleId, values);
      } else {
        await createRole(values);
      }
      router.push("/dashboard/users/roles");
    } catch {
      // Error toast is surfaced by the API layer / interceptor.
    } finally {
      setIsSubmitting(false);
    }
  };

  const handleCancel = () => {
    router.push("/dashboard/users/roles");
  };

  return (
    <RoleUpsertFormView
      mode={mode}
      catalog={catalog}
      isCatalogLoading={isCatalogLoading}
      name={name}
      language={language}
      isActive={isActive}
      isPermissionChecked={isPermissionChecked}
      isModuleChecked={isModuleChecked}
      allPermissionsChecked={allPermissionsChecked}
      isSubmitting={isSubmitting}
      onNameChange={setName}
      onLanguageChange={setLanguage}
      onActiveChange={setIsActive}
      onTogglePermission={togglePermission}
      onToggleModule={toggleModule}
      onToggleAll={toggleAll}
      onSubmit={handleSubmit}
      onCancel={handleCancel}
    />
  );
}
