import { PlusOutlined, ReloadOutlined, SearchOutlined } from "@ant-design/icons";
import { listUsers } from "@/api";
import {
  Button,
  Form,
  Input,
  InputNumber,
  message,
  Modal,
  Select,
  Space,
  Tag,
  Tabs,
  Typography,
} from "antd";
import { useEffect, useMemo, useState } from "react";
import PageContainer from "@/components/shared/PageContainer";
import AppPagination from "@/components/shared/AppPagination";
import DataListPanel from "@/components/shared/DataListPanel";
import ListTable from "@/components/shared/ListTable/ListTable";
import SectionCard from "@/components/shared/SectionCard";
import {
  getMeetingPointsLedgerPage,
  getMeetingPointsOverview,
  transferMeetingPoints,
  type MeetingPointsLedgerListItemVO,
  type MeetingPointsOverviewVO,
  type MeetingPointsPersonalAccountVO,
} from "@/api/business/meetingPoints";
import type { SysUser } from "@/types";
import "./MeetingPointsManagement.css";

const { Text } = Typography;

const POINTS_TYPE_OPTIONS = [
  { label: "全部类型", value: "" },
  { label: "转录", value: "ASR" },
  { label: "总结", value: "LLM" },
];

const ACCOUNT_MODE_PUBLIC = "PUBLIC";
const ACCOUNT_MODE_PERSONAL = "PERSONAL";
const ACCOUNT_MODE_BOTH = "BOTH";

function getAccountModeLabel(mode?: string) {
  if (mode === ACCOUNT_MODE_PERSONAL) return "个人账户";
  if (mode === ACCOUNT_MODE_BOTH) return "公共 + 个人";
  return "公共账户";
}

function getChargePriorityLabel(priority?: string) {
  return priority === "PUBLIC_FIRST" ? "公共优先" : "个人优先";
}

function getAccountTypeLabel(type?: string) {
  return type === "PERSONAL" ? "个人账户" : "公共账户";
}

function getPointsTypeLabel(value?: string) {
  if (value === "ASR") return "转录";
  if (value === "LLM") return "总结";
  if (value === "TRANSFER_OUT") return "转出";
  if (value === "TRANSFER_IN") return "转入";
  if (value === "INIT") return "初始化";
  return value || "-";
}

function getPointsTypeColor(value?: string) {
  if (value === "ASR") return "blue";
  if (value === "LLM") return "geekblue";
  if (value === "TRANSFER_IN") return "green";
  if (value === "TRANSFER_OUT") return "orange";
  return "default";
}

function getChargeTriggerLabel(value?: string) {
  if (value === "RESUMMARY") return "重新总结";
  if (value === "AUTO_SUMMARY") return "自动总结";
  return "-";
}

function formatDateTime(value?: string) {
  return value ? value.replace("T", " ").substring(0, 19) : "-";
}

type OverviewRow = {
  id: string;
  metric: string;
  value: string | number;
  note: string;
};

