"use client";

import { useEffect, useState } from "react";
import {
  Autocomplete,
  Button,
  Chip,
  EmptyState,
  Input,
  Label,
  ListBox,
  Modal,
  SearchField,
  Select,
  Spinner,
  Table,
  TextField,
  useFilter,
} from "@heroui/react";
import { CreditCard, Pencil, ArrowRotateRight } from "@gravity-ui/icons";
import { api, type IdTag, type UserRow } from "@/lib/api";
import { useSession } from "@/lib/auth-client";
import dayjs from "@/lib/dayjs";

type CreateForm = {
  name: string;
  email: string;
  username: string;
  password: string;
  role: string;
};

type EditForm = {
  name: string;
  username: string;
  role: string;
};

const emptyCreate: CreateForm = { name: "", email: "", username: "", password: "", role: "user" };

const ROLE_OPTIONS = [
  { key: "user", label: "用户" },
  { key: "admin", label: "管理员" },
];

const statusColorMap: Record<string, "success" | "danger" | "warning"> = {
  Accepted: "success",
  Blocked: "danger",
  Expired: "warning",
  Invalid: "danger",
  ConcurrentTx: "warning",
};

function generateIdTag(): string {
  const chars = "0123456789ABCDEF";
  let result = "";
  for (let i = 0; i < 8; i++) {
    result += chars[Math.floor(Math.random() * chars.length)];
  }
  return result;
}

function fenToYuan(fen: number): string {
  return (fen / 100).toFixed(2);
}

function FreeTagBinder({
  freeTags,
  selected,
  onSelect,
  onBind,
  binding,
}: {
  freeTags: IdTag[];
  selected: string;
  onSelect: (v: string) => void;
  onBind: () => void;
  binding: boolean;
}) {
  const { contains } = useFilter({ sensitivity: "base" });
  return (
    <div className="flex items-end gap-2">
      <div className="flex flex-1 flex-col gap-1">
        <Label className="text-sm font-medium">从无主卡中绑定</Label>
        <Autocomplete
          fullWidth
          placeholder={freeTags.length === 0 ? "暂无无主卡" : "搜索卡号"}
          selectionMode="single"
          isDisabled={freeTags.length === 0}
          value={selected || null}
          onChange={(key) => onSelect(key ? String(key) : "")}
        >
          <Autocomplete.Trigger>
            <Autocomplete.Value>
              {({ isPlaceholder, state }: any) => {
                if (isPlaceholder || !state.selectedItems?.length)
                  return (
                    <span className="text-muted">
                      {freeTags.length === 0 ? "暂无无主卡" : "选择卡号"}
                    </span>
                  );
                const tag = freeTags.find((t) => t.idTag === state.selectedItems[0]?.key);
                return tag ? <span className="font-mono">{tag.idTag}</span> : null;
              }}
            </Autocomplete.Value>
            <Autocomplete.ClearButton />
            <Autocomplete.Indicator />
          </Autocomplete.Trigger>
          <Autocomplete.Popover>
            <Autocomplete.Filter filter={contains}>
              <SearchField autoFocus name="freeTagSearch" variant="secondary">
                <SearchField.Group>
                  <SearchField.SearchIcon />
                  <SearchField.Input placeholder="搜索卡号" />
                  <SearchField.ClearButton />
                </SearchField.Group>
              </SearchField>
              <ListBox renderEmptyState={() => <EmptyState>无匹配卡号</EmptyState>}>
                {freeTags.map((t) => (
                  <ListBox.Item key={t.idTag} id={t.idTag} textValue={t.idTag}>
                    <span className="font-mono">{t.idTag}</span>
                    <span className="ml-2 text-xs text-muted">¥{(t.balance / 100).toFixed(2)}</span>
                    <ListBox.ItemIndicator />
                  </ListBox.Item>
                ))}
              </ListBox>
            </Autocomplete.Filter>
          </Autocomplete.Popover>
        </Autocomplete>
      </div>
      <Button isDisabled={binding || !selected} onPress={onBind}>
        {binding ? <Spinner size="sm" /> : "绑定"}
      </Button>
    </div>
  );
}

