import { useEffect, useState, useMemo, useCallback } from 'react';
import {
  Alert, Table, Button, Modal, Input, Select, Popconfirm, Typography, Tag, Space,
  Row, Col, Card, Statistic,
} from 'antd';
import { message } from '../utils/antdMessage';
import type { TableProps } from 'antd';
import { ImportOutlined, DeleteOutlined, TagOutlined, FilterOutlined, EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons';
import { accountApi, userApi, type AccountItem, type BasicSummary, type UserInfo } from '../api/modules';
import { usePermissions } from '../hooks/usePermissions';
import { formatTime } from '../utils/time';
import { getErrorMessage } from '../utils/error';

const { TextArea } = Input;
const { Text } = Typography;

const TAG_COLORS = [
  'blue', 'green', 'cyan', 'geekblue', 'purple', 'orange', 'magenta', 'volcano',
];

export default function AccountsPage() {
  const [accounts, setAccounts] = useState<AccountItem[]>([]);
  const [users, setUsers] = useState<UserInfo[]>([]);
  const [tags, setTags] = useState<string[]>([]);
  const [loading, setLoading] = useState(false);
  const [importOpen, setImportOpen] = useState(false);
  const [importText, setImportText] = useState('');
  const [importTag, setImportTag] = useState('');
  const [importing, setImporting] = useState(false);
  const [tagFilter, setTagFilter] = useState<string>('');
  const [searchText, setSearchText] = useState('');
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  const [selectedAllMatching, setSelectedAllMatching] = useState(false);
  const [batchTagInput, setBatchTagInput] = useState('');
  const [batchTagVisible, setBatchTagVisible] = useState(false);
  const [sensitiveVisible, setSensitiveVisible] = useState(false);
  const [total, setTotal] = useState(0);
  const [summary, setSummary] = useState<BasicSummary>({ total: 0, assigned_count: 0, unassigned_count: 0, tag_count: 0 });
  const [pageSize, setPageSize] = useState(() => {
    const v = localStorage.getItem('account_page_size');
    return v ? Number(v) || 20 : 20;
  });
  const [currentPage, setCurrentPage] = useState(1);
  const { can } = usePermissions();

  const canViewFull = can('account:view_full');
  const canImport = can('account:import');
  const canTag = can('account:tag') || canImport;
  const canAssign = can('account:assign');
  const canDelete = can('account:delete');
  const canSelectRows = canTag || canDelete || canAssign;

  const loadAccounts = useCallback(async () => {
    setLoading(true);
    try {
      const params: { tag?: string } = {};
      if (tagFilter) params.tag = tagFilter;
      const data = await accountApi.listPaged({
        ...params,
        page: currentPage,
        page_size: pageSize,
        search: searchText.trim() || undefined,
        include_sensitive: canViewFull && sensitiveVisible,
      });
      setAccounts(data.items);
      setTotal(data.total);
    } catch (e: unknown) {
      message.error(getErrorMessage(e));
    } finally {
      setLoading(false);
    }
  }, [canViewFull, currentPage, pageSize, searchText, sensitiveVisible, tagFilter]);

  const loadSummary = useCallback(async () => {
    try {
      const data = await accountApi.summary();
      setSummary(data);
    } catch {
      // 统计加载失败时不影响主列表操作。
    }
  }, []);

  const loadUsers = useCallback(async () => {
    try {
      const data = await userApi.list();
      setUsers(data.filter((u) => u.role === 'support'));
    } catch {
      // 忽略客服列表加载失败，账号列表仍可继续使用。
    }
  }, []);

  const loadTags = useCallback(async () => {
    try {
      const data = await accountApi.listTags();
      setTags(data);
    } catch {
      // 忽略标签加载失败，页面会退化为无标签筛选。
    }
  }, []);

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

  useEffect(() => {
    if (canAssign) loadUsers();
    loadTags();
    loadSummary();
  }, [canAssign, loadUsers, loadTags, loadSummary]);

  const tagColorMap = useMemo(() => {
    const map: Record<string, string> = {};
    tags.forEach((t, i) => {
      map[t] = TAG_COLORS[i % TAG_COLORS.length];
    });
    return map;
  }, [tags]);

  const selectedCount = selectedAllMatching ? total : selectedRowKeys.length;
  const selectionPayload = useMemo(() => ({
    account_ids: selectedAllMatching ? [] : selectedRowKeys.map((key) => Number(key)),
    all_matching: selectedAllMatching,
    search: searchText.trim(),
    tag: tagFilter,
  }), [searchText, selectedAllMatching, selectedRowKeys, tagFilter]);

  const clearSelection = () => {
    setSelectedRowKeys([]);
    setSelectedAllMatching(false);
  };

  useEffect(() => {
    clearSelection();
  }, [searchText, tagFilter]);

  const handleImport = async () => {
    if (!importText.trim()) {
      message.warning('请输入账号数据');
      return;
    }
    setImporting(true);
    try {
      const result = await accountApi.import(importText, importTag);
      message.success(result.message);
      setImportOpen(false);
      setImportText('');
      setImportTag('');
      loadAccounts();
      loadTags();
      loadSummary();
    } catch (e: unknown) {
      message.error(getErrorMessage(e));
    } finally {
      setImporting(false);
    }
  };

  const handleAssign = async (accountId: number, assignedTo: number | null) => {
    try {
      await accountApi.assign(accountId, assignedTo);
      message.success('已分配');
      loadAccounts();
    } catch (e: unknown) {
      message.error(getErrorMessage(e));
    }
  };

  const handleSetTag = async (accountId: number, tag: string) => {
    try {
      await accountApi.setTag(accountId, tag);
      message.success('标签已更新');
      loadAccounts();
      loadTags();
    } catch (e: unknown) {
      message.error(getErrorMessage(e));
    }
  };

  const handleBatchTag = async () => {
    if (selectedCount === 0) {
      message.warning('请先选择账号');
      return;
    }
    try {
      const result = await accountApi.batchTagSelection({ ...selectionPayload, tag_value: batchTagInput });
      message.success(result.message);
      setBatchTagVisible(false);
      setBatchTagInput('');
      clearSelection();
      loadAccounts();
      loadTags();
      loadSummary();
    } catch (e: unknown) {
      message.error(getErrorMessage(e));
    }
  };

  const handleDelete = async (id: number) => {
    try {
      await accountApi.delete(id);
      message.success('已删除');
      setSelectedRowKeys((prev) => prev.filter((k) => k !== id));
      setSelectedAllMatching(false);
      loadAccounts();
      loadTags();
      loadSummary();
    } catch (e: unknown) {
      message.error(getErrorMessage(e));
    }
  };

  const handleBatchDelete = async () => {
    if (selectedCount === 0) {
      message.warning('请先选择账号');
      return;
    }
    try {
      const result = await accountApi.batchDeleteSelection(selectionPayload);
      message.success(result.message);
      clearSelection();
      loadAccounts();
      loadTags();
      loadSummary();
    } catch (e: unknown) {
      message.error(getErrorMessage(e));
    }
  };

  const handleSensitiveVisibility = () => {
    if (sensitiveVisible) {
      // 立即清除已加载的敏感内容，再由 effect 重新获取脱敏列表。
      setAccounts((previous) => previous.map((account) => ({
        ...account,
        password: undefined,
        email: undefined,
        email_password: undefined,
      })));
      setSensitiveVisible(false);
      return;
    }
    Modal.confirm({
      title: '显示账号凭据？',
      content: '密码、邮箱和邮箱密码将临时显示在当前页面。关闭或刷新页面后会恢复脱敏。',
      okText: '显示',
      cancelText: '取消',
      onOk: () => setSensitiveVisible(true),
    });
  };

  const columns: TableProps<AccountItem>['columns'] = [
    { title: 'ID', dataIndex: 'id', width: 60 },
    { title: '用户名', dataIndex: 'username' },
    {
      title: '标签',
      dataIndex: 'tag',
      width: 170,
      render: (tag: string, record: AccountItem) => {
        if (canTag) {
          return (
            <Select
              mode="tags"
              maxCount={1}
              allowClear
              showSearch
              optionFilterProp="label"
              size="small"
              placeholder="选择或输入标签"
              style={{ width: 150 }}
              value={tag ? [tag] : []}
              onChange={(values) => {
                const value = values.at(-1)?.trim() || '';
                if (value !== tag) handleSetTag(record.id, value);
              }}
              options={tags.map((value) => ({ value, label: value }))}
            />
          );
        }
        return tag ? <Tag color={tagColorMap[tag]}>{tag}</Tag> : <Text type="secondary">-</Text>;
      },
    },
    {
      title: '上传时间',
      dataIndex: 'created_at',
      width: 180,
      render: (val: string | null) => val ? formatTime(val) : <Text type="secondary">-</Text>,
    },
  ];

  if (canViewFull && sensitiveVisible) {
    columns.push(
      { title: '密码', dataIndex: 'password', width: 120 },
      { title: '邮箱', dataIndex: 'email' },
      { title: '邮箱密码', dataIndex: 'email_password', width: 120 },
    );
  }

  columns.push({
    title: '分配给',
    dataIndex: 'assigned_username',
    render: (_: unknown, record: AccountItem) => {
      if (canAssign) {
        return (
          <Select
            style={{ width: 140 }}
            allowClear
            placeholder="未分配"
            value={record.assigned_to}
            onChange={(val) => handleAssign(record.id, val ?? null)}
            options={users.map((u) => ({ value: u.id, label: u.username }))}
          />
        );
      }
      return record.assigned_username || <Text type="secondary">未分配</Text>;
    },
  });

  if (canDelete) {
    columns.push({
      title: '操作',
      width: 80,
      render: (_: unknown, record: AccountItem) => (
        <Popconfirm title="确认删除？" onConfirm={() => handleDelete(record.id)}>
          <Button danger size="small" icon={<DeleteOutlined />}>删除</Button>
        </Popconfirm>
      ),
    });
  }

  return (
    <div>
      <div style={{ marginBottom: 16, display: 'flex', justifyContent: 'space-between' }}>
        <h2>账号管理</h2>
        <Space>
          <Select
            allowClear
            showSearch
            optionFilterProp="label"
            placeholder="按标签筛选"
            style={{ width: 150 }}
            value={tagFilter || undefined}
            onChange={(val) => {
              setTagFilter(val || '');
              setCurrentPage(1);
            }}
            options={tags.map((t) => ({ value: t, label: t }))}
            prefix={<FilterOutlined />}
          />
          <Input.Search
            allowClear
            size="small"
            placeholder="搜索账号/标签/备注"
            style={{ width: 220 }}
            value={searchText}
            onChange={(e) => {
              setSearchText(e.target.value);
              setCurrentPage(1);
            }}
          />
          {canViewFull && (
            <Button
              icon={sensitiveVisible ? <EyeInvisibleOutlined /> : <EyeOutlined />}
              onClick={handleSensitiveVisibility}
            >
              {sensitiveVisible ? '隐藏凭据' : '显示凭据'}
            </Button>
          )}
          {canTag && (
            <Button
              disabled={selectedCount === 0}
              icon={<TagOutlined />}
              onClick={() => {
                setBatchTagInput('');
                setBatchTagVisible(true);
              }}
            >
              批量打标签
            </Button>
          )}
          {canDelete && (
            <Popconfirm
              title={`确认删除${selectedAllMatching ? '当前筛选下' : '选中的'} ${selectedCount} 个账号？`}
              description="将同时删除关联的登录任务"
              onConfirm={handleBatchDelete}
              okText="删除"
              okButtonProps={{ danger: true }}
              cancelText="取消"
            >
              <Button
                danger
                disabled={selectedCount === 0}
                icon={<DeleteOutlined />}
              >
                批量删除
              </Button>
            </Popconfirm>
          )}
          {canImport && (
            <Button type="primary" icon={<ImportOutlined />} onClick={() => { setImportTag(''); setImportOpen(true); }}>
              批量导入
            </Button>
          )}
        </Space>
      </div>

      <Row gutter={16} style={{ marginBottom: 16 }}>
        <Col span={6}>
          <Card size="small"><Statistic title="账号总数" value={summary.total} /></Card>
        </Col>
        <Col span={6}>
          <Card size="small"><Statistic title="标签数" value={summary.tag_count || tags.length} /></Card>
        </Col>
        <Col span={6}>
          <Card size="small">
            <Statistic
              title="已分配"
              value={summary.assigned_count}
            />
          </Card>
        </Col>
        <Col span={6}>
          <Card size="small">
            <Statistic
              title="未分配"
              value={summary.unassigned_count}
            />
          </Card>
        </Col>
      </Row>

      <Table
        title={() => selectedRowKeys.length > 0 ? (
          <Alert
            type="info"
            showIcon
            message={(
              <Space wrap>
                <span>
                  {selectedAllMatching
                    ? `已选择当前筛选下全部 ${total} 个账号`
                    : `已选择 ${selectedRowKeys.length} 个账号`}
                </span>
                {!selectedAllMatching && total > selectedRowKeys.length ? (
                  <Button size="small" type="link" onClick={() => setSelectedAllMatching(true)}>
                    选择当前筛选下全部 {total} 个
                  </Button>
                ) : null}
                <Button size="small" type="link" onClick={clearSelection}>
                  取消选择
                </Button>
              </Space>
            )}
          />
        ) : undefined}
        rowSelection={canSelectRows ? {
          selectedRowKeys,
          onChange: (keys) => {
            setSelectedRowKeys(keys);
            setSelectedAllMatching(false);
          },
          preserveSelectedRowKeys: true,
        } : undefined}
        columns={columns}
        dataSource={accounts}
        rowKey="id"
        loading={loading}
        size="small"
        pagination={{
          current: currentPage,
          pageSize,
          total,
          showSizeChanger: true,
          showTotal: (t) => `共 ${t} 条`,
          onChange: (page, size) => {
            setCurrentPage(page);
            if (size !== pageSize) {
              setPageSize(size);
              localStorage.setItem('account_page_size', String(size));
              setCurrentPage(1); // 切换 pageSize 时重置到第1页
            }
          },
        }}
      />

      <Modal
        title="批量导入账号"
        open={importOpen}
        onCancel={() => setImportOpen(false)}
        onOk={handleImport}
        confirmLoading={importing}
        okText="导入"
        width={600}
      >
        <Text type="secondary">
          格式：用户名|密码|邮箱|邮箱密码|标签（可选，每行一个）
        </Text>
        <TextArea
          rows={10}
          value={importText}
          onChange={(e) => setImportText(e.target.value)}
          placeholder={`用户名|密码|邮箱|邮箱密码|标签\n用户名|密码|邮箱|邮箱密码|标签`}
          style={{ marginTop: 8 }}
        />
        <div style={{ marginTop: 12 }}>
          <Text type="secondary">统一标签（可选）：未在行内写标签的账号将使用此标签</Text>
          <Select
            mode="tags"
            style={{ width: '100%', marginTop: 4 }}
            placeholder="输入或选择标签"
            value={importTag ? [importTag] : []}
            onChange={(vals) => setImportTag(vals.length > 0 ? vals[vals.length - 1] : '')}
            options={tags.map((t) => ({ value: t, label: t }))}
          />
        </div>
      </Modal>

      <Modal
        title="批量设置标签"
        open={batchTagVisible}
        onCancel={() => setBatchTagVisible(false)}
        onOk={handleBatchTag}
        okText="确定"
        width={400}
      >
        <p>为{selectedAllMatching ? '当前筛选下' : '选中的'} {selectedCount} 个账号设置标签：</p>
        <Select
          mode="tags"
          style={{ width: '100%' }}
          placeholder="输入或选择标签"
          value={batchTagInput ? [batchTagInput] : []}
          onChange={(vals) => setBatchTagInput(vals.length > 0 ? vals[vals.length - 1] : '')}
          options={tags.map((t) => ({ value: t, label: t }))}
        />
      </Modal>
    </div>
  );
}
