import React, { useEffect, useState } from 'react';
import {
  Button, Card, Checkbox, Form, Input, InputNumber, message, Modal, Popconfirm, Progress, Select, Space, Switch, Table, Tabs, Tag, Typography,
} from 'antd';
import {
  UserOutlined, WalletOutlined, SearchOutlined, StopOutlined, CheckCircleOutlined, PlusOutlined, MenuOutlined, LockOutlined, SettingOutlined, SaveOutlined, DatabaseOutlined, TeamOutlined, PictureOutlined, SecurityScanOutlined,
} from '@ant-design/icons';
import {
  adjustCredits,
  adminGetPrivatePortraitConfig,
  adminUpdatePrivatePortraitConfig,
  createUser,
  deleteUserResourceCapacity,
  getAdminUsers,
  getMenuConfigs,
  getTeamOptions,
  getSystemConfigs,
  getUserResourceCapacity,
  resetUserPassword,
  saveUserResourceCapacity,
  toggleUserStatus,
  updateFrontendUserKind,
  updateUserTeam,
  updateSystemConfig,
  updateUserMenus,
  updateUserAdminStatus,
} from '../api';
import type { AdminTeamOption, AdminUser, AdminUserResourceCapacityOut, PrivatePortraitConfig, ResourceCapacityUnit, ResourceCapacityUsage, SystemConfig } from '../types';
import { formatDate } from '../utils/formatDate';

const TEAM_UNASSIGNED_VALUE = '__none__';

const capacityUnitOptions: { value: ResourceCapacityUnit; label: string }[] = [
  { value: 'MB', label: 'MB（1024 × 1024 字节）' },
  { value: 'GB', label: 'GB（1024 × 1024 × 1024 字节）' },
  { value: 'TB', label: 'TB（1024 × 1024 × 1024 × 1024 字节）' },
];

function formatBytes(bytes?: number | null): string {
  if (bytes === null || bytes === undefined) return '-';
  const value = Number(bytes || 0);
  if (value < 1024) return `${value} B`;
  const units = ['KB', 'MB', 'GB', 'TB', 'PB'];
  let size = value;
  let unitIndex = -1;
  do {
    size /= 1024;
    unitIndex += 1;
  } while (size >= 1024 && unitIndex < units.length - 1);
  return `${size.toFixed(size >= 100 ? 0 : size >= 10 ? 1 : 2)} ${units[unitIndex]}`;
}

function capacitySourceLabel(capacity?: ResourceCapacityUsage | null): string {
  if (!capacity || !capacity.enabled) return '未开启';
  if (capacity.source === 'user') return '个人';
  if (capacity.source === 'global') return '全局';
  return '未开启';
}

