'use client';

import { useEffect, useState } from 'react';
import type { Key } from 'react';
import { useRouter } from 'next/navigation';
import type { ColumnsType } from 'antd/es/table';
import type { SorterResult } from 'antd/es/table/interface';
import { App, Button, DatePicker, Input, Select, Space, Table, Tag, Tooltip } from 'antd';
import dayjs, { type Dayjs } from 'dayjs';
import { api, errMsg } from '@/lib/api';
import { canDo } from '@/lib/auth';
import { formatUtcTime } from '@/lib/format';
import { usePagedList } from '@/lib/usePagedList';
import { AdjustCashModal, AdjustCoinModal } from '@/components/AdjustBalanceModals';
import { DeleteUserModal } from '@/components/DeleteUserModal';
import type { UserListItem } from '@/lib/types';

const { RangePicker } = DatePicker;

const STATUS_COLOR: Record<string, string> = { active: 'green', disabled: 'red', deleted: 'default' };

type SortField = 'id' | 'created_at' | 'last_active_at';

export default function UsersPage() {
  const router = useRouter();
  const { message, modal } = App.useApp();

  // 筛选草稿:点「查询」才应用(避免输入即刷新);状态/渠道/日期一并随查询提交
  const [phone, setPhone] = useState('');
  const [nickname, setNickname] = useState('');
  const [status, setStatus] = useState<string | undefined>();
  const [channel, setChannel] = useState<string | undefined>();
  const [regRange, setRegRange] = useState<[Dayjs, Dayjs] | null>(null);
  const [loginRange, setLoginRange] = useState<[Dayjs, Dayjs] | null>(null);
  const [applied, setApplied] = useState<Record<string, unknown>>({});
  // 排序(服务端):点列头即时生效,与「查询」按钮分开
  const [sortBy, setSortBy] = useState<SortField>('id');
  const [sortOrder, setSortOrder] = useState<'asc' | 'desc'>('desc');

  const filters: Record<string, unknown> = { ...applied, sort_by: sortBy, sort_order: sortOrder };
  const filterKey = JSON.stringify(filters);
  const { items, total, page, pageSize, loading, onChange: onPageChange, reload } =
    usePagedList<UserListItem>('/admin/api/users', filters);

  const canCoins = canDo(['finance']);
  const canStatus = canDo(['operator']);
  const canDelete = canDo(['super_admin']); // 注销账号最高危,仅 super_admin(与后端 require_role 对齐)

  const [coinUser, setCoinUser] = useState<UserListItem | null>(null);
  const [cashUser, setCashUser] = useState<UserListItem | null>(null);
  const [delUser, setDelUser] = useState<UserListItem | null>(null);
  const [selectedRowKeys, setSelectedRowKeys] = useState<Key[]>([]);

  // 筛选/排序变化后清空已选(避免选中项跨筛选错位)
  useEffect(() => {
    setSelectedRowKeys([]);
  }, [filterKey]);

  const search = () =>
    setApplied({
      phone: phone || undefined,
      nickname: nickname || undefined,
      status,
      register_channel: channel || undefined,
      created_from: regRange?.[0] ? regRange[0].startOf('day').toISOString() : undefined,
      created_to: regRange?.[1] ? regRange[1].endOf('day').toISOString() : undefined,
      last_active_from: loginRange?.[0] ? loginRange[0].startOf('day').toISOString() : undefined,
      last_active_to: loginRange?.[1] ? loginRange[1].endOf('day').toISOString() : undefined,
    });

  const resetFilters = () => {
    setPhone('');
    setNickname('');
    setStatus(undefined);
    setChannel(undefined);
    setRegRange(null);
    setLoginRange(null);
    setSortBy('id');
    setSortOrder('desc');
    setApplied({});
  };

  const onTableChange = (
    _pagination: unknown,
    _filters: unknown,
    sorter: SorterResult<UserListItem> | SorterResult<UserListItem>[],
  ) => {
    const s = Array.isArray(sorter) ? sorter[0] : sorter;
    if (s && s.order && s.field) {
      setSortBy(s.field as SortField);
      setSortOrder(s.order === 'ascend' ? 'asc' : 'desc');
    } else {
      // 取消排序 → 回默认(ID 倒序)
      setSortBy('id');
      setSortOrder('desc');
    }
  };

  const sortOrderOf = (field: SortField) =>
    sortBy === field ? (sortOrder === 'asc' ? 'ascend' : 'descend') : null;

  const toggleStatus = (u: UserListItem) => {
    const next = u.status === 'active' ? 'disabled' : 'active';
    modal.confirm({
      title: `确认${next === 'disabled' ? '封禁' : '解封'}用户 ${u.phone}?`,
      onOk: async () => {
        try {
          await api.post(`/admin/api/users/${u.id}/status`, { status: next });
          message.success('已更新状态');
          reload();
        } catch (e) {
          message.error(errMsg(e));
        }
      },
    });
  };

  const toggleDebugTrace = (u: UserListItem) => {
    const next = !u.debug_trace_enabled;
    modal.confirm({
      title: `确认${next ? '开启' : '关闭'}用户 ${u.phone} 的调试链接权限?`,
      content: next
        ? '开启后,该用户在 App 比价结果页/记录页可复制 trace 调试链接发给开发排障'
        : undefined,
      onOk: async () => {
        try {
          await api.post(`/admin/api/users/${u.id}/debug-trace`, { enabled: next });
          message.success('已更新调试链接权限');
          reload();
        } catch (e) {
          message.error(errMsg(e));
        }
      },
    });
  };

  // 一次性操作:点一下把该用户标记为「未看过引导」,下次打开 App 重看一遍,看完后端自动恢复(只触发这一次)。
  // 用户尚未重看前可「撤销」(把 force_onboarding 置回 false),纠正误点。
  const setForceOnboarding = (u: UserListItem, enable: boolean) => {
    modal.confirm({
      title: enable
        ? `确认让用户 ${u.phone} 重看一次新手引导?`
        : `撤销用户 ${u.phone} 的「重看新手引导」?`,
      content: enable
        ? '点一下即把该用户标记为「未看过引导」:Ta 下次打开 App 会重走一遍新手引导,看完自动恢复——只触发这一次。仅对已支持该功能的 App 版本生效。'
        : '该用户尚未重看,撤销后下次打开 App 不再触发。',
      onOk: async () => {
        try {
          await api.post(`/admin/api/users/${u.id}/force-onboarding`, { enabled: enable });
          message.success(enable ? '已开启:该用户下次打开 App 会重看一次' : '已撤销');
          reload();
        } catch (e) {
          message.error(errMsg(e));
        }
      },
    });
  };

  const selectedUsers = items.filter((u) => selectedRowKeys.includes(u.id));
  const selectedActive = selectedUsers.filter((u) => u.status === 'active');
  const selectedDisabled = selectedUsers.filter((u) => u.status === 'disabled');

  // 批量:循环调现有逐用户接口(各自已带审计),Promise.allSettled 汇总成败,不新增 bulk 端点
  const runBulk = async (
    targets: UserListItem[],
    label: string,
    call: (u: UserListItem) => Promise<unknown>,
  ) => {
    const results = await Promise.allSettled(targets.map(call));
    const ok = results.filter((r) => r.status === 'fulfilled').length;
    const fail = results.length - ok;
    if (fail) message.warning(`${label}完成:成功 ${ok}/${results.length},失败 ${fail}`);
    else message.success(`${label}完成:${ok} 个`);
    setSelectedRowKeys([]);
    reload();
  };

  const bulkStatus = (target: 'disabled' | 'active') => {
    const targets = target === 'disabled' ? selectedActive : selectedDisabled;
    const label = target === 'disabled' ? '批量封禁' : '批量解封';
    if (!targets.length) {
      message.warning(`没有可${target === 'disabled' ? '封禁(active)' : '解封(disabled)'}的选中用户`);
      return;
    }
    modal.confirm({
      title: `确认${label} ${targets.length} 个用户?`,
      content: target === 'disabled' ? '仅对选中的 active 用户生效' : '仅对选中的 disabled 用户生效',
      okButtonProps: { danger: target === 'disabled' },
      onOk: () =>
        runBulk(targets, label, (u) =>
          api.post(`/admin/api/users/${u.id}/status`, { status: target }),
        ),
    });
  };

  const bulkDebugTrace = (enabled: boolean) => {
    // 只对「非 deleted 且当前态不同」的选中用户操作,避免无谓请求
    const targets = selectedUsers.filter(
      (u) => u.status !== 'deleted' && u.debug_trace_enabled !== enabled,
    );
    const label = enabled ? '批量开调试链接' : '批量关调试链接';
    if (!targets.length) {
      message.warning('没有需要变更的选中用户');
      return;
    }
    modal.confirm({
      title: `确认${label} ${targets.length} 个用户?`,
      onOk: () =>
        runBulk(targets, label, (u) =>
          api.post(`/admin/api/users/${u.id}/debug-trace`, { enabled }),
        ),
    });
  };

  const columns: ColumnsType<UserListItem> = [
    { title: 'ID', dataIndex: 'id', width: 80, sorter: true, sortOrder: sortOrderOf('id') },
    { title: '手机号', dataIndex: 'phone', width: 130 },
    {
      title: '昵称',
      dataIndex: 'nickname',
      width: 150,
      ellipsis: true,
      render: (v: string | null) => v || '-',
    },
    { title: '渠道', dataIndex: 'register_channel', width: 90 },
    {
      title: '状态',
      dataIndex: 'status',
      width: 90,
      render: (s: string) => <Tag color={STATUS_COLOR[s]}>{s}</Tag>,
    },
    {
      title: '注册时间',
      dataIndex: 'created_at',
      width: 160,
      sorter: true,
      sortOrder: sortOrderOf('created_at'),
      render: (v: string) => formatUtcTime(v),
    },
    {
      // 最近活跃 = max(最近登录, 最近发起比价, 最近发起领券),与大盘 DAU/留存活跃口径一致(2026-07-05)
      title: (
        <Tooltip title="进入 App(登录)/ 发起比价 / 发起领券,取最近一次">
          最近活跃
        </Tooltip>
      ),
      dataIndex: 'last_active_at',
      width: 160,
      sorter: true,
      // 关掉 antd 默认的「点击升序/降序」表头提示,否则与上面自定义口径 Tooltip 同时弹出互相遮挡
      showSorterTooltip: false,
      sortOrder: sortOrderOf('last_active_at'),
      render: (v: string | null, u: UserListItem) => formatUtcTime(v ?? u.last_login_at),
    },
    {
      title: '操作',
      key: 'op',
      fixed: 'right',
      width: 340,
      render: (_: unknown, u: UserListItem) => (
        <Space wrap={false} onClick={(e) => e.stopPropagation()}>
          <a onClick={() => router.push(`/users/${u.id}`)}>详情</a>
          {canCoins && <a onClick={() => setCoinUser(u)}>调金币</a>}
          {canCoins && <a onClick={() => setCashUser(u)}>调现金</a>}
          {canStatus && u.status !== 'deleted' && (
            <a onClick={() => toggleStatus(u)}>{u.status === 'active' ? '封禁' : '解封'}</a>
          )}
          {canStatus && u.status !== 'deleted' && (
            <a onClick={() => toggleDebugTrace(u)}>
              {u.debug_trace_enabled ? '关调试链接' : '开调试链接'}
            </a>
          )}
          {canStatus &&
            u.status !== 'deleted' &&
            (u.force_onboarding ? (
              <span style={{ color: '#fa8c16' }}>
                待重看 <a onClick={() => setForceOnboarding(u, false)}>撤销</a>
              </span>
            ) : (
              <a onClick={() => setForceOnboarding(u, true)}>开启新手引导</a>
            ))}
          {canDelete && u.status !== 'deleted' && (
            <a style={{ color: '#cf1322' }} onClick={() => setDelUser(u)}>
              注销
            </a>
          )}
        </Space>
      ),
    },
  ];

  return (
    <div>
      <h2>用户管理</h2>
      <Space style={{ marginBottom: 16 }} wrap>
        <Input
          placeholder="手机号前缀"
          value={phone}
          onChange={(e) => setPhone(e.target.value)}
          onPressEnter={search}
          allowClear
          style={{ width: 150 }}
        />
        <Input
          placeholder="昵称(模糊)"
          value={nickname}
          onChange={(e) => setNickname(e.target.value)}
          onPressEnter={search}
          allowClear
          style={{ width: 150 }}
        />
        <Select
          placeholder="状态"
          value={status}
          onChange={setStatus}
          allowClear
          style={{ width: 110 }}
          options={[
            { value: 'active', label: 'active' },
            { value: 'disabled', label: 'disabled' },
            { value: 'deleted', label: 'deleted' },
          ]}
        />
        <Select
          placeholder="渠道"
          value={channel}
          onChange={setChannel}
          allowClear
          style={{ width: 110 }}
          options={[
            { value: 'sms', label: 'sms' },
            { value: 'wechat', label: 'wechat' },
          ]}
        />
        <RangePicker
          placeholder={['注册起', '注册止']}
          value={regRange}
          onChange={(v) => setRegRange(v as [Dayjs, Dayjs] | null)}
          allowClear
        />
        <RangePicker
          placeholder={['最近活跃起', '最近活跃止']}
          value={loginRange}
          onChange={(v) => setLoginRange(v as [Dayjs, Dayjs] | null)}
          allowClear
        />
        <Button type="primary" onClick={search}>
          查询
        </Button>
        <Button onClick={resetFilters}>重置</Button>
      </Space>

      {canStatus && selectedUsers.length > 0 && (
        <Space style={{ marginBottom: 12, width: '100%' }} wrap>
          <span style={{ color: '#888' }}>
            已选 {selectedUsers.length} 个(active {selectedActive.length}、disabled{' '}
            {selectedDisabled.length})
          </span>
          <Button danger disabled={!selectedActive.length} onClick={() => bulkStatus('disabled')}>
            批量封禁
          </Button>
          <Button disabled={!selectedDisabled.length} onClick={() => bulkStatus('active')}>
            批量解封
          </Button>
          <Button onClick={() => bulkDebugTrace(true)}>批量开调试链接</Button>
          <Button onClick={() => bulkDebugTrace(false)}>批量关调试链接</Button>
          <Button type="link" onClick={() => setSelectedRowKeys([])}>
            清空选择
          </Button>
        </Space>
      )}

      <Table
        rowKey="id"
        rowSelection={
          canStatus
            ? {
                selectedRowKeys,
                onChange: setSelectedRowKeys,
                getCheckboxProps: (u) => ({ disabled: u.status === 'deleted' }),
              }
            : undefined
        }
        columns={columns}
        dataSource={items}
        loading={loading}
        pagination={{
          current: page,
          pageSize,
          total,
          showSizeChanger: true,
          showTotal: (t) => `共 ${t} 个用户`,
          onChange: onPageChange,
        }}
        scroll={{ x: 1200 }}
        onChange={onTableChange}
      />

      <AdjustCoinModal user={coinUser} open={!!coinUser} onClose={() => setCoinUser(null)} />
      <AdjustCashModal user={cashUser} open={!!cashUser} onClose={() => setCashUser(null)} />
      <DeleteUserModal
        user={delUser}
        open={!!delUser}
        onClose={() => setDelUser(null)}
        onDone={reload}
      />
    </div>
  );
}