export default function MeetingPointsManagement() {
  const [overview, setOverview] = useState<MeetingPointsOverviewVO | null>(null);
  const [loading, setLoading] = useState(false);
  const [transferLoading, setTransferLoading] = useState(false);
  const [usersLoading, setUsersLoading] = useState(false);
  const [records, setRecords] = useState<MeetingPointsLedgerListItemVO[]>([]);
  const [total, setTotal] = useState(0);
  const [transferOpen, setTransferOpen] = useState(false);
  const [users, setUsers] = useState<SysUser[]>([]);
  const [activeTabKey, setActiveTabKey] = useState("ledger");
  const [personalAccountPagination, setPersonalAccountPagination] = useState({
    current: 1,
    pageSize: 10,
  });
  const [params, setParams] = useState({
    current: 1,
    size: 10,
    username: "",
    pointsType: "",
  });
  const [transferForm] = Form.useForm();

  const isAdmin = Boolean(overview?.admin);
  const isPublicOnly = overview?.accountMode === ACCOUNT_MODE_PUBLIC;
  const isUnlimitedBalanceMode = overview?.balanceCheckEnabled === false;
  const showTransferButton = isAdmin && !isPublicOnly && !isUnlimitedBalanceMode;
  const showPersonalAccountSection = Boolean(overview) && !isPublicOnly;

  const sectionTabs = useMemo(
    () => [
      { key: "ledger", label: "积分流水" },
      { key: "overview", label: "账户概览" },
      ...(showPersonalAccountSection ? [{ key: "personal", label: "个人账户" }] : []),
    ],
    [showPersonalAccountSection],
  );

  useEffect(() => {
    if (!sectionTabs.some((tab) => tab.key === activeTabKey)) {
      setActiveTabKey("ledger");
    }
  }, [activeTabKey, sectionTabs]);

  const personalAccountRows = useMemo<MeetingPointsPersonalAccountVO[]>(() => {
    if (!overview || isPublicOnly) return [];
    if (isAdmin) return overview.personalAccounts || [];
    return [
      {
        userId: -1,
        displayName: "当前账号",
        currentBalance: overview.personalBalance ?? 0,
        totalPointsUsed: overview.personalTotalPointsUsed ?? 0,
      },
    ];
  }, [overview, isAdmin, isPublicOnly]);

  const pagedPersonalAccounts = useMemo(() => {
    const start = (personalAccountPagination.current - 1) * personalAccountPagination.pageSize;
    const end = start + personalAccountPagination.pageSize;
    return personalAccountRows.slice(start, end);
  }, [personalAccountPagination, personalAccountRows]);

  useEffect(() => {
    setPersonalAccountPagination((prev) => {
      const maxPage = Math.max(1, Math.ceil(personalAccountRows.length / prev.pageSize));
      return prev.current > maxPage ? { ...prev, current: maxPage } : prev;
    });
  }, [personalAccountRows.length]);

  const loadOverview = async () => {
    const data = await getMeetingPointsOverview();
    setOverview(data);
  };

  const loadUsers = async () => {
    setUsersLoading(true);
    try {
      const data = await listUsers();
      setUsers(data || []);
    } finally {
      setUsersLoading(false);
    }
  };

  const loadPage = async (nextParams = params) => {
    setLoading(true);
    try {
      const result = await getMeetingPointsLedgerPage(nextParams);
      setRecords(result.records || []);
      setTotal(result.total || 0);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    void Promise.all([loadOverview(), loadPage()]);
  }, []);

  const handleSearch = () => {
    const nextParams = { ...params, current: 1 };
    setParams(nextParams);
    void loadPage(nextParams);
  };

  const handleReset = () => {
    const nextParams = {
      current: 1,
      size: 10,
      username: "",
      pointsType: "",
    };
    setParams(nextParams);
    void loadPage(nextParams);
  };

  const handleRefresh = async () => {
    await Promise.all([loadOverview(), loadPage()]);
    message.success("已刷新积分数据");
  };

  const handleOpenTransfer = async () => {
    setTransferOpen(true);
    if (!users.length) {
      await loadUsers();
    }
  };

  const handleTransferSubmit = async () => {
    const values = await transferForm.validateFields();
    setTransferLoading(true);
    try {
      await transferMeetingPoints(values);
      message.success("积分分配成功");
      setTransferOpen(false);
      transferForm.resetFields();
      await Promise.all([loadOverview(), loadPage()]);
    } finally {
      setTransferLoading(false);
    }
  };

  const ledgerColumns = [
    {
      title: "用户",
      dataIndex: "ownerUserName",
      key: "ownerUserName",
      width: 140,
      render: (value: string) => <Text strong>{value || "-"}</Text>,
    },
    {
      title: "扣费账户",
      dataIndex: "chargeAccountType",
      key: "chargeAccountType",
      width: 120,
      render: (value: string) => <Tag>{getAccountTypeLabel(value)}</Tag>,
    },
    {
      title: "消耗类型",
      dataIndex: "pointsType",
      key: "pointsType",
      width: 100,
      render: (value: string) => <Tag color={getPointsTypeColor(value)}>{getPointsTypeLabel(value)}</Tag>,
    },
    {
      title: "消耗积分",
      dataIndex: "consumedPoints",
      key: "consumedPoints",
      width: 110,
      render: (value: number) => <Text>{value ?? 0}</Text>,
    },
    {
      title: "会议标题",
      dataIndex: "meetingTitle",
      key: "meetingTitle",
      ellipsis: true,
      render: (value: string) => <Text>{value || "-"}</Text>,
    },
    {
      title: "触发类型",
      dataIndex: "chargeTriggerType",
      key: "chargeTriggerType",
      width: 130,
      render: (value: string) => <Tag>{getChargeTriggerLabel(value)}</Tag>,
    },
    {
      title: "消耗时间",
      dataIndex: "createdAt",
      key: "createdAt",
      width: 180,
      render: (value: string) => <Text>{formatDateTime(value)}</Text>,
    },
  ];

  const personalAccountColumns = [
    {
      title: "序号",
      key: "index",
      width: 80,
      render: (_: unknown, __: MeetingPointsPersonalAccountVO, index: number) =>
        (personalAccountPagination.current - 1) * personalAccountPagination.pageSize + index + 1,
    },
    {
      title: "账户",
      key: "displayName",
      width: 260,
      render: (_: unknown, record: MeetingPointsPersonalAccountVO) => (
        <Space direction="vertical" size={2}>
          <Text strong>{record.displayName || record.username || `用户 #${record.userId}`}</Text>
          <Text type="secondary">{record.username ? `@${record.username}` : `ID ${record.userId}`}</Text>
        </Space>
      ),
    },
    {
      title: "当前余额",
      dataIndex: "currentBalance",
      key: "currentBalance",
      width: 140,
      render: (value: number) => <Text strong>{value ?? 0}</Text>,
    },
    {
      title: "累计消耗",
      dataIndex: "totalPointsUsed",
      key: "totalPointsUsed",
      width: 140,
      render: (value: number) => <Text>{value ?? 0}</Text>,
    },
    {
      title: "账户类型",
      key: "accountType",
      width: 120,
      render: () => <Tag color="blue">个人账户</Tag>,
    },
  ];

  const overviewRows = useMemo<OverviewRow[]>(() => {
    if (!overview) return [];
    return [
      { id: "accountMode", metric: "账户模式", value: getAccountModeLabel(overview.accountMode), note: "当前租户积分账户组合方式" },
      { id: "chargePriority", metric: "扣费优先级", value: getChargePriorityLabel(overview.chargePriority), note: "公共账户与个人账户的扣费顺序" },
      { id: "balanceCheckEnabled", metric: "余额校验状态", value: overview.balanceCheckEnabled ? "校验余额模式" : "无限余额模式", note: "控制会议提交时是否执行余额拦截" },
      { id: "publicBalance", metric: "公共账户余额", value: overview.publicBalance ?? 0, note: "公共账户当前可用积分" },
      { id: "publicTotalPointsUsed", metric: "公共账户累计消耗", value: overview.publicTotalPointsUsed ?? 0, note: "公共账户已消耗积分总量" },
      { id: "personalBalance", metric: "个人账户余额", value: overview.personalBalance ?? 0, note: "个人账户当前可用积分" },
      { id: "personalTotalPointsUsed", metric: "个人账户累计消耗", value: overview.personalTotalPointsUsed ?? 0, note: "个人账户已消耗积分总量" },
      { id: "totalAvailableBalance", metric: "总可用余额", value: overview.totalAvailableBalance ?? 0, note: "当前账户体系可直接使用的积分余额" },
      { id: "totalChargeCount", metric: "累计扣费次数", value: overview.totalChargeCount ?? 0, note: "已产生的积分扣费记录数" },
    ];
  }, [overview]);

  const overviewColumns = [
    {
      title: "指标",
      dataIndex: "metric",
      key: "metric",
      width: 180,
      render: (value: string) => <Text strong>{value || "-"}</Text>,
    },
    {
      title: "数值",
      dataIndex: "value",
      key: "value",
      width: 180,
      render: (value: string | number, record: OverviewRow) =>
        record.id === "balanceCheckEnabled" ? (
          <Tag color={overview?.balanceCheckEnabled ? "green" : "volcano"}>{value}</Tag>
        ) : (
          <Text strong>{value ?? "-"}</Text>
        ),
    },
    {
      title: "说明",
      dataIndex: "note",
      key: "note",
      ellipsis: true,
      render: (value: string) => <Text type="secondary">{value || "-"}</Text>,
    },
  ];

  return (
    <PageContainer title={null} className="meeting-points-page">
      <SectionCard
        title="积分管理"
        description="查看当前租户下的积分账面余额、累计消耗和会议消耗记录。"
        tabs={
          <Tabs
            activeKey={activeTabKey}
            onChange={setActiveTabKey}
            items={sectionTabs}
            size="middle"
            type="card"
          />
        }
      >
        <DataListPanel
          leftActions={
            isLookupTab(activeTabKey) && showTransferButton ? (
              <Button icon={<PlusOutlined />} onClick={() => void handleOpenTransfer()}>
                分配积分
              </Button>
            ) : null
          }
          rightActions={
            <Space wrap>
              {activeTabKey === "ledger" ? (
                <>
                  <Input
                    placeholder="按用户名搜索"
                    value={params.username}
                    onChange={(event) => setParams((prev) => ({ ...prev, username: event.target.value }))}
                    style={{ width: 220 }}
                    prefix={<SearchOutlined className="text-gray-400" />}
                    allowClear
                  />
                  <Select
                    style={{ width: 140 }}
                    value={params.pointsType}
                    onChange={(value) => setParams((prev) => ({ ...prev, pointsType: value }))}
                    options={POINTS_TYPE_OPTIONS}
                  />
                  <Button type="primary" icon={<SearchOutlined />} onClick={handleSearch}>
                    查询
                  </Button>
                  <Button onClick={handleReset}>重置</Button>
                </>
              ) : null}
              <Button
                icon={<ReloadOutlined />}
                onClick={() => void handleRefresh()}
                title="刷新"
                aria-label="刷新"
              />
            </Space>
          }
          footer={
            activeTabKey === "overview" ? (
                <div className="app-pagination-container meeting-points-page__static-pagination">
                  <div className="app-pagination-total">共 {overviewRows.length} 条记录</div>
                </div>
            ) : activeTabKey === "personal" ? (
              <AppPagination
                current={personalAccountPagination.current}
                pageSize={personalAccountPagination.pageSize}
                total={personalAccountRows.length}
                onChange={(page, size) => setPersonalAccountPagination({ current: page, pageSize: size })}
              />
            ) : (
              <AppPagination
                current={params.current}
                pageSize={params.size}
                total={total}
                onChange={(page, size) => {
                  const nextParams = { ...params, current: page, size };
                  setParams(nextParams);
                  void loadPage(nextParams);
                }}
              />
            )
          }
        >
          {activeTabKey === "overview" ? (
            <ListTable<any>
              key="overview"
              rowKey="id"
              columns={overviewColumns}
              dataSource={overviewRows}
              loading={false}
              scroll={{ x: 900, y: "100%" }}
              pagination={false}
            />
          ) : activeTabKey === "personal" ? (
            <ListTable<any>
              key="personal"
              rowKey="userId"
              columns={personalAccountColumns}
              dataSource={pagedPersonalAccounts}
              loading={false}
              scroll={{ x: 900, y: "100%" }}
              pagination={false}
            />
          ) : (
            <ListTable<any>
              key="ledger"
              rowKey="id"
              columns={ledgerColumns}
              dataSource={records}
              loading={loading}
              scroll={{ x: 1100, y: "100%" }}
              pagination={false}
            />
          )}
        </DataListPanel>
      </SectionCard>

      <Modal
        title="从公共账户分配积分"
        open={transferOpen}
        onCancel={() => {
          setTransferOpen(false);
          transferForm.resetFields();
        }}
        onOk={() => void handleTransferSubmit()}
        confirmLoading={transferLoading}
      >
        <Form form={transferForm} layout="vertical">
          <Form.Item name="targetUserId" label="目标用户" rules={[{ required: true, message: "请选择目标用户" }]}>
            <Select
              showSearch
              loading={usersLoading}
              optionFilterProp="label"
              placeholder="请选择用户"
              options={users
                .filter((user) => user.userId && user.userId > 0)
                .map((user) => ({
                  label: `${user.displayName || user.username} (#${user.userId})`,
                  value: user.userId,
                }))}
            />
          </Form.Item>
          <Form.Item name="points" label="分配积分" rules={[{ required: true, message: "请输入分配积分" }]}>
            <InputNumber min={1} precision={0} style={{ width: "100%" }} placeholder="请输入正整数积分" />
          </Form.Item>
          <Form.Item name="remark" label="备注">
            <Input placeholder="可选，默认记为管理员从公共账户分配积分" maxLength={200} />
          </Form.Item>
        </Form>
      </Modal>
    </PageContainer>
  );
}

function isLookupTab(tabKey: string) {
  return tabKey === "ledger" || tabKey === "personal";
}