const AdminUsers: React.FC = () => {
  const [users, setUsers] = useState<AdminUser[]>([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState('');
  const [activeTab, setActiveTab] = useState<string>('frontend');
  const [frontendKindFilter, setFrontendKindFilter] = useState<string>('');
  const [teamFilter, setTeamFilter] = useState<string>('');
  const [teamOptions, setTeamOptions] = useState<AdminTeamOption[]>([]);
  const [creditModal, setCreditModal] = useState<{ open: boolean; user: AdminUser | null }>({ open: false, user: null });
  const [createModal, setCreateModal] = useState(false);
  const [createType, setCreateType] = useState<string>('frontend');
  const [menuModal, setMenuModal] = useState<{ open: boolean; user: AdminUser | null }>({ open: false, user: null });
  const [allMenus, setAllMenus] = useState<any[]>([]);
  const [checkedMenus, setCheckedMenus] = useState<string[]>([]);
  const [resetPwdModal, setResetPwdModal] = useState<{ open: boolean; user: AdminUser | null }>({ open: false, user: null });
  const [capacityModal, setCapacityModal] = useState<{ open: boolean; user: AdminUser | null; detail: AdminUserResourceCapacityOut | null }>({ open: false, user: null, detail: null });
  const [teamModal, setTeamModal] = useState<{ open: boolean; user: AdminUser | null }>({ open: false, user: null });
  const [portraitModal, setPortraitModal] = useState<{ open: boolean; user: AdminUser | null; config: PrivatePortraitConfig | null }>({ open: false, user: null, config: null });
  const [capacityLoading, setCapacityLoading] = useState(false);
  const [capacitySaving, setCapacitySaving] = useState(false);
  const [teamSaving, setTeamSaving] = useState(false);
  const [portraitLoading, setPortraitLoading] = useState(false);
  const [portraitSaving, setPortraitSaving] = useState(false);
  const [form] = Form.useForm();
  const [createForm] = Form.useForm();
  const [resetPwdForm] = Form.useForm();
  const [capacityForm] = Form.useForm();
  const [teamForm] = Form.useForm();
  const [portraitForm] = Form.useForm();

  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(20);
  const [total, setTotal] = useState(0);

  const [creditConfigs, setCreditConfigs] = useState<SystemConfig[]>([]);
  const [configForm] = Form.useForm();
  const [configSaving, setConfigSaving] = useState(false);

  const load = async () => {
    setLoading(true);
    try {
      const data = await getAdminUsers(
        page,
        pageSize,
        search || undefined,
        activeTab,
        activeTab === 'frontend' ? (frontendKindFilter || undefined) : undefined,
        activeTab === 'frontend' ? (teamFilter || undefined) : undefined,
      );
      setUsers(data.items || []);
      setTotal(data.total || 0);
    } catch { /* auth error handled by client */ }
    setLoading(false);
  };

  useEffect(() => { load(); }, [page, pageSize, search, activeTab, frontendKindFilter, teamFilter]);

  useEffect(() => {
    getTeamOptions(true).then(setTeamOptions).catch(() => {});
  }, []);

  useEffect(() => {
    const loadCreditConfigs = async () => {
      try {
        const configs = await getSystemConfigs();
        const credit = configs.filter(c => c.key.startsWith('user_') && c.key.includes('credits'));
        setCreditConfigs(credit);
        const formValues: Record<string, string> = {};
        credit.forEach(c => { formValues[c.key] = c.value; });
        configForm.setFieldsValue(formValues);
      } catch { /* auth error handled by client */ }
    };
    loadCreditConfigs();
  }, []);

  const handleSaveCreditConfigs = async () => {
    try {
      const values = await configForm.validateFields();
      setConfigSaving(true);
      for (const config of creditConfigs) {
        const newVal = values[config.key];
        if (newVal !== undefined && String(newVal) !== config.value) {
          await updateSystemConfig(config.id, String(newVal ?? ''));
        }
      }
      message.success('积分配置已保存');
      const configs = await getSystemConfigs();
      setCreditConfigs(configs.filter(c => c.key.startsWith('user_') && c.key.includes('credits')));
    } catch (e: any) {
      message.error(e?.message || '保存失败');
    } finally {
      setConfigSaving(false);
    }
  };

  const handlePageChange = (p: number, ps: number) => {
    setPage(p);
    setPageSize(ps);
  };

  const handleSearch = () => load();

  const handleAdjustCredits = async () => {
    try {
      const values = await form.validateFields();
      const { user } = creditModal;
      if (!user) return;
      await adjustCredits(user.id, values.amount, values.description);
      message.success(`已${values.amount > 0 ? '增加' : '扣除'} ${Math.abs(values.amount)} 积分`);
      setCreditModal({ open: false, user: null });
      form.resetFields();
      load();
    } catch { /* validation */ }
  };

  const handleToggleStatus = async (user: AdminUser) => {
    await toggleUserStatus(user.id, !user.isActive);
    message.success(user.isActive ? '已禁用该用户' : '已启用该用户');
    load();
  };

  const handleCreateUser = async () => {
    try {
      const values = await createForm.validateFields();
      const userType = values.user_type || 'frontend';
      await createUser({
        username: userType === 'admin' ? values.username : undefined,
        password: values.password,
        email: values.email || undefined,
        phone: userType === 'frontend' ? values.phone : (values.phone || undefined),
        credits: values.credits || 0,
        user_type: userType,
        is_admin: userType === 'admin' ? (values.is_admin ?? false) : false,
        frontend_user_kind: values.frontend_user_kind || 'external',
        private_portrait_asset_limit: userType === 'frontend' ? Number(values.private_portrait_asset_limit ?? 5) : 0,
      });
      message.success('用户创建成功');
      setCreateModal(false);
      createForm.resetFields();
      setCreateType('frontend');
      load();
    } catch { /* validation */ }
  };

  const openMenuModal = async (user: AdminUser) => {
    try {
      const menus = await getMenuConfigs();
      const isAdminUser = user.userType === 'admin';
      setAllMenus(menus.filter((m: any) => {
        const target = m.menu_target ?? m.menuTarget ?? 'frontend';
        return isAdminUser ? (target === 'admin' || target === 'both') : (target === 'frontend' || target === 'both');
      }));
      setCheckedMenus(user.allowedMenus || []);
      setMenuModal({ open: true, user });
    } catch {
      message.error('加载菜单失败');
    }
  };

  const openCapacityModal = async (user: AdminUser) => {
    setCapacityLoading(true);
    setCapacityModal({ open: true, user, detail: null });
    try {
      const detail = await getUserResourceCapacity(user.id);
      const initialConfig = detail.userConfig;
      capacityForm.setFieldsValue({
        enabled: initialConfig?.enabled ?? false,
        limitValue: initialConfig?.limitValue ?? detail.effective.limitValue ?? detail.globalConfig.limitValue ?? '1.000',
        limitUnit: initialConfig?.limitUnit ?? detail.effective.limitUnit ?? detail.globalConfig.limitUnit ?? 'GB',
      });
      setCapacityModal({ open: true, user, detail });
    } catch (e: any) {
      message.error(e?.message || '加载容量配置失败');
      setCapacityModal({ open: false, user: null, detail: null });
    } finally {
      setCapacityLoading(false);
    }
  };

  const handleSaveCapacity = async () => {
    const { user } = capacityModal;
    if (!user) return;
    try {
      const values = await capacityForm.validateFields();
      setCapacitySaving(true);
      await saveUserResourceCapacity(user.id, {
        enabled: !!values.enabled,
        limitValue: String(values.limitValue ?? '1.000'),
        limitUnit: values.limitUnit || 'GB',
      });
      message.success('用户容量配置已保存');
      setCapacityModal({ open: false, user: null, detail: null });
      capacityForm.resetFields();
      load();
    } catch (e: any) {
      message.error(e?.message || '保存失败');
    } finally {
      setCapacitySaving(false);
    }
  };

  const handleRestoreGlobalCapacity = async () => {
    const { user } = capacityModal;
    if (!user) return;
    try {
      setCapacitySaving(true);
      await deleteUserResourceCapacity(user.id);
      message.success('已恢复为全局容量配置');
      setCapacityModal({ open: false, user: null, detail: null });
      capacityForm.resetFields();
      load();
    } catch (e: any) {
      message.error(e?.message || '恢复失败');
    } finally {
      setCapacitySaving(false);
    }
  };

  const openPortraitModal = async (user: AdminUser) => {
    setPortraitLoading(true);
    setPortraitModal({ open: true, user, config: null });
    portraitForm.setFieldsValue({ privatePortraitAssetLimit: user.privatePortraitAssetLimit ?? 5 });
    try {
      const config = await adminGetPrivatePortraitConfig(user.id);
      portraitForm.setFieldsValue({ privatePortraitAssetLimit: config.assetLimit });
      setPortraitModal({ open: true, user, config });
    } catch (e: any) {
      message.error(e?.message || '加载私域人像素材库配置失败');
      setPortraitModal({ open: false, user: null, config: null });
    } finally {
      setPortraitLoading(false);
    }
  };

  const handleSavePortraitConfig = async () => {
    const { user } = portraitModal;
    if (!user) return;
    try {
      const values = await portraitForm.validateFields();
      const limit = Number(values.privatePortraitAssetLimit ?? 0);
      setPortraitSaving(true);
      const config = await adminUpdatePrivatePortraitConfig(user.id, limit);
      message.success(limit > 0 ? `私域人像素材库已开启，限制 ${limit} 个` : '私域人像素材库已关闭');
      setPortraitModal({ open: false, user: null, config });
      portraitForm.resetFields();
      load();
    } catch (e: any) {
      if (e?.errorFields) return;
      message.error(e?.message || '保存私域人像素材库配置失败');
    } finally {
      setPortraitSaving(false);
    }
  };

  const openTeamModal = (user: AdminUser) => {
    teamForm.setFieldsValue({ teamId: user.teamId || '' });
    setTeamModal({ open: true, user });
  };

  const handleSaveTeam = async () => {
    const { user } = teamModal;
    if (!user) return;
    try {
      const values = await teamForm.validateFields();
      setTeamSaving(true);
      await updateUserTeam(user.id, values.teamId || null);
      message.success('用户团队已更新');
      setTeamModal({ open: false, user: null });
      teamForm.resetFields();
      load();
    } catch (e: any) {
      if (e?.errorFields) return;
      message.error(e?.message || '保存团队失败');
    } finally {
      setTeamSaving(false);
    }
  };

  const menuGroups = allMenus.filter((m: any) => (m.menu_type ?? m.menuType) === 'group');
  const menuPages = allMenus.filter((m: any) => (m.menu_type ?? m.menuType) !== 'group');
  const childMap: Record<string, any[]> = {};
  menuPages.filter((m: any) => m.parent_id ?? m.parentId).forEach((m: any) => {
    const pid = m.parent_id ?? m.parentId;
    if (!childMap[pid]) childMap[pid] = [];
    childMap[pid].push(m);
  });
  const topLevelPages = menuPages.filter((m: any) => !(m.parent_id ?? m.parentId));

  const handleSaveMenus = async () => {
    const { user } = menuModal;
    if (!user) return;
    try {
      await updateUserMenus(user.id, checkedMenus.length > 0 ? checkedMenus : null);
      message.success('菜单权限已更新');
      setMenuModal({ open: false, user: null });
      load();
    } catch (e: any) {
      message.error(e?.message || '保存失败');
    }
  };

  const handleResetPassword = async () => {
    try {
      const values = await resetPwdForm.validateFields();
      const { user } = resetPwdModal;
      if (!user) return;
      await resetUserPassword(user.id, values.newPassword);
      message.success(`已重置 ${user.username} 的密码`);
      setResetPwdModal({ open: false, user: null });
      resetPwdForm.resetFields();
    } catch { /* validation */ }
  };

  const handleUpdateFrontendKind = async (user: AdminUser, kind: 'internal' | 'external') => {
    try {
      await updateFrontendUserKind(user.id, kind);
      message.success(kind === 'internal' ? '已设为前台内部用户' : '已设为前台外部用户');
      load();
    } catch (e: any) {
      message.error(e?.message || '设置失败');
    }
  };

  const handleToggleAdminStatus = async (user: AdminUser) => {
    try {
      await updateUserAdminStatus(user.id, !user.isAdmin);
      message.success(user.isAdmin ? '已取消超级管理员' : '已设为超级管理员');
      load();
    } catch (e: any) {
      message.error(e?.message || '设置失败');
    }
  };

  const isAdminTab = activeTab === 'admin';

  const columns = [
    {
      title: '用户', key: 'user', width: 200,
      render: (_: any, r: AdminUser) => (
        <Space>
          <div style={{
            width: 32, height: 32, borderRadius: 8,
            background: r.isAdmin ? 'linear-gradient(135deg, #f59e0b, #f97316)' : 'linear-gradient(135deg, #6366f1, #8b5cf6)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: '#fff', fontSize: 13, fontWeight: 700,
          }}>
            {r.username.charAt(0).toUpperCase()}
          </div>
          <div>
            <div style={{ fontWeight: 600 }}>
              {r.username}
              {r.isAdmin && <Tag color="orange" style={{ marginLeft: 6, fontSize: 10 }}>超级管理员</Tag>}
            </div>
            <div style={{ color: '#94a3b8', fontSize: 12 }}>{r.email}</div>
          </div>
        </Space>
      ),
    },
    ...(!isAdminTab ? [{
      title: '积分余额', dataIndex: 'credits', width: 120, sorter: (a: AdminUser, b: AdminUser) => a.credits - b.credits,
      render: (v: number) => (
        <Typography.Text strong style={{ color: v > 0 ? '#10b981' : '#ef4444', fontSize: 15 }}>
          {v.toLocaleString()}
        </Typography.Text>
      ),
    }] : []),
    {
      title: '手机号', dataIndex: 'phone', width: 130,
      render: (v: string) => <Typography.Text type="secondary">{v || '-'}</Typography.Text>,
    },
    ...(!isAdminTab ? [{
      title: '前台归类', dataIndex: 'frontendUserKind', width: 110,
      render: (v: string) => <Tag color={v === 'internal' ? 'geekblue' : 'default'}>{v === 'internal' ? '内部用户' : '外部用户'}</Tag>,
    }] : []),
    ...(!isAdminTab ? [{
      title: '团队', dataIndex: 'teamName', width: 140,
      render: (v: string | null | undefined) => v ? <Tag color="blue">{v}</Tag> : <Typography.Text type="secondary">未分配</Typography.Text>,
    }] : []),
    ...(!isAdminTab ? [{
      title: '私域人像素材库', dataIndex: 'privatePortraitAssetLimit', width: 150,
      render: (v: number) => {
        const limit = Number(v || 0);
        return limit > 0 ? <Tag color="purple">开启：{limit} 个</Tag> : <Tag>未开启</Tag>;
      },
    }] : []),
    ...(!isAdminTab ? [{
      title: '资源容量', dataIndex: 'resourceCapacity', width: 230,
      render: (capacity: ResourceCapacityUsage | null | undefined) => {
        const usedText = formatBytes(capacity?.usedBytes || 0);
        if (!capacity || !capacity.enabled) {
          return (
            <div>
              <Space size={6} style={{ marginBottom: 4 }}>
                <Tag>未开启</Tag>
                <Typography.Text type="secondary" style={{ fontSize: 12 }}>已用 {usedText}</Typography.Text>
              </Space>
              <Progress percent={0} size="small" showInfo={false} />
            </div>
          );
        }
        const percent = Math.min(Number(capacity.usagePercent || 0), 100);
        return (
          <div>
            <Space size={6} style={{ marginBottom: 4 }}>
              <Tag color={capacity.source === 'user' ? 'blue' : 'purple'}>{capacitySourceLabel(capacity)}</Tag>
              {capacity.exceeded && <Tag color="red">已超额</Tag>}
            </Space>
            <Progress percent={percent} size="small" status={capacity.exceeded ? 'exception' : 'active'} />
            <Typography.Text type="secondary" style={{ fontSize: 12 }}>
              {usedText} / {formatBytes(capacity.totalBytes)}，可用 {formatBytes(capacity.availableBytes)}
            </Typography.Text>
          </div>
        );
      },
    }] : []),
    {
      title: '状态', dataIndex: 'isActive', width: 80,
      render: (v: boolean) => (
        <Tag color={v ? 'green' : 'red'}>{v ? '正常' : '禁用'}</Tag>
      ),
    },
    {
      title: '注册时间', dataIndex: 'createdAt', width: 120,
      render: (v: string) => <Typography.Text type="secondary" style={{ fontSize: 12 }}>{formatDate(v)}</Typography.Text>,
    },
    {
      title: '最后登录', dataIndex: 'lastLoginAt', width: 140,
      render: (v: string) => <Typography.Text type="secondary" style={{ fontSize: 12 }}>{formatDate(v)}</Typography.Text>,
    },
    {
      title: '操作', key: 'action', width: 560, fixed: 'right' as const,
      render: (_: any, r: AdminUser) => (
        <Space size={4} wrap>
          {!isAdminTab && (
            <Button type="link" size="small" icon={<WalletOutlined />}
              onClick={() => { setCreditModal({ open: true, user: r }); form.resetFields(); }}>
              调整积分
            </Button>
          )}
          {!isAdminTab && (
            <Button type="link" size="small" icon={<DatabaseOutlined />}
              onClick={() => openCapacityModal(r)}>
              容量设置
            </Button>
          )}
          {!isAdminTab && (
            <Button type="link" size="small" icon={<PictureOutlined />}
              onClick={() => openPortraitModal(r)}>
              私域人像素材
            </Button>
          )}
          {!isAdminTab && (
            <Button type="link" size="small" icon={<TeamOutlined />}
              onClick={() => openTeamModal(r)}>
              团队设置
            </Button>
          )}
          {!isAdminTab && r.frontendUserKind !== 'internal' && (
            <Button type="link" size="small" onClick={() => handleUpdateFrontendKind(r, 'internal')}>设为内部</Button>
          )}
          {!isAdminTab && r.frontendUserKind === 'internal' && (
            <Button type="link" size="small" onClick={() => handleUpdateFrontendKind(r, 'external')}>取消内部</Button>
          )}
          {isAdminTab && (
            <Popconfirm
              title={r.isAdmin ? '确定取消该用户的超级管理员权限？' : '确定将该用户设为超级管理员？'}
              onConfirm={() => handleToggleAdminStatus(r)}
            >
              <Button type="link" size="small" style={{ color: r.isAdmin ? '#f59e0b' : '#6366f1' }}
                icon={<SecurityScanOutlined />}>
                {r.isAdmin ? '取消超级管理员' : '设为超级管理员'}
              </Button>
            </Popconfirm>
          )}
          <Button type="link" size="small" icon={<MenuOutlined />}
            onClick={() => openMenuModal(r)}>
            菜单权限
          </Button>
          <Button type="link" size="small" icon={<LockOutlined />}
            onClick={() => { setResetPwdModal({ open: true, user: r }); resetPwdForm.resetFields(); }}>
            重置密码
          </Button>
          <Popconfirm
            title={r.isActive ? '确定禁用该用户？' : '确定启用该用户？'}
            onConfirm={() => handleToggleStatus(r)}
          >
            <Button type="link" size="small" danger={r.isActive}
              icon={r.isActive ? <StopOutlined /> : <CheckCircleOutlined />}>
              {r.isActive ? '禁用' : '启用'}
            </Button>
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <div>
      {/* <Card variant="outlined" style={{ borderRadius: 12, border: '1px solid #f0f0f5', marginBottom: 16 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 20 }}>
          <div style={{
            width: 44, height: 44, borderRadius: 10,
            background: 'rgba(99,102,241,0.08)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontSize: 20, color: '#6366f1',
          }}>
            <SettingOutlined />
          </div>
          <div>
            <Typography.Title level={4} style={{ margin: 0 }}>积分配置</Typography.Title>
            <Typography.Text type="secondary">设置用户注册和登录赠送的积分</Typography.Text>
          </div>
        </div>

        <Form form={configForm} layout="vertical">
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 20 }}>
            <Form.Item
              name="user_register_credits"
              label={<span style={{ fontWeight: 500 }}>注册赠送积分</span>}
              extra="用户注册时赠送的初始积分"
            >
              <InputNumber min={0} style={{ width: '100%' }} size="large" />
            </Form.Item>
            <Form.Item
              name="user_login_credits"
              label={<span style={{ fontWeight: 500 }}>每日登录赠送积分</span>}
              extra="用户每日首次登录赠送的积分"
            >
              <InputNumber min={0} style={{ width: '100%' }} size="large" />
            </Form.Item>
            <Form.Item
              name="user_login_credits_enabled"
              label={<span style={{ fontWeight: 500 }}>启用每日登录积分</span>}
              extra="是否开启每日登录赠送积分功能"
            >
              <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                <Switch defaultChecked={creditConfigs.find(c => c.key === 'user_login_credits_enabled')?.value === 'true'} />
                <Typography.Text type="secondary" style={{ fontSize: 13 }}>
                  {creditConfigs.find(c => c.key === 'user_login_credits_enabled')?.value === 'true' ? '已启用' : '已禁用'}
                </Typography.Text>
              </div>
            </Form.Item>
          </div>

          <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: 16 }}>
            <Button type="primary" icon={<SaveOutlined />} onClick={handleSaveCreditConfigs} loading={configSaving} size="large" style={{ borderRadius: 8 }}>
              保存配置
            </Button>
          </div>
        </Form>
      </Card> */}

      <Card variant="outlined" style={{ borderRadius: 12, border: '1px solid #f0f0f5' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 16 }}>
          <div style={{ display: 'flex', gap: 12 }}>
            <Input
              placeholder="搜索用户名或手机号"
              prefix={<SearchOutlined style={{ color: '#94a3b8' }} />}
              value={search}
              onChange={e => setSearch(e.target.value)}
              onPressEnter={handleSearch}
              style={{ width: 280, borderRadius: 8 }}
              allowClear
            />
            {!isAdminTab && (
              <Select
                value={frontendKindFilter}
                onChange={(v) => { setPage(1); setFrontendKindFilter(v); }}
                style={{ width: 140 }}
                options={[
                  { value: '', label: '全部前台用户' },
                  { value: 'internal', label: '内部用户' },
                  { value: 'external', label: '外部用户' },
                ]}
              />
            )}
            {!isAdminTab && (
              <Select
                value={teamFilter}
                onChange={(v) => { setPage(1); setTeamFilter(v); }}
                style={{ width: 170 }}
                options={[
                  { value: '', label: '全部团队' },
                  { value: TEAM_UNASSIGNED_VALUE, label: '未分配团队' },
                  ...teamOptions.map(t => ({ value: t.id, label: t.status === 'disabled' ? `${t.name}（禁用）` : t.name })),
                ]}
              />
            )}
            <Button type="primary" onClick={handleSearch} style={{ borderRadius: 8 }}>搜索</Button>
          </div>
          <Button type="primary" icon={<PlusOutlined />}
            onClick={() => { setCreateType(activeTab); createForm.setFieldsValue({ user_type: activeTab }); setCreateModal(true); }}
            style={{ borderRadius: 8 }}>
            创建用户
          </Button>
        </div>

        <Tabs
          activeKey={activeTab}
          onChange={(key) => { setActiveTab(key); setFrontendKindFilter(''); setTeamFilter(''); setPage(1); }}
          items={[
            { key: 'frontend', label: '前台用户' },
            { key: 'admin', label: '后台用户' },
          ]}
        />

        <Table
          columns={columns}
          dataSource={users}
          rowKey="id"
          loading={loading}
          pagination={{
            current: page,
            pageSize: pageSize,
            total: total,
            onChange: handlePageChange,
            showSizeChanger: true,
            showTotal: (t) => `共 ${t} 个用户`,
          }}
          scroll={{ x: 1280 }}
        />
      </Card>

      <Modal
        title={<Space><WalletOutlined />调整积分 - {creditModal.user?.username}</Space>}
        open={creditModal.open}
        onOk={handleAdjustCredits}
        onCancel={() => { setCreditModal({ open: false, user: null }); form.resetFields(); }}
        okText="确认" cancelText="取消" width={440}
      >
        <div style={{ marginBottom: 16, padding: '12px 16px', background: '#f8fafc', borderRadius: 8 }}>
          <span style={{ color: '#64748b' }}>当前积分：</span>
          <span style={{ fontWeight: 800, fontSize: 18, color: '#6366f1' }}>
            {creditModal.user?.credits.toLocaleString()}
          </span>
        </div>
        <Form form={form} layout="vertical">
          <Form.Item name="amount" label="积分变动"
            rules={[{ required: true, message: '请输入积分数量' }]}>
            <InputNumber
              style={{ width: '100%' }}
              size="large"
              placeholder="正数增加，负数扣除"
              formatter={v => `${v}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}
            />
          </Form.Item>
          <Form.Item name="description" label="原因"
            rules={[{ required: true, message: '请输入调整原因' }]}>
            <Input.TextArea rows={2} placeholder="请输入调整原因" size="large" />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title={<Space><TeamOutlined />团队设置 - {teamModal.user?.username}</Space>}
        open={teamModal.open}
        confirmLoading={teamSaving}
        onOk={handleSaveTeam}
        onCancel={() => { setTeamModal({ open: false, user: null }); teamForm.resetFields(); }}
        okText="保存" cancelText="取消" width={460}
      >
        <Form form={teamForm} layout="vertical" style={{ marginTop: 16 }}>
          <Form.Item name="teamId" label="所属团队" extra="团队归属独立于前台内部/外部归类，不会改变用户内外部设置。">
            <Select
              size="large"
              allowClear
              placeholder="未分配团队"
              options={[
                { value: '', label: '未分配团队' },
                ...teamOptions
                  .filter(t => t.status === 'active' || t.id === teamModal.user?.teamId)
                  .map(t => ({ value: t.id, label: t.status === 'disabled' ? `${t.name}（禁用）` : t.name })),
              ]}
            />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title={<Space><DatabaseOutlined />容量设置 - {capacityModal.user?.username}</Space>}
        open={capacityModal.open}
        confirmLoading={capacitySaving}
        onOk={handleSaveCapacity}
        onCancel={() => { setCapacityModal({ open: false, user: null, detail: null }); capacityForm.resetFields(); }}
        okText="保存个人配置" cancelText="取消" width={560}
      >
        <Card loading={capacityLoading} variant="outlined" style={{ marginBottom: 16 }}>
          <Space direction="vertical" size={6} style={{ width: '100%' }}>
            <Typography.Text type="secondary">
              当前生效来源：{capacitySourceLabel(capacityModal.detail?.effective)}
              {capacityModal.detail?.effective.hasUserConfig ? '（已单独设置）' : '（未单独设置）'}
            </Typography.Text>
            <Typography.Text>
              已用：{formatBytes(capacityModal.detail?.effective.usedBytes)}；
              总量：{formatBytes(capacityModal.detail?.effective.totalBytes)}；
              可用：{formatBytes(capacityModal.detail?.effective.availableBytes)}
            </Typography.Text>
            {capacityModal.detail?.effective.enabled && (
              <Progress
                percent={Math.min(Number(capacityModal.detail.effective.usagePercent || 0), 100)}
                status={capacityModal.detail.effective.exceeded ? 'exception' : 'active'}
              />
            )}
          </Space>
        </Card>
        <Form form={capacityForm} layout="vertical">
          <Form.Item
            name="enabled"
            label="启用个人容量限制"
            valuePropName="checked"
            extra="保存后会生成用户个人配置，优先级高于全局；关闭并保存表示该用户个人明确不限制，不再走全局。"
          >
            <Switch checkedChildren="开启" unCheckedChildren="关闭" />
          </Form.Item>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 180px', gap: 16 }}>
            <Form.Item
              name="limitValue"
              label="容量数值"
              rules={[{ required: true, message: '请输入容量数值' }]}
              extra="最小为1，不能为负数，最多支持3位小数。"
            >
              <InputNumber min={1} precision={3} style={{ width: '100%' }} size="large" placeholder="例如 10.500" />
            </Form.Item>
            <Form.Item
              name="limitUnit"
              label="容量单位"
              rules={[{ required: true, message: '请选择容量单位' }]}
              extra="MB / GB / TB 固定枚举"
            >
              <Select size="large" options={capacityUnitOptions} />
            </Form.Item>
          </div>
        </Form>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 8 }}>
          <Typography.Text type="secondary" style={{ fontSize: 12 }}>
            恢复全局设置会删除该用户个人配置，让用户重新按全局规则判断。
          </Typography.Text>
          <Popconfirm
            title="确定恢复为全局容量配置？"
            onConfirm={handleRestoreGlobalCapacity}
            disabled={!capacityModal.detail?.hasUserConfig}
          >
            <Button disabled={!capacityModal.detail?.hasUserConfig} loading={capacitySaving}>
              恢复全局设置
            </Button>
          </Popconfirm>
        </div>
      </Modal>

      <Modal
        title={<Space><PictureOutlined />私域人像素材库设置 - {portraitModal.user?.username}</Space>}
        open={portraitModal.open}
        confirmLoading={portraitSaving}
        onOk={handleSavePortraitConfig}
        onCancel={() => { setPortraitModal({ open: false, user: null, config: null }); portraitForm.resetFields(); }}
        okText="保存" cancelText="取消" width={520}
      >
        <Card loading={portraitLoading} variant="outlined" style={{ marginBottom: 16 }}>
          <Space direction="vertical" size={6} style={{ width: '100%' }}>
            <Typography.Text>
              当前状态：{portraitModal.config?.enabled ? <Tag color="purple">已开启</Tag> : <Tag>未开启</Tag>}
            </Typography.Text>
            <Typography.Text type="secondary">
              已用：{portraitModal.config?.usedAssetCount ?? '-'} 个；
              剩余：{portraitModal.config?.enabled ? portraitModal.config.remainingAssetCount : 0} 个
            </Typography.Text>
          </Space>
        </Card>
        <Form form={portraitForm} layout="vertical">
          <Form.Item
            name="privatePortraitAssetLimit"
            label="私域人像素材总量上限"
            extra="0 表示关闭私域人像素材库；大于 0 表示开启，并限制该用户所有私域人像素材总量。"
            rules={[{ required: true, message: '请输入私域人像素材总量上限' }]}
          >
            <InputNumber min={0} max={9999} precision={0} style={{ width: '100%' }} size="large" />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title={<Space><UserOutlined />创建用户</Space>}
        open={createModal}
        onOk={handleCreateUser}
        onCancel={() => { setCreateModal(false); createForm.resetFields(); setCreateType('frontend'); }}
        okText="创建" cancelText="取消" width={480}
      >
        <Form form={createForm} layout="vertical" style={{ marginTop: 16 }}
          onValuesChange={(changed) => { if (changed.user_type) setCreateType(changed.user_type); }}
        >
          <Form.Item name="user_type" label="用户类型" initialValue="frontend" rules={[{ required: true }]}>
            <Select size="large" options={[
              { value: 'frontend', label: '前端用户' },
              { value: 'admin', label: '后台管理员' },
            ]} />
          </Form.Item>
          {createType === 'frontend' && (
            <Form.Item name="frontend_user_kind" label="前台归类" initialValue="external">
              <Select size="large" options={[
                { value: 'external', label: '外部用户' },
                { value: 'internal', label: '内部用户' },
              ]} />
            </Form.Item>
          )}
          {createType === 'frontend' ? (
            <Form.Item name="phone" label="手机号" rules={[{ required: true, message: '请输入手机号' }, { pattern: /^1\d{10}$/, message: '请输入正确的手机号' }]}>
              <Input placeholder="请输入手机号" maxLength={11} size="large" />
            </Form.Item>
          ) : (
            <Form.Item name="username" label="用户名" rules={[{ required: true, message: '请输入用户名' }]}>
              <Input placeholder="请输入用户名" size="large" />
            </Form.Item>
          )}
          <Form.Item name="password" label="密码" rules={[{ required: true, min: 6, message: '密码至少6位' }]}>
            <Input.Password placeholder="请输入密码（至少6位）" size="large" />
          </Form.Item>
          {createType === 'frontend' && (
            <Form.Item name="credits" label="初始积分" initialValue={0}>
              <InputNumber min={0} style={{ width: '100%' }} size="large" />
            </Form.Item>
          )}
          {createType === 'frontend' && (
            <Form.Item
              name="private_portrait_asset_limit"
              label="私域人像素材总量上限"
              initialValue={5}
              extra="0 表示关闭私域人像素材库；大于 0 表示开启并限制该用户所有私域人像素材总量。"
              rules={[{ required: true, message: '请输入私域人像素材总量上限' }]}
            >
              <InputNumber min={0} max={9999} precision={0} style={{ width: '100%' }} size="large" />
            </Form.Item>
          )}
          {createType === 'admin' && (
            <Form.Item name="is_admin" label="超级管理员" valuePropName="checked" initialValue={false}>
              <Switch
                checkedChildren="是"
                unCheckedChildren="否"
              />
            </Form.Item>
          )}
          <Form.Item name="email" label="邮箱">
            <Input placeholder="选填" size="large" />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title={<Space><MenuOutlined />菜单权限 - {menuModal.user?.username} ({menuModal.user?.userType === 'admin' ? '后台菜单' : '前台菜单'})</Space>}
        open={menuModal.open}
        onOk={handleSaveMenus}
        onCancel={() => { setMenuModal({ open: false, user: null }); }}
        okText="保存" cancelText="取消" width={520}
      >
        <div style={{ marginBottom: 12 }}>
          <Typography.Text type="secondary" style={{ fontSize: 13 }}>
            勾选该用户可访问的菜单，不勾选则显示全部菜单
          </Typography.Text>
        </div>
        <div style={{ padding: '12px 16px', background: '#f8fafc', borderRadius: 8, maxHeight: 400, overflow: 'auto' }}>
          <Checkbox.Group value={checkedMenus} onChange={(vals) => setCheckedMenus(vals as string[])}>
            <Space direction="vertical" size={8} style={{ width: '100%' }}>
              {topLevelPages.map((m: any) => (
                <Checkbox key={m.path} value={m.path} style={{ width: '100%' }}>
                  {m.label}
                  <Typography.Text type="secondary" style={{ fontSize: 12, marginLeft: 8 }}>{m.path}</Typography.Text>
                </Checkbox>
              ))}
              {menuGroups.map((g: any) => {
                const children = childMap[g.id] || [];
                if (children.length === 0) return null;
                return (
                  <div key={g.id}>
                    <div style={{ fontWeight: 600, fontSize: 13, color: '#6366f1', marginBottom: 4, marginTop: 4 }}>
                      {g.label}
                    </div>
                    <Space direction="vertical" size={4} style={{ paddingLeft: 12, width: '100%' }}>
                      {children.map((c: any) => (
                        <Checkbox key={c.path} value={c.path} style={{ width: '100%' }}>
                          {c.label}
                          <Typography.Text type="secondary" style={{ fontSize: 12, marginLeft: 8 }}>{c.path}</Typography.Text>
                        </Checkbox>
                      ))}
                    </Space>
                  </div>
                );
              })}
            </Space>
          </Checkbox.Group>
        </div>
      </Modal>

      <Modal
        title={<Space><LockOutlined />重置密码 - {resetPwdModal.user?.username}</Space>}
        open={resetPwdModal.open}
        onOk={handleResetPassword}
        onCancel={() => { setResetPwdModal({ open: false, user: null }); resetPwdForm.resetFields(); }}
        okText="确认重置" cancelText="取消" width={420}
      >
        <Form form={resetPwdForm} layout="vertical" style={{ marginTop: 16 }}>
          <Form.Item name="newPassword" label="新密码" rules={[{ required: true, min: 6, message: '密码至少6位' }]}>
            <Input.Password placeholder="请输入新密码（至少6位）" size="large" />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

export default AdminUsers;
