import React, { useRef, useState, useEffect } from 'react';
import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined, UploadOutlined, DownloadOutlined, CommentOutlined } from '@ant-design/icons';
import {
  Button,
  Modal,
  message,
  Drawer,
  Form,
  Input,
  InputNumber,
  DatePicker,
  Card,
  Layout,
  Upload,
  UploadProps,
  Select,
  Tag, // 导入Tag组件用于显示标签
} from 'antd';
import { ProTable, ActionType, ProColumns, ProDescriptions, ProDescriptionsItemProps } from '@ant-design/pro-components';
import { useNavigate } from 'react-router-dom';
import type { BtTorrent, BtTorrentTag } from './data';
import {
  listBtTorrent,
  getBtTorrent,
  addBtTorrent,
  updateBtTorrent,
  removeBtTorrent,
  uploadTorrent,
  downloadTorrent,
  addBtTorrentTag,
  listBtTorrentTags,
  getBtTorrentTag
} from './service';

const { Content } = Layout;

const BtTorrentPage: React.FC = () => {
  const navigate = useNavigate();
  const actionRef = useRef<ActionType>();
  const [form] = Form.useForm();
  const [modalVisible, setModalVisible] = useState(false);
  const [drawerVisible, setDrawerVisible] = useState(false);
  const [current, setCurrent] = useState<Partial<BtTorrent>>({});
  const [uploadModalVisible, setUploadModalVisible] = useState(false); // State for upload modal
  const [uploadFile, setUploadFile] = useState<File | null>(null); // State to store selected file
  const [uploadForm] = Form.useForm(); // Form for upload modal
  const [torrentTags, setTorrentTags] = useState<BtTorrentTag[]>([]); // 修改为数组类型来存储多个标签

  // Columns for the ProTable (the table displaying torrents)
  const columns: ProColumns<BtTorrent>[] = [
    {
      title: '种子ID',
      dataIndex: 'torrentId',
      render: (dom, entity) => (
        <a
          onClick={async () => {
            try {
              // 获取详细信息
              const res = await getBtTorrent(entity.torrentId!);
              console.log('获取的种子详情:', res); // 调试用

              // 确保res是对象类型并且包含数据
              if (res && typeof res === 'object') {
                // 如果API返回了data包装，则提取data
                const torrentData = res.data ? res.data : res;
                setCurrent(torrentData);

                // 先设置当前种子，然后获取标签
                await handleGetTags(entity.torrentId!);
                setDrawerVisible(true);
              } else {
                message.error('获取种子详情格式错误');
              }
            } catch (error) {
              console.error('获取种子详情出错:', error);
              message.error('获取种子详情失败');
            }
          }}
        >
          {dom}
        </a>
      ),
    },
    { title: '名称', dataIndex: 'name' },
    // { title: 'infoHash', dataIndex: 'infoHash' },
    { title: '大小 (bytes)', dataIndex: 'length', valueType: 'digit' },
    // { title: '分片大小', dataIndex: 'pieceLength', valueType: 'digit' },
    // { title: '片段数', dataIndex: 'piecesCount', valueType: 'digit' },
    { title: '创建人', dataIndex: 'createdBy', hideInSearch: true },
    { title: '上传时间', dataIndex: 'uploadTime', valueType: 'dateTime', hideInSearch: true },
    {
      title: '操作',
      valueType: 'option',
      render: (_, record) => [
        <Button key="view" type="link" icon={<EyeOutlined />} onClick={async () => {
          try {
            // 获取详细信息
            const res = await getBtTorrent(record.torrentId!);
            console.log('获取的种子详情:', res); // 调试用

            // 确保res是对象类型并且包含数据
            if (res && typeof res === 'object') {
              // 如果API返回了data包装，则提取data
              const torrentData = res.data ? res.data : res;
              setCurrent(torrentData);

              // 获取标签
              await handleGetTags(record.torrentId!);
              setDrawerVisible(true);
            } else {
              message.error('获取种子详情格式错误');
            }
          } catch (error) {
            console.error('获取种子详情出错:', error);
            message.error('获取详情失败');
          }
        }}>查看</Button>,
        <Button key="download" type="link" icon={<DownloadOutlined />} onClick={async () => {
          try {
            const blob = await downloadTorrent(record.torrentId!);
            const url = window.URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.href = url;
            link.download = `${record.name}.torrent`;
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            window.URL.revokeObjectURL(url);
            message.success('下载成功');
          } catch (error: any) {
            message.error('下载失败');
          }
        }}>下载</Button>,

      ],
    },
  ];

  // Handle the submit for adding or updating a torrent
  const handleSubmit = async () => {
    const values = await form.validateFields();
    try {
      if (current?.torrentId) {
        await updateBtTorrent({ ...current, ...values });
        message.success('更新成功');
      } else {
        await addBtTorrent(values as BtTorrent);
        message.success('新增成功');
      }
      setModalVisible(false);
      form.resetFields();
      actionRef.current?.reload();
    } catch (error) {
      message.error('操作失败');
    }
  };

  // Handle file upload
  const handleFileUpload = async (file: File) => {
    try {
      if (!file) {
        throw new Error('请选择一个文件');
      }

      const values = await uploadForm.validateFields();
      console.log(file);
      // Call the uploadTorrent function to upload the file with additional info
      await uploadTorrent(file);

      // Show a success message
      message.success('文件上传成功');

      // Close the upload modal and reset form
      setUploadModalVisible(false);
      uploadForm.resetFields();

      // Reload the table
      actionRef.current?.reload();

    } catch (error) {
      message.error(error.message || '文件上传失败');
    }
  };

  // 修改获取标签的函数，处理API特定的响应格式
  const handleGetTags = async (id: number) => {
    try {
      // 根据API的响应格式，获取rows数组中的标签
      const response = await listBtTorrentTags({ torrentId: id });
      console.log('API标签响应:', response);

      // 检查响应格式并提取rows数组
      if (response && response.rows && Array.isArray(response.rows)) {
        setTorrentTags(response.rows);
        console.log('设置标签:', response.rows);
      } else {
        console.log('未找到标签或格式不符');
        setTorrentTags([]);
      }
    } catch (error) {
      console.error('获取标签失败:', error);
      message.error('获取标签失败');
      setTorrentTags([]);
    }
  };

  useEffect(() => {
    if (current?.torrentId) {
      handleGetTags(current.torrentId);
    } else {
      setTorrentTags([]); // 清空标签当没有选中种子时
    }
  }, [current]);

  // 渲染标签列表的函数
  const renderTags = () => {
    if (!torrentTags || torrentTags.length === 0) {
      return <span style={{ color: '#999' }}>暂无标签</span>;
    }

    // 定义一些可能的标签颜色
    const tagColors = ['blue', 'green', 'cyan', 'purple', 'magenta', 'orange', 'gold', 'lime'];

    return (
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px' }}>
        {torrentTags.map((tag, index) => {
          // 根据索引轮换颜色
          const colorIndex = index % tagColors.length;
          return (
            <Tag
              key={tag.id || tag.torrentId || index}
              color={tagColors[colorIndex]}
              style={{ margin: '0 4px 4px 0', padding: '2px 8px' }}
            >
              {tag.tag}
            </Tag>
          );
        })}
      </div>
    );
  };

  return (
    <Content>
      <Card bordered={false}>
        <ProTable<BtTorrent>
          headerTitle="种子列表"
          actionRef={actionRef}
          rowKey="torrentId"
          search={{ labelWidth: 100 }}
          toolBarRender={() => [
            <Button
              key="upload"
              type="primary"
              icon={<UploadOutlined />}
              onClick={() => setUploadModalVisible(true)}
            >
              上传种子文件
            </Button>
          ]}
          request={async (params) => {
            const res = await listBtTorrent(params);
            return { data: res.rows || res.data || [], success: true };
          }}
          columns={columns}
        />

        {/* 编辑/新增弹窗 */}
        <Modal
          title={current?.torrentId ? '编辑种子' : '新增种子'}
          open={modalVisible}
          onOk={handleSubmit}
          onCancel={() => setModalVisible(false)}
          destroyOnClose
        >
          <Form form={form} layout="vertical">
            <Form.Item name="name" label="名称" rules={[{ required: true }]}>
              <Input />
            </Form.Item>
            <Form.Item name="infoHash" label="infoHash" rules={[{ required: true }]}>
              <Input />
            </Form.Item>
            <Form.Item name="length" label="总大小 (bytes)" rules={[{ required: true }]}>
              <InputNumber style={{ width: '100%' }} />
            </Form.Item>
            <Form.Item name="pieceLength" label="分片大小" rules={[{ required: true }]}>
              <InputNumber style={{ width: '100%' }} />
            </Form.Item>
            <Form.Item name="piecesCount" label="片段数">
              <InputNumber style={{ width: '100%' }} />
            </Form.Item>
            <Form.Item name="createdBy" label="创建工具">
              <Input />
            </Form.Item>
          </Form>
        </Modal>

        {/* 上传种子文件的Modal */}
        <Modal
          title="上传种子文件"
          open={uploadModalVisible}
          onCancel={() => {
            setUploadModalVisible(false);
            uploadForm.resetFields();
          }}
          onOk={() => {
            if (uploadFile) {
              handleFileUpload(uploadFile);
            } else {
              message.error('请选择文件');
            }
          }}
        >
          <Form form={uploadForm} layout="vertical">
            <Form.Item
              name="file"
              label="种子文件"
              rules={[{ required: true, message: '请选择种子文件' }]}
            >
              <Upload
                customRequest={({ file, onSuccess }) => {
                  setUploadFile(file as File);
                  onSuccess?.();
                }}
                showUploadList={true}
                maxCount={1}
                accept=".torrent"
                onRemove={() => setUploadFile(null)}
              >
                <Button icon={<UploadOutlined />}>选择 .torrent 文件</Button>
              </Upload>
            </Form.Item>
            <Form.Item
              name="description"
              label="介绍"
              rules={[{ required: true, message: '请输入种子介绍' }]}
            >
              <Input.TextArea rows={4} placeholder="请输入种子文件的详细介绍" />
            </Form.Item>
            <Form.Item
              name="tags"
              label="标签"
              rules={[{ required: true, message: '请输入标签' }]}
            >
              <Select
                mode="tags"
                style={{ width: '100%' }}
                placeholder="请输入标签，按回车键确认"
                tokenSeparators={[',']}
              />
            </Form.Item>
          </Form>
        </Modal>

        {/* 详情抽屉 */}
        <Drawer
          width={600}
          open={drawerVisible}
          onClose={() => setDrawerVisible(false)}
          title="种子详情"
          extra={
            <Button
              type="primary"
              icon={<CommentOutlined />}
              onClick={() => navigate(`/torrent/comments/${current.torrentId}`)}
            >
              查看评论
            </Button>
          }
        >
          {current && (
            <>
              {/* 不要使用request属性，直接使用dataSource */}
              <ProDescriptions<BtTorrent>
                column={1}
                title={current.name}
                dataSource={current}
                columns={[
                  {
                    title: '种子ID',
                    dataIndex: 'torrentId',
                    valueType: 'text'
                  },
                  {
                    title: '名称',
                    dataIndex: 'name',
                    valueType: 'text'
                  },
                  {
                    title: 'infoHash',
                    dataIndex: 'infoHash',
                    valueType: 'text',
                    copyable: true
                  },
                  {
                    title: '大小 (bytes)',
                    dataIndex: 'length',
                    valueType: 'digit',

                  },
                  {
                    title: '分片大小',
                    dataIndex: 'pieceLength',
                    valueType: 'digit'
                  },
                  {
                    title: '片段数',
                    dataIndex: 'piecesCount',
                    valueType: 'digit'
                  },
                  {
                    title: '创建人',
                    dataIndex: 'createdBy',
                    valueType: 'text'
                  },
                  {
                    title: '上传时间',
                    dataIndex: 'uploadTime',
                    valueType: 'dateTime'
                  },
                  {
                    title: '标签',
                    dataIndex: 'tags',
                    render: () => renderTags()
                  }
                ] as ProDescriptionsItemProps<BtTorrent>[]}
              />

              {/* 如果需要显示额外信息，可以在这里添加 */}
              {current.description && (
                <div style={{ marginTop: 16 }}>
                  <h3>介绍</h3>
                  <p>{current.description}</p>
                </div>
              )}

              {/* 添加调试信息 - 开发时使用，生产环境可以移除 */}
              {/* <div style={{ marginTop: 20, background: '#f5f5f5', padding: 10, borderRadius: 4 }}>
                <h4>调试信息:</h4>
                <p>当前种子ID: {current.torrentId}</p>
                <p>标签数量: {torrentTags?.length || 0}</p>
                <details>
                  <summary>查看完整数据</summary>
                  <pre style={{ maxHeight: 200, overflow: 'auto' }}>{JSON.stringify(current, null, 2)}</pre>
                  <h5>标签数据:</h5>
                  <pre style={{ maxHeight: 200, overflow: 'auto' }}>{JSON.stringify(torrentTags, null, 2)}</pre>
                </details>
              </div> */}
            </>
          )}
        </Drawer>
      </Card>
    </Content>
  );
};

export default BtTorrentPage;