"use client";

import { useState } from "react";
import type { RankCategory, SeafarerDocType } from "@prisma/client";
import { AddRankButton, EditRankButton } from "./rank-form";
import { RankDocPanel } from "./rank-doc-panel";
import { RowActionsMenu, RowActionsItem, RowActionsDestructiveItem, RowActionsSeparator } from "@/components/ui/row-actions-menu";
import { DeleteConfirmDialog } from "@/components/ui/delete-confirm-dialog";
import { ConfirmDialog } from "@/components/ui/confirm-dialog";
import { deleteRank, toggleRankActive } from "./actions";
import { cn } from "@/lib/utils";

export type DocReqRow = {
  id: string;
  docType: SeafarerDocType;
  isMandatory: boolean;
  note: string | null;
};

export type RankRow = {
  id: string;
  code: string;
  name: string;
  description: string | null;
  category: RankCategory;
  isSeafarer: boolean;
  grantsLogin: boolean;
  isActive: boolean;
  parentId: string | null;
  docRequirements: DocReqRow[];
};

type TreeNode = RankRow & { children: TreeNode[] };

function buildTree(ranks: RankRow[]): TreeNode[] {
  const byId = new Map<string, TreeNode>();
  ranks.forEach((r) => byId.set(r.id, { ...r, children: [] }));
  const roots: TreeNode[] = [];
  byId.forEach((node) => {
    if (node.parentId && byId.has(node.parentId)) {
      byId.get(node.parentId)!.children.push(node);
    } else {
      roots.push(node);
    }
  });
  const sortRec = (nodes: TreeNode[]) => {
    nodes.sort((a, b) => a.name.localeCompare(b.name));
    nodes.forEach((n) => sortRec(n.children));
  };
  sortRec(roots);
  return roots;
}

function RankActionsMenu({ rank, allRanks }: { rank: RankRow; allRanks: RankRow[] }) {
  const [editOpen, setEditOpen] = useState(false);
  const [deleteOpen, setDeleteOpen] = useState(false);
  const [toggleOpen, setToggleOpen] = useState(false);

  return (
    <>
      <RowActionsMenu>
        <RowActionsItem onClick={() => setEditOpen(true)}>Edit</RowActionsItem>
        <RowActionsItem onClick={() => setToggleOpen(true)}>
          {rank.isActive ? "Deactivate" : "Activate"}
        </RowActionsItem>
        <RowActionsSeparator />
        <RowActionsDestructiveItem onClick={() => setDeleteOpen(true)}>Delete</RowActionsDestructiveItem>
      </RowActionsMenu>
      <EditRankButton rank={rank} allRanks={allRanks} open={editOpen} onOpenChange={setEditOpen} />
      <DeleteConfirmDialog
        open={deleteOpen}
        onOpenChange={setDeleteOpen}
        label={`${rank.code} — ${rank.name}`}
        onConfirm={() => deleteRank(rank.id)}
      />
      <ConfirmDialog
        open={toggleOpen}
        onOpenChange={setToggleOpen}
        title={rank.isActive ? `Deactivate ${rank.name}?` : `Activate ${rank.name}?`}
        description={
          rank.isActive
            ? `${rank.name} will be hidden from new requisitions and crew records.`
            : `${rank.name} will become available again.`
        }
        confirmLabel={rank.isActive ? "Deactivate" : "Activate"}
        onConfirm={() => toggleRankActive(rank.id)}
      />
    </>
  );
}

function RankRowView({
  node,
  depth,
  allRanks,
  selectedId,
  onSelect,
}: {
  node: TreeNode;
  depth: number;
  allRanks: RankRow[];
  selectedId: string | null;
  onSelect: (id: string) => void;
}) {
  const isSelected = node.id === selectedId;
  return (
    <>
      <div
        className={cn(
          "flex items-center gap-2 px-3 py-2 border-b border-neutral-100 last:border-0 cursor-pointer",
          isSelected ? "bg-primary-50" : "hover:bg-neutral-50"
        )}
        style={{ paddingLeft: 12 + depth * 20 }}
        onClick={() => onSelect(node.id)}
      >
        <span className="font-mono text-xs text-neutral-400 w-12 shrink-0">{node.code}</span>
        <span className={cn("text-sm flex-1", node.isActive ? "text-neutral-900" : "text-neutral-400 line-through")}>
          {node.name}
        </span>
        {node.grantsLogin && (
          <span className="rounded-full bg-primary-100 text-primary-700 px-2 py-0.5 text-xs font-medium">Login</span>
        )}
        {node.isSeafarer && (
          <span className="rounded-full bg-neutral-100 text-neutral-600 px-2 py-0.5 text-xs font-medium">Seafarer</span>
        )}
        <span className="rounded-full bg-neutral-100 text-neutral-500 px-2 py-0.5 text-xs">{node.category}</span>
        <span className="text-xs text-neutral-400 w-16 text-right shrink-0">
          {node.docRequirements.length} doc{node.docRequirements.length === 1 ? "" : "s"}
        </span>
        <div onClick={(e) => e.stopPropagation()}>
          <RankActionsMenu rank={node} allRanks={allRanks} />
        </div>
      </div>
      {node.children.map((child) => (
        <RankRowView
          key={child.id}
          node={child}
          depth={depth + 1}
          allRanks={allRanks}
          selectedId={selectedId}
          onSelect={onSelect}
        />
      ))}
    </>
  );
}

export function RanksManager({ ranks }: { ranks: RankRow[] }) {
  const tree = buildTree(ranks);
  const [selectedId, setSelectedId] = useState<string | null>(ranks[0]?.id ?? null);
  const selected = ranks.find((r) => r.id === selectedId) ?? null;

  return (
    <div>
      <div className="mb-6 flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-semibold text-neutral-900">Ranks &amp; Documents</h1>
          <p className="text-sm text-neutral-500 mt-0.5">
            {ranks.length} ranks · the crew org chart and the documents each rank must hold
          </p>
        </div>
        <AddRankButton allRanks={ranks} />
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-5 gap-6">
        {/* Rank hierarchy card */}
        <div className="lg:col-span-3 rounded-lg border border-neutral-200 bg-white overflow-hidden">
          <div className="px-4 py-3 border-b border-neutral-200 bg-neutral-50">
            <h2 className="text-sm font-semibold text-neutral-900">Rank hierarchy</h2>
            <p className="text-xs text-neutral-500 mt-0.5">
              The org chart. <span className="text-primary-700 font-medium">Login</span> ranks (PM, Assistant PM, Site
              In-charge) map to a portal account; all others are crew records.
            </p>
          </div>
          {tree.length === 0 ? (
            <p className="px-4 py-12 text-center text-neutral-400">No ranks yet. Add a top-level rank to begin.</p>
          ) : (
            <div>
              {tree.map((node) => (
                <RankRowView
                  key={node.id}
                  node={node}
                  depth={0}
                  allRanks={ranks}
                  selectedId={selectedId}
                  onSelect={setSelectedId}
                />
              ))}
            </div>
          )}
        </div>

        {/* Required documents card */}
        <div className="lg:col-span-2">
          <RankDocPanel rank={selected} />
        </div>
      </div>
    </div>
  );
}
