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[]>([]); // 修改为数组类型来存储多个标签
  const [tagModalVisible, setTagModalVisible] = useState(false);
  const [currentTorrent, setCurrentTorrent] = useState<BtTorrent | null>(null);
  const [tagForm] = Form.useForm();

  // 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>,
        <Button key="tags" type="link" onClick={() => {
          setCurrentTorrent(record);
          handleGetTags(record.torrentId!);
          setTagModalVisible(true);
        }}>设置标签</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>
        </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>

        {/* 设置标签的Modal */}
        <Modal
          title="设置标签"
          open={tagModalVisible}
          onCancel={() => {
            setTagModalVisible(false);
            tagForm.resetFields();
          }}
          onOk={async () => {
            try {
              const values = await tagForm.validateFields();
              if (currentTorrent?.torrentId && values.tags) {
                // 添加新标签
                for (const tag of values.tags) {
                  await addBtTorrentTag({
                    torrentId: currentTorrent.torrentId,
                    tag: tag
                  });
                }
                message.success('标签设置成功');
                setTagModalVisible(false);
                tagForm.resetFields();
                // 刷新标签列表
                if (currentTorrent.torrentId === current?.torrentId) {
                  handleGetTags(currentTorrent.torrentId);
                }
              }
            } catch (error) {
              message.error('设置标签失败');
            }
          }}
        >
          <Form form={tagForm} layout="vertical">
            <Form.Item
              name="tags"
              label="标签"
              rules={[{ required: true, message: '请输入标签' }]}
            >
              <Select
                mode="tags"
                style={{ width: '100%' }}
                placeholder="请输入标签，按回车键确认"
                tokenSeparators={[',']}
              />
            </Form.Item>
          </Form>
        </Modal>
      </Card>
    </Content>
  );
};

export default BtTorrentPage;