import { useEffect, useState, useMemo, useCallback } from 'react';
import {
  Table, Button, Select, message, Tag, Space, InputNumber, Tooltip, Popconfirm, theme,
} from 'antd';
import { PlayCircleOutlined, StopOutlined, FilterOutlined, ThunderboltOutlined, ReloadOutlined, DeleteOutlined } from '@ant-design/icons';
import { accountApi, loginApi, type AccountItem, type LoginTaskItem } from '../api/modules';
import RealtimeLogPanel from '../components/RealtimeLogPanel';
import { usePermissions } from '../hooks/usePermissions';
import { useWebSocketLogs } from '../hooks/useWebSocketLogs';
import { formatTime } from '../utils/time';
import { getErrorMessage } from '../utils/error';

const STATUS_COLORS: Record<string, string> = {
  pending: 'default',
  running: 'processing',
  success: 'success',
  failed: 'error',
  error: 'error',
};

const STATUS_LABELS: Record<string, string> = {
  pending: '等待中',
  running: '登录中',
  success: '成功',
  failed: '失败',
  error: '异常',
};

interface SelectGroupOption {
  label: string;
  options: { value: number; label: string }[];
}

export default function LoginTasksPage() {
  const [accounts, setAccounts] = useState<AccountItem[]>([]);
  const [selectedIds, setSelectedIds] = useState<number[]>([]);
  const [tasks, setTasks] = useState<LoginTaskItem[]>([]);
  const [loading, setLoading] = useState(false);
  const [batchId, setBatchId] = useState<string | null>(null);
  const [selectedTags, setSelectedTags] = useState<string[]>([]);
  const [concurrency, setConcurrency] = useState(() => {
    const v = localStorage.getItem('login_concurrency');
    return v ? Math.max(1, Math.min(10, Number(v) || 3)) : 3;
  });

  // 值变化时自动持久化
  useEffect(() => { localStorage.setItem('login_concurrency', String(concurrency)); }, [concurrency]);
  const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([]);
  const { logs, connected: wsConnected, connect: connectLogs } = useWebSocketLogs();
  const { can } = usePermissions();

  const { token } = theme.useToken();

  const canBatch = can('login:batch');

  // 从账号中提取所有标签
  const allTags = useMemo(() => {
    const tags = [...new Set(accounts.map((a) => (a.tag || '').trim()).filter(Boolean))];
    return tags.sort();
  }, [accounts]);

  // 标签→账号ID映射
  const tagAccountMap = useMemo(() => {
    const map: Record<string, number[]> = {};
    accounts.forEach((a) => {
      const tag = (a.tag || '').trim();
      if (tag) {
        if (!map[tag]) map[tag] = [];
        map[tag].push(a.id);
      }
    });
    return map;
  }, [accounts]);

  const loadAccounts = useCallback(async () => {
    try {
      const data = await accountApi.list();
      setAccounts(data);
    } catch (e: unknown) {
      message.error(getErrorMessage(e));
    }
  }, []);

  // 标签选择变化时，同步更新选中的账号
  const handleTagChange = useCallback((tags: string[]) => {
    setSelectedTags(tags);

    setSelectedIds((prev) => {
      const prevTagSet = new Set(selectedTags);
      const newTagSet = new Set(tags);

      // 新增的标签
      const addedTags = tags.filter((t) => !prevTagSet.has(t));
      // 移除的标签
      const removedTags = selectedTags.filter((t) => !newTagSet.has(t));

      // 收集被移除标签下的所有账号ID
      const removedIds = new Set(removedTags.flatMap((t) => tagAccountMap[t] || []));
      // 收集新增标签下的所有账号ID
      const addedIds = addedTags.flatMap((t) => tagAccountMap[t] || []);

      // 保留手动选择的账号（不属于任何已选标签的），移除被取消标签的账号，添加新选标签的账号
      const manualIds = prev.filter((id) => {
        const acc = accounts.find((a) => a.id === id);
        if (!acc) return false;
        const accTag = (acc.tag || '').trim();
        // 保留不属于当前任何已选标签、也不属于被移除标签的
        return !prevTagSet.has(accTag) && !removedIds.has(id);
      });

      return [...new Set([...manualIds, ...addedIds])];
    });
  }, [selectedTags, tagAccountMap, accounts]);

  const loadTasks = useCallback(async () => {
    try {
      const data = await loginApi.listTasks(batchId || undefined);
      setTasks(data);
    } catch {
      // 忽略轮询失败，下一次定时刷新会继续尝试。
    }
  }, [batchId]);

  useEffect(() => {
    Promise.all([loadAccounts(), loadTasks()]);
  }, [loadAccounts, loadTasks]);

  useEffect(() => {
    const timer = setInterval(loadTasks, 3000);
    return () => clearInterval(timer);
  }, [loadTasks]);

  // 共享的批量登录启动逻辑
  const startBatch = async (accountIds: number[]) => {
    if (accountIds.length === 0) {
      message.warning('请选择账号');
      return;
    }
    setLoading(true);
    try {
      const result = await loginApi.createBatch({
        account_ids: accountIds,
        concurrency,
      });
      setBatchId(result.batch_id);
      message.success(`已创建登录任务，共 ${result.count} 个账号`);

      connectLogs(`/api/login/ws/login/${result.batch_id}`, {
        onClose: () => setBatchId(null),
        onResult: () => setBatchId(null),
      });
    } catch (e: unknown) {
      message.error(getErrorMessage(e));
    } finally {
      setLoading(false);
    }
  };

  const handleBatchLogin = () => startBatch(selectedIds);

  // 重试当前批次所有失败的任务
  const handleRetryFailed = () => {
    const failedIds = tasks
      .filter((t) => ['failed', 'error'].includes(t.status))
      .map((t) => t.account_id);
    if (failedIds.length === 0) {
      message.info('没有失败的任务');
      return;
    }
    startBatch(failedIds);
  };

  // 重试单个失败任务
  const handleRetryOne = (taskId: number) => {
    const task = tasks.find((t) => t.id === taskId);
    if (!task) return;
    startBatch([task.account_id]);
  };

  const handleStop = async () => {
    if (batchId) {
      try {
        await loginApi.stop(batchId);
        message.success('已发送停止信号');
      } catch (e: unknown) {
        message.error(getErrorMessage(e));
      }
    }
  };

  const handleDeleteTask = async (taskId: number) => {
    try {
      await loginApi.deleteTask(taskId);
      message.success('已删除');
      loadTasks();
      setSelectedRowKeys((prev) => prev.filter((k) => k !== taskId));
    } catch (e: unknown) {
      message.error(getErrorMessage(e));
    }
  };

  const handleDeleteSelected = async () => {
    if (selectedRowKeys.length === 0) {
      message.warning('请选择要删除的任务');
      return;
    }
    try {
      await loginApi.deleteTasks(selectedRowKeys);
      message.success(`已删除 ${selectedRowKeys.length} 个任务`);
      setSelectedRowKeys([]);
      loadTasks();
    } catch (e: unknown) {
      message.error(getErrorMessage(e));
    }
  };

  const successCount = tasks.filter((t) => t.status === 'success').length;
  const failedCount = tasks.filter((t) => ['failed', 'error'].includes(t.status)).length;

  const columns = [
    { title: 'ID', dataIndex: 'id', width: 60 },
    { title: '账号', dataIndex: 'account_username' },
    {
      title: '状态',
      dataIndex: 'status',
      render: (status: string) => <Tag color={STATUS_COLORS[status]}>{STATUS_LABELS[status] || status}</Tag>,
    },
    { title: '消息', dataIndex: 'message', ellipsis: true },
    { title: '时间', dataIndex: 'created_at', width: 180, render: (val: string) => formatTime(val) },
    {
      title: '操作',
      width: 120,
      render: (_: unknown, record: LoginTaskItem) => (
        <Space size={4}>
          {['failed', 'error'].includes(record.status) && !wsConnected && (
            <Button
              type="link"
              size="small"
              icon={<ReloadOutlined />}
              onClick={() => handleRetryOne(record.id)}
            >
              重试
            </Button>
          )}
          <Popconfirm title="确定删除此任务？" onConfirm={() => handleDeleteTask(record.id)} okText="删除" cancelText="取消">
            <Button type="link" size="small" danger icon={<DeleteOutlined />} />
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      {/* 标题 + 筛选栏 */}
      <div style={{ flexShrink: 0, paddingBottom: 8, borderBottom: `1px solid ${token.colorBorderSecondary}` }}>
        <h2 style={{ marginTop: 0, marginBottom: 6 }}>登录任务</h2>
        {canBatch && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
            {allTags.length > 0 && (
              <Select
                mode="multiple"
                style={{ minWidth: 200, maxWidth: 300 }}
                placeholder="按标签筛选"
                value={selectedTags}
                onChange={handleTagChange}
                options={allTags.map((t) => ({ value: t, label: t }))}
                maxTagCount="responsive"
                allowClear
                size="small"
                suffixIcon={<FilterOutlined />}
              />
            )}
            <Select
              mode="multiple"
              style={{ minWidth: 280, flex: 1, maxWidth: 500 }}
              placeholder="选择账号"
              value={selectedIds}
              onChange={setSelectedIds}
              options={(() => {
                const grouped: Record<string, { value: number; label: string }[]> = {};
                const noTag: { value: number; label: string }[] = [];
                accounts.forEach((a) => {
                  const tag = (a.tag || '').trim();
                  if (tag) {
                    if (!grouped[tag]) grouped[tag] = [];
                    grouped[tag].push({ value: a.id, label: a.username });
                  } else {
                    noTag.push({ value: a.id, label: a.username });
                  }
                });
                const result: SelectGroupOption[] = [];
                Object.keys(grouped).sort().forEach((tag) => {
                  result.push({ label: tag, options: grouped[tag] });
                });
                if (noTag.length > 0) {
                  result.push({ label: '未分组', options: noTag });
                }
                return result;
              })()}
              maxTagCount="responsive"
              showSearch
              size="small"
              filterOption={(input, option) => {
                if (!option) return false;
                const label = (option as { label?: string }).label || '';
                return label.toLowerCase().includes(input.toLowerCase());
              }}
              dropdownRender={(menu) => (
                <>
                  <div style={{ padding: '4px 8px', borderBottom: `1px solid ${token.colorBorderSecondary}`, display: 'flex', gap: 8 }}>
                    <Button size="small" type="link" onClick={() => { setSelectedIds(accounts.map((a) => a.id)); setSelectedTags([]); }}>
                      全选 ({accounts.length})
                    </Button>
                    <Button size="small" type="link" onClick={() => { setSelectedIds([]); setSelectedTags([]); }}>
                      清空
                    </Button>
                  </div>
                  {menu}
                </>
              )}
            />
            {selectedTags.length > 0 && (
              <span style={{ color: token.colorTextSecondary, fontSize: 12, whiteSpace: 'nowrap' }}>
                标签选中 {accounts.filter((a) => selectedTags.includes((a.tag || '').trim())).length} 个
              </span>
            )}
            <Tooltip title="同时登录的账号数，1为顺序执行">
              <Space size={4}>
                <ThunderboltOutlined style={{ color: token.colorTextSecondary }} />
                <InputNumber
                  min={1}
                  max={10}
                  value={concurrency}
                  onChange={(v) => setConcurrency(v || 1)}
                  style={{ width: 50 }}
                  size="small"
                />
              </Space>
            </Tooltip>
            <Button
              type="primary"
              icon={<PlayCircleOutlined />}
              loading={loading}
              onClick={handleBatchLogin}
              disabled={selectedIds.length === 0 || wsConnected}
              size="small"
            >
              开始登录
            </Button>
            {batchId && (
              <Button danger icon={<StopOutlined />} onClick={handleStop} size="small">
                停止
              </Button>
            )}
          </div>
        )}
      </div>

      {/* 概览 + 任务列表区域 */}
      <div style={{ flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column', paddingTop: 6 }}>
        {/* 概览 */}
        <div style={{ flexShrink: 0, display: 'flex', alignItems: 'center', gap: 16, fontSize: 13, color: token.colorTextSecondary, padding: '4px 0' }}>
          <span>共 <b>{tasks.length}</b> 个任务</span>
          <span>成功 <b style={{ color: token.colorSuccess }}>{successCount}</b></span>
          <span>失败 <b style={{ color: token.colorError }}>{failedCount}</b></span>
          {batchId && <span>批次: <b>{batchId}</b></span>}
          <div style={{ flex: 1 }} />
          {selectedRowKeys.length > 0 && (
            <Popconfirm title={`确定删除选中的 ${selectedRowKeys.length} 个任务？`} onConfirm={handleDeleteSelected} okText="删除" cancelText="取消">
              <Button type="link" size="small" danger icon={<DeleteOutlined />}>
                删除选中 ({selectedRowKeys.length})
              </Button>
            </Popconfirm>
          )}
          {!wsConnected && failedCount > 0 && (
            <Button
              type="link"
              size="small"
              icon={<ReloadOutlined />}
              onClick={handleRetryFailed}
              loading={loading}
            >
              重试失败 ({failedCount})
            </Button>
          )}
        </div>

        {/* 任务列表 - flex:1 占满剩余空间，内部滚动 */}
        <div style={{ flex: 1, minHeight: 0, overflow: 'auto' }}>
          <Table
            columns={columns}
            dataSource={tasks}
            rowKey="id"
            size="small"
            pagination={false}
            sticky
            rowSelection={{
              selectedRowKeys,
              onChange: (keys) => setSelectedRowKeys(keys as number[]),
            }}
          />
        </div>
      </div>

      {/* 实时日志 - 底部可折叠 */}
      <RealtimeLogPanel
        logs={logs}
        connected={wsConnected}
        collapsible
        spinWhenEmpty
        style={{ marginTop: 4 }}
      />
    </div>
  );
}
