"use client";

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

import { createPosition, deletePosition, updatePosition } from "@/lib/api/organization";
import type { Position } from "@/lib/api/organization";
import { StickyFormDialog } from "@/components/common/StickyFormDialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Switch } from "@/components/ui/switch";
import { Textarea } from "@/components/ui/textarea";
import { toast } from "@/components/ui/toast";
import { useAsyncAction } from "@/lib/hooks/useAsyncAction";

type PositionItem = Pick<Position, "id" | "code" | "name" | "description" | "enabled" | "sort">;

type Props = {
  positions: PositionItem[];
};

export function PositionsManager(props: Props) {
  const router = useRouter();
  const action = useAsyncAction();
  const [items, setItems] = useState<PositionItem[]>(() => props.positions);

  const sorted = useMemo(() => {
    const out = items.slice();
    out.sort((a, b) => (a.sort !== b.sort ? a.sort - b.sort : a.name.localeCompare(b.name, "zh-Hans-CN")));
    return out;
  }, [items]);

  const [createOpen, setCreateOpen] = useState(false);
  const [createCode, setCreateCode] = useState("");
  const [createName, setCreateName] = useState("");
  const [createDescription, setCreateDescription] = useState("");
  const [createEnabled, setCreateEnabled] = useState(true);
  const [createSort, setCreateSort] = useState(0);
  const [createReason, setCreateReason] = useState("");

  const [editOpen, setEditOpen] = useState(false);
  const [editId, setEditId] = useState<string | null>(null);
  const [editCode, setEditCode] = useState("");
  const [editName, setEditName] = useState("");
  const [editDescription, setEditDescription] = useState("");
  const [editEnabled, setEditEnabled] = useState(true);
  const [editSort, setEditSort] = useState(0);
  const [editReason, setEditReason] = useState("");

  const [deleteOpen, setDeleteOpen] = useState(false);
  const [deleteId, setDeleteId] = useState<string | null>(null);
  const [deleteReason, setDeleteReason] = useState("");

  async function submitCreate() {
    const code = createCode.trim();
    const name = createName.trim();
    const description = createDescription.trim();
    const reason = createReason.trim();

    const res = await action.run(
      () =>
        createPosition({
          code: code ? code : undefined,
          name,
          description: description ? description : undefined,
          enabled: createEnabled,
          sort: createSort,
          reason: reason ? reason : undefined,
        }),
      { fallbackErrorMessage: "创建失败" },
    );
    if (!res) return;
    const next: PositionItem = {
      id: res.id,
      code: code ? code : null,
      name,
      description: description ? description : null,
      enabled: createEnabled,
      sort: createSort,
    };
    setItems((prev) => [...prev, next]);
    setCreateOpen(false);
    toast.success("已创建岗位", { description: name });
    router.refresh();
  }

  async function submitUpdate() {
    if (!editId) return;
    const code = editCode.trim();
    const name = editName.trim();
    const description = editDescription.trim();
    const reason = editReason.trim();

    const ok = await action.run(
      () =>
        updatePosition(editId, {
          code: code ? code : null,
          name: name ? name : undefined,
          description: description ? description : null,
          enabled: editEnabled,
          sort: editSort,
          reason: reason ? reason : undefined,
        }),
      { fallbackErrorMessage: "保存失败" },
    );
    if (!ok) return;
    setItems((prev) =>
      prev.map((p) =>
        p.id === editId
          ? {
              ...p,
              code: code ? code : null,
              name: name ? name : p.name,
              description: description ? description : null,
              enabled: editEnabled,
              sort: editSort,
            }
          : p,
      ),
    );
    setEditOpen(false);
    toast.success("已保存岗位", { description: name });
    router.refresh();
  }

  async function submitDelete() {
    if (!deleteId) return;
    const id = deleteId;
    const reason = deleteReason.trim();
    const deletedName = items.find((p) => p.id === id)?.name ?? undefined;
    const ok = await action.run(
      () => deletePosition(id, { reason: reason ? reason : undefined }),
      { fallbackErrorMessage: "删除失败" },
    );
    if (!ok) return;
    setItems((prev) => prev.filter((p) => p.id !== id));
    setDeleteOpen(false);
    toast.success("已删除岗位", { description: deletedName });
    router.refresh();
  }

  return (
    <div className="space-y-3">
      <div className="flex flex-wrap items-center justify-between gap-2">
        <div className="text-sm text-muted-foreground">{items.length} 个岗位</div>

        <Button
          disabled={action.pending}
          onClick={() => {
            setCreateCode("");
            setCreateName("");
            setCreateDescription("");
            setCreateEnabled(true);
            setCreateSort(0);
            setCreateReason("");
            action.reset();
            setCreateOpen(true);
          }}
        >
          新增岗位
        </Button>
      </div>

      <div className="overflow-hidden rounded-xl border border-border bg-card">
        <table className="w-full table-auto">
          <thead className="bg-muted text-left text-xs text-muted-foreground">
            <tr>
              <th className="px-3 py-2">sort</th>
              <th className="px-3 py-2">code</th>
              <th className="px-3 py-2">名称</th>
              <th className="px-3 py-2">状态</th>
              <th className="px-3 py-2">描述</th>
              <th className="px-3 py-2 text-right">操作</th>
            </tr>
          </thead>
          <tbody className="text-sm">
            {sorted.length === 0 ? (
              <tr>
                <td className="px-4 py-10 text-center text-sm text-muted-foreground" colSpan={6}>
                  暂无岗位
                </td>
              </tr>
            ) : null}

            {sorted.map((p) => (
              <tr key={p.id} className="border-t border-border">
                <td className="px-3 py-2 text-xs text-muted-foreground">{p.sort}</td>
                <td className="px-3 py-2 font-mono text-xs">{p.code ?? "—"}</td>
                <td className="px-3 py-2 font-medium">{p.name}</td>
                <td className="px-3 py-2">
                  <span
                    className={
                      p.enabled
                        ? "rounded-md bg-secondary px-2 py-0.5 text-xs font-medium text-secondary-foreground"
                        : "rounded-md bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground"
                    }
                  >
                    {p.enabled ? "启用" : "停用"}
                  </span>
                </td>
                <td className="px-3 py-2 text-sm text-muted-foreground">{p.description ?? "—"}</td>
                <td className="px-3 py-2 text-right">
                  <div className="flex justify-end gap-2">
                    <Button
                      size="sm"
                      variant="outline"
                      disabled={action.pending}
                      onClick={() => {
                        action.reset();
                        setEditId(p.id);
                        setEditCode(p.code ?? "");
                        setEditName(p.name);
                        setEditDescription(p.description ?? "");
                        setEditEnabled(p.enabled);
                        setEditSort(p.sort);
                        setEditReason("");
                        setEditOpen(true);
                      }}
                    >
                      编辑
                    </Button>
                    <Button
                      size="sm"
                      variant="destructive"
                      disabled={action.pending}
                      onClick={() => {
                        action.reset();
                        setDeleteId(p.id);
                        setDeleteReason("");
                        setDeleteOpen(true);
                      }}
                    >
                      删除
                    </Button>
                  </div>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <StickyFormDialog
        open={createOpen}
        onOpenChange={(open) => {
          if (open) return;
          if (action.pending) return;
          setCreateOpen(false);
        }}
        title="新增岗位"
        description="code 可用于业务规则/筛选（可选）；enabled 为停用/启用开关。"
        error={action.error}
        footer={
          <div className="flex w-full flex-wrap items-center gap-2">
            <Button variant="outline" disabled={action.pending} onClick={() => setCreateOpen(false)}>
              取消
            </Button>
            <div className="ml-auto flex flex-wrap items-center gap-2">
              <Button disabled={action.pending || !createName.trim()} onClick={() => void submitCreate()}>
                {action.pending ? "提交中..." : "创建"}
              </Button>
            </div>
          </div>
        }
        contentClassName="max-w-xl"
      >
        <div className="grid grid-cols-2 gap-3">
          <div className="grid gap-2">
            <Label>code（可选）</Label>
            <Input value={createCode} onChange={(e) => setCreateCode(e.target.value)} placeholder="例如 librarian" />
          </div>
          <div className="grid gap-2">
            <Label>排序（sort）</Label>
            <Input value={String(createSort)} onChange={(e) => setCreateSort(Number(e.target.value))} inputMode="numeric" type="number" min={0} />
          </div>
        </div>

        <div className="grid gap-2">
          <Label>名称</Label>
          <Input value={createName} onChange={(e) => setCreateName(e.target.value)} placeholder="例如 图书管理员" />
        </div>

        <div className="grid gap-2">
          <Label>描述（可选）</Label>
          <Textarea value={createDescription} onChange={(e) => setCreateDescription(e.target.value)} placeholder="简要说明岗位职责…" />
        </div>

        <div className="flex items-center justify-between rounded-lg border border-border bg-muted px-3 py-2">
          <div className="space-y-0.5">
            <div className="text-sm font-medium">启用</div>
            <div className="text-xs text-muted-foreground">停用后不影响已有绑定，仅用于业务判断。</div>
          </div>
          <Switch checked={createEnabled} onCheckedChange={setCreateEnabled} />
        </div>

        <div className="grid gap-2">
          <Label>原因（可选，将写入审计）</Label>
          <Textarea value={createReason} onChange={(e) => setCreateReason(e.target.value)} placeholder="可填写工单号、变更原因、备注…" />
        </div>
      </StickyFormDialog>

      <StickyFormDialog
        open={editOpen}
        onOpenChange={(open) => {
          if (open) return;
          if (action.pending) return;
          setEditId(null);
          setEditOpen(false);
        }}
        title="编辑岗位"
        description="覆盖式更新；删除岗位会自动解绑用户。"
        error={action.error}
        footer={
          <div className="flex w-full flex-wrap items-center gap-2">
            <Button variant="outline" disabled={action.pending} onClick={() => setEditOpen(false)}>
              取消
            </Button>
            <div className="ml-auto flex flex-wrap items-center gap-2">
              <Button disabled={action.pending || !editName.trim()} onClick={() => void submitUpdate()}>
                {action.pending ? "保存中..." : "保存"}
              </Button>
            </div>
          </div>
        }
        contentClassName="max-w-xl"
      >
        <div className="grid grid-cols-2 gap-3">
          <div className="grid gap-2">
            <Label>code（可选）</Label>
            <Input value={editCode} onChange={(e) => setEditCode(e.target.value)} />
          </div>
          <div className="grid gap-2">
            <Label>排序（sort）</Label>
            <Input value={String(editSort)} onChange={(e) => setEditSort(Number(e.target.value))} inputMode="numeric" type="number" min={0} />
          </div>
        </div>

        <div className="grid gap-2">
          <Label>名称</Label>
          <Input value={editName} onChange={(e) => setEditName(e.target.value)} />
        </div>

        <div className="grid gap-2">
          <Label>描述（可选）</Label>
          <Textarea value={editDescription} onChange={(e) => setEditDescription(e.target.value)} />
        </div>

        <div className="flex items-center justify-between rounded-lg border border-border bg-muted px-3 py-2">
          <div className="space-y-0.5">
            <div className="text-sm font-medium">启用</div>
            <div className="text-xs text-muted-foreground">停用后不影响已有绑定，仅用于业务判断。</div>
          </div>
          <Switch checked={editEnabled} onCheckedChange={setEditEnabled} />
        </div>

        <div className="grid gap-2">
          <Label>原因（可选，将写入审计）</Label>
          <Textarea value={editReason} onChange={(e) => setEditReason(e.target.value)} placeholder="可填写工单号、变更原因、备注…" />
        </div>
      </StickyFormDialog>

      <StickyFormDialog
        open={deleteOpen}
        onOpenChange={(open) => {
          if (open) return;
          if (action.pending) return;
          setDeleteId(null);
          setDeleteOpen(false);
        }}
        title="删除岗位"
        description="若存在用户绑定，将自动解绑（MVP 行为）。"
        error={action.error}
        footer={
          <div className="flex w-full flex-wrap items-center gap-2">
            <Button variant="outline" disabled={action.pending} onClick={() => setDeleteOpen(false)}>
              取消
            </Button>
            <div className="ml-auto flex flex-wrap items-center gap-2">
              <Button variant="destructive" disabled={action.pending} onClick={() => void submitDelete()}>
                {action.pending ? "删除中..." : "确认删除"}
              </Button>
            </div>
          </div>
        }
        contentClassName="max-w-xl"
      >
        <div className="grid gap-2">
          <Label>原因（可选，将写入审计）</Label>
          <Textarea value={deleteReason} onChange={(e) => setDeleteReason(e.target.value)} placeholder="可填写工单号、删除原因、备注…" />
        </div>
      </StickyFormDialog>
    </div>
  );
}
