import { useEffect, useState, useCallback } from 'react';
import { Table, Button, Card, Row, Col, Statistic, message, Tag, Popconfirm, Space, Typography, Input, theme, Dropdown } from 'antd';
import { DownloadOutlined, DeleteOutlined, CopyOutlined, SearchOutlined } from '@ant-design/icons';
import { cookieApi, type CookieItem } from '../api/modules';
import { usePermissions } from '../hooks/usePermissions';
import { formatTime } from '../utils/time';
import { getErrorMessage } from '../utils/error';

const { Text } = Typography;

/** 复制文本到剪贴板，兼容非安全上下文（http://非localhost） */
function copyToClipboard(text: string): Promise<void> {
  if (navigator.clipboard?.writeText) {
    return navigator.clipboard.writeText(text);
  }
  // fallback：利用 textarea + execCommand，兼容 http 远程访问
  return new Promise((resolve, reject) => {
    const ta = document.createElement('textarea');
    ta.value = text;
    ta.style.position = 'fixed';
    ta.style.left = '-9999px';
    document.body.appendChild(ta);
    ta.select();
    try {
      const ok = document.execCommand('copy');
      document.body.removeChild(ta);
      if (ok) {
        resolve();
      } else {
        reject(new Error('execCommand copy failed'));
      }
    } catch (e) {
      document.body.removeChild(ta);
      reject(e);
    }
  });
}

