"use client";

import { useEffect, useRef, useState, type FormEvent } from "react";
import { Eye, MoreVertical, Pencil, Plus, RefreshCw, Search, Trash2 } from "lucide-react";
import { toast } from "react-hot-toast";
import { Panel } from "@/components/shared/panel";
import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import {
  fetchOrganization,
  fetchOrganizations,
  removeOrganization as removeOrganizationRequest,
  saveOrganization as saveOrganizationRequest,
} from "./client-api";
import { OrganizationDetailsDialog } from "./organization-details-dialog";
import { OrganizationEditorDialog } from "./organization-editor-dialog";
import type { OrganizationRecord, OrganizationWriteValues } from "./types";

function messageFrom(error: unknown, fallback: string) {
  return error instanceof Error && error.message.trim() ? error.message : fallback;
}

export function OrganizationsView() {
  const [organizations, setOrganizations] = useState<OrganizationRecord[]>([]);
  const [codeInput, setCodeInput] = useState("");
  const [appliedCode, setAppliedCode] = useState("");
  const [loading, setLoading] = useState(true);
  const [loadError, setLoadError] = useState("");
  const [refreshVersion, setRefreshVersion] = useState(0);
  const [selectedOrganization, setSelectedOrganization] = useState<OrganizationRecord | null>(null);
  const [detailLoading, setDetailLoading] = useState(false);
  const [detailError, setDetailError] = useState("");
  const [editingOrganization, setEditingOrganization] = useState<OrganizationRecord | null>(null);
  const [editorOpen, setEditorOpen] = useState(false);
  const [organizationToDelete, setOrganizationToDelete] = useState<OrganizationRecord | null>(null);
  const [deleting, setDeleting] = useState(false);
  const detailRequest = useRef(0);

  useEffect(() => {
    let cancelled = false;
    async function load() {
      setLoading(true);
      setLoadError("");
      try {
        const result = await fetchOrganizations(appliedCode || undefined);
        if (cancelled) return;
        setOrganizations(result.records);
      } catch (error) {
        if (cancelled) return;
        setLoadError(messageFrom(error, "Unable to load organizations. Please try again."));
      } finally {
        if (!cancelled) setLoading(false);
      }
    }
    void load();
    return () => {
      cancelled = true;
    };
  }, [appliedCode, refreshVersion]);

  async function openDetails(organization: OrganizationRecord) {
    const requestId = ++detailRequest.current;
    setSelectedOrganization(organization);
    setDetailLoading(true);
    setDetailError("");
    try {
      const result = await fetchOrganization(organization.id);
      if (detailRequest.current !== requestId) return;
      setSelectedOrganization(result.organization);
      setOrganizations((current) => current.map((item) =>
        item.id === result.organization.id ? result.organization : item,
      ));
    } catch (error) {
      if (detailRequest.current !== requestId) return;
      setDetailError(messageFrom(error, "Unable to load organization details. Please try again."));
    } finally {
      if (detailRequest.current === requestId) setDetailLoading(false);
    }
  }

  function closeDetails(open: boolean) {
    if (open) return;
    detailRequest.current += 1;
    setSelectedOrganization(null);
    setDetailLoading(false);
    setDetailError("");
  }

  function refreshList() {
    setRefreshVersion((version) => version + 1);
  }

  function applyCodeFilter(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const nextCode = codeInput.trim();
    if (nextCode === appliedCode) refreshList();
    else setAppliedCode(nextCode);
  }

  function clearCodeFilter() {
    setCodeInput("");
    if (!appliedCode) refreshList();
    else setAppliedCode("");
  }

  function openCreateDialog() {
    setEditingOrganization(null);
    setEditorOpen(true);
  }

  function openEditDialog(organization: OrganizationRecord) {
    setEditingOrganization(organization);
    setEditorOpen(true);
  }

  async function saveOrganization(values: OrganizationWriteValues) {
    if (!values.code.trim()) {
      toast.error("Organization code is required.");
      return false;
    }
    if (!values.name.trim()) {
      toast.error("Organization name is required.");
      return false;
    }

    try {
      const result = await saveOrganizationRequest(editingOrganization?.id, values);
      const savedOrganization = result.organization;
      const isCreating = !editingOrganization;
      const matchesAppliedCode = !appliedCode || savedOrganization.code.toLowerCase() === appliedCode.toLowerCase();

      setOrganizations((current) => {
        const existing = current.some((item) => item.id === savedOrganization.id);
        if (existing) {
          return current
            .map((item) => item.id === savedOrganization.id ? savedOrganization : item)
            .filter((item) => !appliedCode || item.code.toLowerCase() === appliedCode.toLowerCase());
        }
        return isCreating || matchesAppliedCode ? [savedOrganization, ...current] : current;
      });
      setLoadError("");
      if (isCreating) {
        setCodeInput("");
        setAppliedCode("");
      }
      setSelectedOrganization((current) => current?.id === savedOrganization.id ? savedOrganization : current);
      toast.success(result.message || (editingOrganization ? "Organization updated successfully." : "Organization created successfully."));
      return true;
    } catch (error) {
      toast.error(messageFrom(error, "Unable to save the organization. Please try again."));
      return false;
    }
  }

  async function confirmDeleteOrganization() {
    if (!organizationToDelete || deleting) return;
    const target = organizationToDelete;
    setDeleting(true);
    try {
      const message = await removeOrganizationRequest(target.id);
      setOrganizations((current) => current.filter((item) => item.id !== target.id));
      if (selectedOrganization?.id === target.id) closeDetails(false);
      setOrganizationToDelete(null);
      toast.success(message || "Organization deleted successfully.");
    } catch (error) {
      toast.error(messageFrom(error, "Unable to delete the organization. Please try again."));
    } finally {
      setDeleting(false);
    }
  }

  return (
    <>
      <Panel className="overflow-hidden p-0">
        <div className="border-b border-border px-5 py-4 md:px-6">
          <div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
            <div>
              <h2 className="text-lg font-semibold">Organizations ({organizations.length})</h2>
              <p className="mt-1 text-sm text-muted-foreground">Manage and monitor organizations within your tenant.</p>
            </div>
            <span className="inline-flex w-fit items-center rounded-full border border-primary/25 bg-primary/10 px-3 py-1 text-xs font-medium text-primary">
              Tenant-scoped
            </span>
          </div>
        </div>

        <div className="flex flex-col gap-3 px-5 py-4 sm:flex-row sm:items-center sm:justify-between md:px-6">
          <form className="flex w-full flex-col gap-2 sm:max-w-xl sm:flex-row" onSubmit={applyCodeFilter}>
            <label className="relative min-w-0 flex-1">
              <span className="sr-only">Filter by exact organization code</span>
              <Search className="pointer-events-none absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" aria-hidden="true" />
              <Input
                className="pl-9"
                value={codeInput}
                onChange={(event) => setCodeInput(event.target.value)}
                placeholder="Filter by exact organization code"
              />
            </label>
            <Button type="submit" variant="outline" disabled={loading}>
              Filter
            </Button>
            {appliedCode && (
              <Button type="button" variant="ghost" disabled={loading} onClick={clearCodeFilter}>
                Clear
              </Button>
            )}
          </form>
          <Button onClick={openCreateDialog} disabled={loading}>
            <Plus aria-hidden="true" />
            Add Organization
          </Button>
        </div>

        <p className="px-5 pb-4 text-xs text-muted-foreground md:px-6">
          The list endpoint supports an exact code filter and returns the tenant-scoped list without pagination.
        </p>

        {loadError && (
          <div role="alert" className="mx-5 mb-4 flex flex-wrap items-center justify-between gap-3 rounded-lg border border-destructive/40 bg-destructive/5 px-4 py-3 text-destructive md:mx-6">
            <span>{loadError}</span>
            <Button variant="outline" size="sm" onClick={refreshList}>
              <RefreshCw aria-hidden="true" />
              Retry
            </Button>
          </div>
        )}

        <div className="max-w-full overflow-x-auto px-5 md:px-6">
          <table className="w-full min-w-[760px] border-collapse text-sm">
            <thead>
              <tr>
                {["Code", "Name", "Status", "Phone", "Email", "Actions"].map((heading) => (
                  <th key={heading} scope="col" className="border border-border px-4 py-3 text-left text-xs font-medium text-muted-foreground">
                    {heading}
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {loading && organizations.length === 0 ? (
                <tr><td colSpan={6} className="border border-border px-4 py-8 text-center text-muted-foreground">Loading organizations…</td></tr>
              ) : loadError && organizations.length === 0 ? (
                <tr><td colSpan={6} className="border border-border px-4 py-8 text-center text-muted-foreground">Organization list is unavailable.</td></tr>
              ) : organizations.length === 0 ? (
                <tr><td colSpan={6} className="border border-border px-4 py-8 text-center text-muted-foreground">No organizations found.</td></tr>
              ) : organizations.map((organization) => (
                <tr key={organization.id} className="hover:bg-muted/30">
                  <td className="whitespace-nowrap border border-border px-4 py-4 font-mono text-xs">{organization.code}</td>
                  <td className="border border-border px-4 py-4 font-medium">{organization.name}</td>
                  <td className="border border-border px-4 py-4">
                    <span className={`inline-flex rounded-full px-2.5 py-1 text-xs font-medium ${organization.active === true ? "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400" : "bg-muted text-muted-foreground"}`}>
                      {organization.active === true ? "Active" : organization.active === false ? "Inactive" : "—"}
                    </span>
                  </td>
                  <td className="whitespace-nowrap border border-border px-4 py-4">{organization.phone || "—"}</td>
                  <td className="border border-border px-4 py-4">{organization.email || "—"}</td>
                  <td className="border border-border px-4 py-3">
                    <DropdownMenu>
                      <DropdownMenuTrigger asChild>
                        <Button
                          variant="ghost"
                          size="icon-sm"
                          aria-label={`Actions for ${organization.name}`}
                          disabled={deleting}
                        >
                          <MoreVertical aria-hidden="true" />
                        </Button>
                      </DropdownMenuTrigger>
                      <DropdownMenuContent align="end">
                        <DropdownMenuItem onSelect={() => void openDetails(organization)}>
                          <Eye aria-hidden="true" />
                          View details
                        </DropdownMenuItem>
                        <DropdownMenuItem onSelect={() => openEditDialog(organization)}>
                          <Pencil aria-hidden="true" />
                          Edit
                        </DropdownMenuItem>
                        <DropdownMenuItem
                          variant="destructive"
                          onSelect={() => setOrganizationToDelete(organization)}
                        >
                          <Trash2 aria-hidden="true" />
                          Delete
                        </DropdownMenuItem>
                      </DropdownMenuContent>
                    </DropdownMenu>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        <div className="mt-4 border-t border-border px-5 py-4 text-sm text-muted-foreground md:px-6">
          {appliedCode
            ? `Showing ${organizations.length} organizations for code ${appliedCode}`
            : `Showing ${organizations.length} organizations`}
        </div>
      </Panel>

      <OrganizationDetailsDialog
        organization={selectedOrganization}
        loading={detailLoading}
        error={detailError}
        onRetry={() => selectedOrganization && void openDetails(selectedOrganization)}
        onOpenChange={closeDetails}
      />
      {editorOpen && (
        <OrganizationEditorDialog
          organization={editingOrganization}
          onOpenChange={setEditorOpen}
          onSave={saveOrganization}
        />
      )}
      <Dialog
        open={Boolean(organizationToDelete)}
        onOpenChange={(open) => {
          if (!open && !deleting) setOrganizationToDelete(null);
        }}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Delete organization?</DialogTitle>
            <DialogDescription>
              {organizationToDelete
                ? `“${organizationToDelete.name}” will be deleted. This action cannot be undone.`
                : "This organization will be deleted. This action cannot be undone."}
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button type="button" variant="outline" disabled={deleting} onClick={() => setOrganizationToDelete(null)}>
              Cancel
            </Button>
            <Button type="button" variant="destructive" disabled={deleting} onClick={() => void confirmDeleteOrganization()}>
              {deleting ? "Deleting…" : "Delete Organization"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}
