import React, { useRef, useState } from 'react';
import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined, UploadOutlined } from '@ant-design/icons';
import {
  Button,
  Modal,
  message,
  Drawer,
  Form,
  Input,
  InputNumber,
  DatePicker,
  Card,
  Layout,
  Upload,
  UploadProps,
} from 'antd';
import { ProTable, ActionType, ProColumns, ProDescriptions, ProDescriptionsItemProps } from '@ant-design/pro-components';
import type { BtTorrent } from './data';
import {
  listBtTorrent,
  getBtTorrent,
  addBtTorrent,
  updateBtTorrent,
  removeBtTorrent,
  uploadTorrent, // Function to handle torrent upload
} from './service';

const { Content } = Layout;

const BtTorrentPage: React.FC = () => {
  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

  // Columns for the ProTable (the table displaying torrents)
  const columns: ProColumns<BtTorrent>[] = [
    {
      title: '种子ID',
      dataIndex: 'torrentId',
      hideInForm: true,
      render: (dom, entity) => (
        <a
          onClick={async () => {
            const res = await getBtTorrent(entity.torrentId!);
            setCurrent(res);
            setDrawerVisible(true);
          }}
        >
          {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={() => {
          setCurrent(record);
          setDrawerVisible(true);
        }}>查看</Button>,
        <Button key="edit" type="link" icon={<EditOutlined />} onClick={() => {
          setCurrent(record);
          form.setFieldsValue(record);
          setModalVisible(true);
        }}>编辑</Button>,
        <Button key="delete" type="link" icon={<DeleteOutlined />} danger onClick={() => {
          Modal.confirm({
            title: '删除确认',
            content: '确定删除该种子？',
            onOk: async () => {
              await removeBtTorrent([record.torrentId!]);
              message.success('删除成功');
              actionRef.current?.reload();
            },
          });
        }}>删除</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('请选择一个文件');
      }

      // Call the uploadTorrent function to upload the file
      await uploadTorrent(file);

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

      // Close the upload modal
      setUploadModalVisible(false);

      // Optionally reload the table or perform other actions (e.g., refresh list)
      actionRef.current?.reload();

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

  return (
    <Content>
      <Card bordered={false}>
        <ProTable<BtTorrent>
          headerTitle="种子列表"
          actionRef={actionRef}
          rowKey="torrentId"
          search={{ labelWidth: 100 }}
          toolBarRender={() => [
            <Button
              key="add"
              type="primary"
              icon={<PlusOutlined />}
              onClick={() => {
                form.resetFields();
                setCurrent({});
                setModalVisible(true);
              }}
            >
              新增
            </Button>,
            <Button
              key="upload"
              type="primary"
              icon={<UploadOutlined />}
              onClick={() => setUploadModalVisible(true)} // Show the upload modal
            >
              上传种子文件
            </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="上传种子文件"
          visible={uploadModalVisible}
          onCancel={() => setUploadModalVisible(false)}
          footer={null}
        >
          <Upload
            customRequest={({ file, onSuccess, onError }) => {
              setUploadFile(file);
              handleFileUpload(file);
              onSuccess?.();
            }}
            showUploadList={false}
            accept=".torrent"
          >
            <Button icon={<UploadOutlined />}>点击上传 .torrent 文件</Button>
          </Upload>
        </Modal>

        {/* 详情抽屉 */}
        <Drawer
          width={500}
          open={drawerVisible}
          onClose={() => setDrawerVisible(false)}
          title="种子详情"
        >
          {current && (
            <ProDescriptions<BtTorrent>
              column={1}
              title={current.name}
              request={async () => ({ data: current })}
              columns={columns as ProDescriptionsItemProps<BtTorrent>[]}
            />
          )}
        </Drawer>
      </Card>
    </Content>
  );
};

export default BtTorrentPage;