export default function CookiePage() {
  const { token } = theme.useToken();
  const [cookies, setCookies] = useState<CookieItem[]>([]);
  const [loading, setLoading] = useState(false);
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  const [searchText, setSearchText] = useState('');
  const [pageSize, setPageSize] = useState(() => {
    const v = localStorage.getItem('cookie_page_size');
    return v ? Number(v) || 20 : 20;
  });
  const [currentPage, setCurrentPage] = useState(1);
  const { can } = usePermissions();

  const canView = can('cookie:view');
  const canExport = can('cookie:export');

  const loadCookies = useCallback(async () => {
    setLoading(true);
    try {
      const data = await cookieApi.list();
      setCookies(data);
    } catch (e: unknown) {
      message.error(getErrorMessage(e));
    } finally {
      setLoading(false);
    }
  }, []);

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

  const handleExport = async (format: string = 'csv') => {
    try {
      const blob = await cookieApi.exportCsv(format);
      const url = URL.createObjectURL(blob instanceof Blob ? blob : new Blob([blob]));
      const a = document.createElement('a');
      a.href = url;
      a.download = format === 'custom' ? 'cookies_custom.txt' : 'cookies.csv';
      a.click();
      URL.revokeObjectURL(url);
      message.success('已导出');
    } catch (e: unknown) {
      message.error(getErrorMessage(e));
    }
  };

  const handleCopyCookie = (cookie: string, username: string) => {
    if (!cookie) {
      message.warning('Cookie 为空');
      return;
    }
    copyToClipboard(cookie).then(() => {
      message.success(`已复制 ${username} 的 Cookie`);
    }).catch(() => {
      message.error('复制失败');
    });
  };

  const handleCopySelected = () => {
    if (selectedRowKeys.length === 0) {
      message.warning('请先选择 Cookie');
      return;
    }
    const selected = cookies.filter((c) => selectedRowKeys.includes(c.id));
    const text = selected
      .map((c) => `${c.account_username}: ${c.cookie || '(空)'}`)
      .join('\n');
    copyToClipboard(text).then(() => {
      message.success(`已复制 ${selected.length} 条 Cookie`);
    }).catch(() => {
      message.error('复制失败');
    });
  };

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

  const handleDeleteSelected = async () => {
    if (selectedRowKeys.length === 0) {
      message.warning('请先选择要删除的 Cookie');
      return;
    }
    try {
      const ids = selectedRowKeys.map((k) => Number(k));
      const res = await cookieApi.deleteBatch(ids);
      message.success(res.message);
      setSelectedRowKeys([]);
      loadCookies();
    } catch (e: unknown) {
      message.error(getErrorMessage(e));
    }
  };

  // 筛选
  const filteredCookies = cookies.filter((c) => {
    if (!searchText) return true;
    const s = searchText.toLowerCase();
    return (
      c.account_username?.toLowerCase().includes(s) ||
      c.assigned_username?.toLowerCase().includes(s)
    );
  });

  const columns = [
    { title: 'ID', dataIndex: 'id', width: 60, align: 'center' as const },
    {
      title: '账号',
      dataIndex: 'account_username',
      width: 140,
      ellipsis: true,
    },
    {
      title: '分配',
      dataIndex: 'assigned_username',
      width: 100,
      align: 'center' as const,
      render: (name: string | null) =>
        name ? <Tag color="green">{name}</Tag> : <Text type="secondary" style={{ fontSize: 12 }}>未分配</Text>,
    },
    {
      title: 'Cookie',
      dataIndex: 'cookie_preview',
      ellipsis: true,
      render: (val: string) => {
        if (!canView) return <Tag>***</Tag>;
        return <span style={{ fontFamily: 'monospace', fontSize: 12 }}>{val}</span>;
      },
    },
    {
      title: '时间',
      dataIndex: 'created_at',
      width: 180,
      align: 'center' as const,
      render: (val: string) => formatTime(val),
    },
    {
      title: '操作',
      width: 130,
      align: 'center' as const,
      fixed: 'right' as const,
      render: (_: unknown, record: CookieItem) => (
        <Space size={4}>
          <Button
            size="small"
            icon={<CopyOutlined />}
            onClick={() => handleCopyCookie(record.cookie, record.account_username)}
          >
            复制
          </Button>
          {canExport && (
            <Popconfirm title="确认删除？" onConfirm={() => handleDelete(record.id)}>
              <Button danger size="small" icon={<DeleteOutlined />} />
            </Popconfirm>
          )}
        </Space>
      ),
    },
  ];

  const assignedCount = cookies.filter((c) => c.assigned_to).length;
  const unassignedCount = cookies.length - assignedCount;

  return (
    <div>
      <div style={{ marginBottom: 16, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <h2 style={{ margin: 0 }}>Cookie 管理</h2>
        <Space>
          <Button
            icon={<CopyOutlined />}
            onClick={handleCopySelected}
            disabled={selectedRowKeys.length === 0}
          >
            复制选中 {selectedRowKeys.length > 0 && `(${selectedRowKeys.length})`}
          </Button>
          {canExport && (
            <Popconfirm
              title={`确认删除选中的 ${selectedRowKeys.length} 条 Cookie？`}
              onConfirm={handleDeleteSelected}
              disabled={selectedRowKeys.length === 0}
            >
              <Button
                danger
                icon={<DeleteOutlined />}
                disabled={selectedRowKeys.length === 0}
              >
                删除选中 {selectedRowKeys.length > 0 && `(${selectedRowKeys.length})`}
              </Button>
            </Popconfirm>
          )}
          {canExport && (
            <Dropdown
              menu={{
                items: [
                  { key: 'csv', label: 'CSV（账号, Cookie, 时间）', onClick: () => handleExport('csv') },
                  { key: 'custom', label: '自定义（账号----密码----ck）', onClick: () => handleExport('custom') },
                ],
              }}
            >
              <Button type="primary" icon={<DownloadOutlined />}>
                导出
              </Button>
            </Dropdown>
          )}
        </Space>
      </div>
      <Row gutter={12} style={{ marginBottom: 16 }}>
        <Col span={6}>
          <Card size="small"><Statistic title="Cookie 总数" value={cookies.length} /></Card>
        </Col>
        <Col span={6}>
          <Card size="small">
            <Statistic
              title="已分配"
              value={assignedCount}
              styles={{ content: { color: token.colorSuccess } }}
            />
          </Card>
        </Col>
        <Col span={6}>
          <Card size="small">
            <Statistic
              title="未分配"
              value={unassignedCount}
              styles={{ content: { color: token.colorError } }}
            />
          </Card>
        </Col>
      </Row>
      <div style={{ marginBottom: 12 }}>
        <Input.Search
          placeholder="搜索账号或分配客服"
          allowClear
          value={searchText}
          onChange={(e) => setSearchText(e.target.value)}
          style={{ width: 260 }}
          size="small"
          prefix={<SearchOutlined />}
        />
      </div>
      <Table
        rowSelection={{
          selectedRowKeys,
          onChange: (keys) => setSelectedRowKeys(keys),
        }}
        columns={columns}
        dataSource={filteredCookies}
        rowKey="id"
        loading={loading}
        size="small"
        pagination={{
          current: currentPage,
          pageSize,
          showSizeChanger: true,
          showTotal: (t) => `共 ${t} 条`,
          onChange: (page, size) => {
            setCurrentPage(page);
            if (size !== pageSize) {
              setPageSize(size);
              localStorage.setItem('cookie_page_size', String(size));
              setCurrentPage(1); // 切换 pageSize 时重置到第1页
            }
          },
        }}
        scroll={{ x: 900 }}
      />
    </div>
  );
}