export default function UsersPage() {
  const { data: session } = useSession();
  const currentUserId = session?.user?.id;

  const [users, setUsers] = useState<UserRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [refreshing, setRefreshing] = useState(false);
  const [updating, setUpdating] = useState<string | null>(null);

  const [createForm, setCreateForm] = useState<CreateForm>(emptyCreate);
  const [editTarget, setEditTarget] = useState<UserRow | null>(null);
  const [editForm, setEditForm] = useState<EditForm>({ name: "", username: "", role: "user" });
  const [saving, setSaving] = useState(false);
  const [cardsUser, setCardsUser] = useState<UserRow | null>(null);
  const [userTags, setUserTags] = useState<IdTag[]>([]);
  const [tagsLoading, setTagsLoading] = useState(false);
  const [newTagId, setNewTagId] = useState("");
  const [creatingTag, setCreatingTag] = useState(false);
  const [unlinkingTag, setUnlinkingTag] = useState<string | null>(null);
  const [deletingTag, setDeletingTag] = useState<string | null>(null);
  const [freeTags, setFreeTags] = useState<IdTag[]>([]);
  const [selectedFreeTag, setSelectedFreeTag] = useState("");
  const [bindingTag, setBindingTag] = useState(false);

  const load = async () => {
    setLoading(true);
    try {
      setUsers(await api.users.list());
    } catch {
      // possibly not admin — show empty
    } finally {
      setLoading(false);
    }
  };

  const handleRefresh = async () => {
    setRefreshing(true);
    try {
      setUsers(await api.users.list());
    } catch {
      // ignore
    } finally {
      setRefreshing(false);
    }
  };

  useEffect(() => {
    load();
  }, []);

  const openEdit = (u: UserRow) => {
    setEditTarget(u);
    setEditForm({ name: u.name ?? "", username: u.username ?? "", role: u.role ?? "user" });
  };

  const handleCreate = async () => {
    setSaving(true);
    try {
      await api.users.create({
        name: createForm.name,
        email: createForm.email,
        password: createForm.password,
        username: createForm.username || undefined,
        role: createForm.role,
      });
      setCreateForm(emptyCreate);
      await load();
    } finally {
      setSaving(false);
    }
  };

  const handleEdit = async () => {
    if (!editTarget) return;
    setSaving(true);
    try {
      await api.users.update(editTarget.id, {
        name: editForm.name || undefined,
        username: editForm.username || null,
        role: editForm.role,
      });
      await load();
    } finally {
      setSaving(false);
    }
  };

  const toggleBan = async (u: UserRow) => {
    setUpdating(u.id);
    try {
      await api.users.update(u.id, {
        banned: !u.banned,
        banReason: u.banned ? null : "管理员封禁",
      });
      await load();
    } finally {
      setUpdating(null);
    }
  };

  const loadUserTags = async (userId: string) => {
    setTagsLoading(true);
    try {
      const all = await api.idTags.list();
      setUserTags(all.filter((t) => t.userId === userId));
      setFreeTags(all.filter((t) => !t.userId));
    } finally {
      setTagsLoading(false);
    }
  };

  const openCardsModal = (u: UserRow) => {
    setCardsUser(u);
    setSelectedFreeTag("");
    setUserTags([]);
    setFreeTags([]);
    void loadUserTags(u.id);
  };

  const handleCreateTag = async () => {
    if (!cardsUser || !newTagId) return;
    setCreatingTag(true);
    try {
      await api.idTags.create({ idTag: newTagId, userId: cardsUser.id });
      setNewTagId(generateIdTag());
      await loadUserTags(cardsUser.id);
    } finally {
      setCreatingTag(false);
    }
  };

  const handleUnlinkTag = async (idTag: string) => {
    if (!cardsUser) return;
    setUnlinkingTag(idTag);
    try {
      await api.idTags.update(idTag, { userId: null });
      await loadUserTags(cardsUser.id);
    } finally {
      setUnlinkingTag(null);
    }
  };

  const handleBindFreeTag = async () => {
    if (!cardsUser || !selectedFreeTag) return;
    setBindingTag(true);
    try {
      await api.idTags.update(selectedFreeTag, { userId: cardsUser.id });
      setSelectedFreeTag("");
      await loadUserTags(cardsUser.id);
    } finally {
      setBindingTag(false);
    }
  };

  const handleDeleteTag = async (idTag: string) => {
    if (!cardsUser) return;
    setDeletingTag(idTag);
    try {
      await api.idTags.delete(idTag);
      await loadUserTags(cardsUser.id);
    } finally {
      setDeletingTag(null);
    }
  };

  const isEditingSelf = editTarget?.id === currentUserId;

  return (
    <div className="space-y-4">
      <div className="flex flex-wrap items-start justify-between gap-3">
        <div>
          <h1 className="text-xl font-semibold text-foreground">用户管理</h1>
          <p className="mt-0.5 text-sm text-muted">共 {users.length} 位用户（仅管理员可见）</p>
        </div>
        <div className="flex items-center gap-2">
          <Button isIconOnly size="sm" variant="ghost" isDisabled={refreshing} onPress={handleRefresh} aria-label="刷新">
            <ArrowRotateRight className={`size-4 ${refreshing ? "animate-spin" : ""}`} />
          </Button>
          <Modal>
          <Button variant="secondary" onPress={() => setCreateForm(emptyCreate)}>
            新增用户
          </Button>
          <Modal.Backdrop>
            <Modal.Container scroll="outside">
              <Modal.Dialog className="sm:max-w-105">
                <Modal.CloseTrigger />
                <Modal.Header>
                  <Modal.Heading>新增用户</Modal.Heading>
                </Modal.Header>
                <Modal.Body className="space-y-3">
                  <TextField fullWidth>
                    <Label className="text-sm font-medium">显示名称</Label>
                    <Input
                      placeholder="对外显示的名称"
                      value={createForm.name}
                      onChange={(e) => setCreateForm({ ...createForm, name: e.target.value })}
                    />
                  </TextField>
                  <TextField fullWidth>
                    <Label className="text-sm font-medium">邮箱</Label>
                    <Input
                      type="email"
                      placeholder="user@example.com"
                      value={createForm.email}
                      onChange={(e) => setCreateForm({ ...createForm, email: e.target.value })}
                    />
                  </TextField>
                  <TextField fullWidth>
                    <Label className="text-sm font-medium">登录名</Label>
                    <Input
                      placeholder="创建账号的登录名"
                      value={createForm.username}
                      onChange={(e) => setCreateForm({ ...createForm, username: e.target.value })}
                    />
                  </TextField>
                  <TextField fullWidth>
                    <Label className="text-sm font-medium">密码</Label>
                    <Input
                      autoComplete="new-password"
                      type="password"
                      placeholder="创建账号的密码"
                      value={createForm.password}
                      onChange={(e) => setCreateForm({ ...createForm, password: e.target.value })}
                    />
                  </TextField>
                  <div className="flex flex-col gap-1">
                    <Label className="text-sm font-medium">角色</Label>
                    <Select
                      fullWidth
                      selectedKey={createForm.role}
                      onSelectionChange={(key) =>
                        setCreateForm({ ...createForm, role: String(key) })
                      }
                    >
                      <Select.Trigger>
                        <Select.Value />
                        <Select.Indicator />
                      </Select.Trigger>
                      <Select.Popover>
                        <ListBox>
                          {ROLE_OPTIONS.map((r) => (
                            <ListBox.Item key={r.key} id={r.key}>
                              {r.label}
                            </ListBox.Item>
                          ))}
                        </ListBox>
                      </Select.Popover>
                    </Select>
                  </div>
                </Modal.Body>
                <Modal.Footer className="flex justify-end gap-2">
                  <Button slot="close" variant="ghost">
                    取消
                  </Button>
                  <Button
                    isDisabled={
                      saving || !createForm.name || !createForm.email || !createForm.password
                    }
                    slot="close"
                    onPress={handleCreate}
                  >
                    {saving ? <Spinner size="sm" /> : "创建"}
                  </Button>
                </Modal.Footer>
              </Modal.Dialog>
            </Modal.Container>
          </Modal.Backdrop>
        </Modal>
        </div>
      </div>

      <Table>
        <Table.ScrollContainer>
          <Table.Content aria-label="用户列表" className="min-w-187.5">
            <Table.Header>
              <Table.Column isRowHeader>用户</Table.Column>
              <Table.Column>邮箱</Table.Column>
              <Table.Column>登录名</Table.Column>
              <Table.Column>角色</Table.Column>
              <Table.Column>状态</Table.Column>
              <Table.Column>注册时间</Table.Column>
              <Table.Column className="text-end">操作</Table.Column>
            </Table.Header>
            <Table.Body
              renderEmptyState={() => (
                <div className="py-8 text-center text-sm text-muted">
                  {loading ? "加载中…" : "暂无用户或无权限"}
                </div>
              )}
            >
              {users.map((u) => (
                <Table.Row key={u.id} id={u.id}>
                  <Table.Cell>
                    <div className="font-medium">{u.name ?? "—"}</div>
                  </Table.Cell>
                  <Table.Cell className="text-sm">{u.email}</Table.Cell>
                  <Table.Cell className="font-mono text-sm">{u.username ?? "—"}</Table.Cell>
                  <Table.Cell>
                    <Chip
                      color={u.role === "admin" ? "warning" : "success"}
                      size="sm"
                      variant="soft"
                    >
                      {u.role === "admin" ? "管理员" : "用户"}
                    </Chip>
                  </Table.Cell>
                  <Table.Cell>
                    {u.banned ? (
                      <Chip color="danger" size="sm" variant="soft">
                        已封禁
                      </Chip>
                    ) : (
                      <Chip color="success" size="sm" variant="soft">
                        正常
                      </Chip>
                    )}
                  </Table.Cell>
                  <Table.Cell className="text-sm">
                    {dayjs(u.createdAt).format("YYYY/M/D HH:mm:ss")}
                  </Table.Cell>
                  <Table.Cell>
                    <div className="flex justify-end gap-1">
                      {/* Edit button */}
                      <Modal>
                        <Button isIconOnly size="sm" variant="tertiary" onPress={() => openEdit(u)}>
                          <Pencil className="size-4" />
                        </Button>
                        <Modal.Backdrop>
                          <Modal.Container scroll="outside">
                            <Modal.Dialog className="sm:max-w-105">
                              <Modal.CloseTrigger />
                              <Modal.Header>
                                <Modal.Heading>编辑用户</Modal.Heading>
                              </Modal.Header>
                              <Modal.Body className="space-y-3">
                                <TextField fullWidth>
                                  <Label className="text-sm font-medium">姓名</Label>
                                  <Input
                                    placeholder="用户姓名"
                                    value={editForm.name}
                                    onChange={(e) =>
                                      setEditForm({ ...editForm, name: e.target.value })
                                    }
                                  />
                                </TextField>
                                <TextField fullWidth>
                                  <Label className="text-sm font-medium">登录名</Label>
                                  <Input
                                    placeholder="用户登录名"
                                    value={editForm.username}
                                    onChange={(e) =>
                                      setEditForm({ ...editForm, username: e.target.value })
                                    }
                                  />
                                </TextField>
                                {!isEditingSelf && (
                                  <div className="flex flex-col gap-1">
                                    <Label className="text-sm font-medium">角色</Label>
                                    <Select
                                      fullWidth
                                      selectedKey={editForm.role}
                                      onSelectionChange={(key) =>
                                        setEditForm({ ...editForm, role: String(key) })
                                      }
                                    >
                                      <Select.Trigger>
                                        <Select.Value />
                                        <Select.Indicator />
                                      </Select.Trigger>
                                      <Select.Popover>
                                        <ListBox>
                                          {ROLE_OPTIONS.map((r) => (
                                            <ListBox.Item key={r.key} id={r.key}>
                                              {r.label}
                                            </ListBox.Item>
                                          ))}
                                        </ListBox>
                                      </Select.Popover>
                                    </Select>
                                  </div>
                                )}
                              </Modal.Body>
                              <Modal.Footer className="flex justify-end gap-2">
                                <Button slot="close" variant="ghost">
                                  取消
                                </Button>
                                <Button isDisabled={saving} slot="close" onPress={handleEdit}>
                                  {saving ? <Spinner size="sm" /> : "保存"}
                                </Button>
                              </Modal.Footer>
                            </Modal.Dialog>
                          </Modal.Container>
                        </Modal.Backdrop>
                      </Modal>
                      {/* Cards management */}
                      <Modal>
                        <Button
                          isIconOnly
                          size="sm"
                          variant="tertiary"
                          onPress={() => openCardsModal(u)}
                        >
                          <CreditCard className="size-4" />
                        </Button>
                        <Modal.Backdrop>
                          <Modal.Container scroll="outside">
                            <Modal.Dialog className="sm:max-w-2xl">
                              <Modal.CloseTrigger />
                              <Modal.Header>
                                <Modal.Heading>
                                  {cardsUser
                                    ? `${cardsUser.name ?? cardsUser.username ?? cardsUser.email} 的储值卡`
                                    : "储值卡管理"}
                                </Modal.Heading>
                              </Modal.Header>
                              <Modal.Body className="space-y-4">
                                <div className="flex items-end gap-2">
                                  <TextField fullWidth>
                                    <div className="flex items-center justify-between">
                                      <Label className="text-sm font-medium">新建储值卡</Label>
                                      <button
                                        type="button"
                                        className="text-xs text-accent hover:underline"
                                        onClick={() => setNewTagId(generateIdTag())}
                                      >
                                        随机生成
                                      </button>
                                    </div>
                                    <Input
                                      className="font-mono"
                                      placeholder="e.g. A1B2C3D4"
                                      value={newTagId}
                                      onChange={(e) => setNewTagId(e.target.value)}
                                    />
                                  </TextField>
                                  <Button
                                    isDisabled={creatingTag || !newTagId}
                                    onPress={handleCreateTag}
                                  >
                                    {creatingTag ? <Spinner size="sm" /> : "创建并绑定"}
                                  </Button>
                                </div>
                                <FreeTagBinder
                                  freeTags={freeTags}
                                  selected={selectedFreeTag}
                                  onSelect={setSelectedFreeTag}
                                  onBind={handleBindFreeTag}
                                  binding={bindingTag}
                                />
                                {tagsLoading ? (
                                  <div className="flex justify-center py-6">
                                    <Spinner />
                                  </div>
                                ) : userTags.length === 0 ? (
                                  <p className="py-4 text-center text-sm text-muted">
                                    该用户暂无储值卡
                                  </p>
                                ) : (
                                  <Table>
                                    <Table.ScrollContainer>
                                      <Table.Content aria-label="用户储值卡">
                                        <Table.Header>
                                          <Table.Column isRowHeader>卡号</Table.Column>
                                          <Table.Column>状态</Table.Column>
                                          <Table.Column>余额</Table.Column>
                                          <Table.Column className="text-end">操作</Table.Column>
                                        </Table.Header>
                                        <Table.Body>
                                          {userTags.map((tag) => (
                                            <Table.Row key={tag.idTag} id={tag.idTag}>
                                              <Table.Cell className="font-mono font-medium">
                                                {tag.idTag}
                                              </Table.Cell>
                                              <Table.Cell>
                                                <Chip
                                                  color={statusColorMap[tag.status] ?? "warning"}
                                                  size="sm"
                                                  variant="soft"
                                                >
                                                  {tag.status}
                                                </Chip>
                                              </Table.Cell>
                                              <Table.Cell className="font-mono">
                                                ¥{fenToYuan(tag.balance)}
                                              </Table.Cell>
                                              <Table.Cell>
                                                <div className="flex justify-end gap-1">
                                                  <Button
                                                    size="sm"
                                                    variant="tertiary"
                                                    isDisabled={
                                                      unlinkingTag === tag.idTag ||
                                                      deletingTag === tag.idTag
                                                    }
                                                    onPress={() => handleUnlinkTag(tag.idTag)}
                                                  >
                                                    {unlinkingTag === tag.idTag ? (
                                                      <Spinner size="sm" />
                                                    ) : (
                                                      "解绑"
                                                    )}
                                                  </Button>
                                                  <Button
                                                    size="sm"
                                                    variant="danger-soft"
                                                    isDisabled={
                                                      deletingTag === tag.idTag ||
                                                      unlinkingTag === tag.idTag
                                                    }
                                                    onPress={() => handleDeleteTag(tag.idTag)}
                                                  >
                                                    {deletingTag === tag.idTag ? (
                                                      <Spinner size="sm" />
                                                    ) : (
                                                      "删除"
                                                    )}
                                                  </Button>
                                                </div>
                                              </Table.Cell>
                                            </Table.Row>
                                          ))}
                                        </Table.Body>
                                      </Table.Content>
                                    </Table.ScrollContainer>
                                  </Table>
                                )}
                              </Modal.Body>
                              <Modal.Footer className="flex justify-end">
                                <Button slot="close" variant="ghost">
                                  关闭
                                </Button>
                              </Modal.Footer>
                            </Modal.Dialog>
                          </Modal.Container>
                        </Modal.Backdrop>
                      </Modal>
                      {/* Ban / Unban button — disabled for current account */}
                      <Button
                        isDisabled={u.id === currentUserId || updating === u.id}
                        size="sm"
                        variant={u.banned ? "tertiary" : "danger-soft"}
                        onPress={() => toggleBan(u)}
                      >
                        {updating === u.id ? <Spinner size="sm" /> : u.banned ? "解封" : "封禁"}
                      </Button>
                    </div>
                  </Table.Cell>
                </Table.Row>
              ))}
            </Table.Body>
          </Table.Content>
        </Table.ScrollContainer>
      </Table>
    </div>
  );
}
