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}`;
            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;
