import React, { useState, useEffect } from 'react';
import { List, Button, Form, Input, Select, message, Typography, Tag, Divider, Pagination } from 'antd';
import { BugOutlined } from '@ant-design/icons';
import WorkAPI from '../api/workApi';
import type { BugReport } from '../api/otherType';

const { Text } = Typography;
const { Option } = Select;
const { TextArea } = Input;

interface BugReportForm {
  title: string;
  description: string;
  severity: 'low' | 'medium' | 'high';
}

const BugReportSection: React.FC<{ workId: number }> = ({ workId }) => {
  const [bugs, setBugs] = useState<BugReport[]>([]);
  const [loading, setLoading] = useState(false);
  const [form] = Form.useForm();
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize, setPageSize] = useState(5); // 每页显示5条

  // 加载Bug反馈列表
  useEffect(() => {
    const loadBugs = async () => {
      try {
        setLoading(true);
        const bugList = await WorkAPI.getBugReports(workId);
        setBugs(bugList);
      } catch (error) {
        message.error('加载Bug反馈失败');
      } finally {
        setLoading(false);
      }
    };

    loadBugs();
  }, [workId]);

  // 获取当前页的Bug数据
  const getCurrentPageBugs = () => {
    const startIndex = (currentPage - 1) * pageSize;
    const endIndex = startIndex + pageSize;
    return bugs.slice(startIndex, endIndex);
  };

  // 提交Bug反馈
  const handleSubmit = async (values: BugReportForm) => {
    try {
      await WorkAPI.reportBug(workId, values);
      message.success('Bug反馈提交成功');
      form.resetFields();
      // 重新加载Bug列表
      const bugList = await WorkAPI.getBugReports(workId);
      setBugs(bugList);
      // 重置到第一页
      setCurrentPage(1);
    } catch (error) {
      message.error('Bug反馈提交失败');
    }
  };

  const getSeverityColor = (severity: string) => {
    switch (severity) {
      case 'high': return 'red';
      case 'medium': return 'orange';
      default: return 'green';
    }
  };

  return (
    <div className="bug-report-section">
      <Divider orientation="left">
        <BugOutlined /> Bug反馈
      </Divider>

      <Form form={form} onFinish={handleSubmit} layout="vertical">
        <Form.Item
          name="title"
          label="Bug标题"
          rules={[{ required: true, message: '请输入Bug标题' }]}
        >
          <Input placeholder="简要描述Bug" />
        </Form.Item>

        <Form.Item
          name="severity"
          label="严重程度"
          initialValue="medium"
          rules={[{ required: true }]}
        >
          <Select>
            <Option value="low">低</Option>
            <Option value="medium">中</Option>
            <Option value="high">高</Option>
          </Select>
        </Form.Item>

        <Form.Item
          name="description"
          label="详细描述"
          rules={[{ required: true, message: '请详细描述Bug' }]}
        >
          <TextArea rows={4} placeholder="请详细描述Bug出现的步骤、现象和预期结果" />
        </Form.Item>

        <Form.Item>
          <Button type="primary" htmlType="submit">
            提交Bug
          </Button>
        </Form.Item>
      </Form>

      <Divider orientation="left">Bug列表</Divider>

      <List
        dataSource={getCurrentPageBugs()}
        loading={loading}
        renderItem={bug => (
          <List.Item>
            <div className="bug-item">
              <div className="bug-header">
                <Text strong>{bug.title}</Text>
                <Tag color={getSeverityColor(bug.severity)}>
                  {bug.severity === 'high' ? '严重' : bug.severity === 'medium' ? '中等' : '轻微'}
                </Tag>
              </div>
              <Text type="secondary">报告人: {bug.reporter} | 时间: {new Date(bug.createTime).toLocaleString()}</Text>
              <div className="bug-content">
                <Text>{bug.description}</Text>
              </div>
              <Tag color={bug.status === 'open' ? 'red' : bug.status === 'resolved' ? 'green' : 'gray'}>
                {bug.status === 'open' ? '未解决' : bug.status === 'resolved' ? '已解决' : '不予解决'}
              </Tag>
            </div>
          </List.Item>
        )}
      />

      <div style={{ textAlign: 'right', marginTop: 16 }}>
        <Pagination
          current={currentPage}
          pageSize={pageSize}
          total={bugs.length}
          onChange={(page, size) => {
            setCurrentPage(page);
            setPageSize(size);
          }}
          showSizeChanger
          showQuickJumper
          showTotal={total => `共 ${total} 条`}
        />
      </div>
    </div>
  );
};

export default BugReportSection;