import React, { useState, useRef, useEffect } from 'react';
import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined } from '@ant-design/icons';
import {
  Button,
  message,
  Drawer,
  Modal,
  Form,
  Input,
  Select,
  DatePicker,
  Card,
  Layout,
} from 'antd';
import type { FormInstance } from 'antd';
import {
  ProTable,
  ActionType,
  ProColumns,
  FooterToolbar,
  ProDescriptions,
  ProDescriptionsItemProps,
} from '@ant-design/pro-components';
import type { TrackerProject } from '../data.d.ts';
import {
  listTrackerProject,
  getTrackerProject,
  addTrackerProject,
  updateTrackerProject,
  removeTrackerProject,
} from '../service';

const { Content } = Layout;

const TrackerProjectPage: React.FC = () => {
  const actionRef = useRef<ActionType>();
  const [detailVisible, setDetailVisible] = useState(false);
  const [editVisible, setEditVisible] = useState(false);
  const [current, setCurrent] = useState<TrackerProject>();
  const [form] = Form.useForm();

  const columns: ProColumns<TrackerProject>[] = [
    {
      title: '项目ID',
      dataIndex: 'projectId',
      render: (_, row) => (
        <a
          onClick={async () => {
            const res = await getTrackerProject(row.projectId!);
            setCurrent(res.data);
            setDetailVisible(true);
          }}
        >
          {row.projectId}
        </a>
      ),
    },
    { title: '项目名称', dataIndex: 'projectName' },
    { title: '描述', dataIndex: 'description', hideInSearch: true },
    { title: '状态', dataIndex: 'status', valueEnum: { active: { text: '激活' }, inactive: { text: '不活跃' } } },
    { title: '创建者', dataIndex: 'createBy', hideInSearch: true },
    { title: '创建时间', dataIndex: 'createTime', hideInSearch: true },
    { title: '更新时间', dataIndex: 'updateTime', hideInSearch: true },
    {
      title: '操作',
      valueType: 'option',
      render: (_, row) => [
        <Button
          key="view"
          type="link"
          icon={<EyeOutlined />}
          onClick={async () => {
            const res = await getTrackerProject(row.projectId!);
            setCurrent(res.data);
            setDetailVisible(true);
          }}
        >
          查看
        </Button>,
        <Button
          key="edit"
          type="link"
          icon={<EditOutlined />}
          onClick={() => {
            setCurrent(row);
            form.setFieldsValue(row);
            setEditVisible(true);
          }}
        >
          编辑
        </Button>,
        <Button
          key="delete"
          type="link"
          icon={<DeleteOutlined />}
          danger
          onClick={() => {
            Modal.confirm({
              title: '删除项目',
              content: '确认删除该项目？',
              onOk: async () => {
                await removeTrackerProject([row.projectId!]);
                message.success('删除成功');
                actionRef.current?.reload();
              },
            });
          }}
        >
          删除
        </Button>,
      ],
    },
  ];

  /** 新增或更新 */
  const handleSubmit = async (values: any) => {
    if (current?.projectId) {
      await updateTrackerProject({ ...current, ...values });
      message.success('更新成功');
    } else {
      await addTrackerProject(values);
      message.success('新增成功');
    }
    setEditVisible(false);
    actionRef.current?.reload();
  };

  return (
    <Content>
      <Card bordered={false}>
        <ProTable<TrackerProject>
          headerTitle="项目列表"
          actionRef={actionRef}
          rowKey="projectId"
          search={{ labelWidth: 100 }}
          toolBarRender={() => [
            <Button
              key="add"
              type="primary"
              icon={<PlusOutlined />}
              onClick={() => {
                form.resetFields();
                setCurrent(undefined);
                setEditVisible(true);
              }}
            >
              新增
            </Button>,
          ]}
          request={async (params) => {
            const res = await listTrackerProject(params);
            return { data: res.rows, success: true, total: res.total };
          }}
          columns={columns}
        />

        {/* 详情 Drawer */}
        <Drawer
          width={500}
          open={detailVisible}
          onClose={() => setDetailVisible(false)}
        >
          {current && (
            <ProDescriptions<TrackerProject>
              column={1}
              title="项目详情"
              dataSource={current}
              columns={columns as ProDescriptionsItemProps<TrackerProject>[]}
            />
          )}
        </Drawer>

        {/* 新增/编辑 Modal */}
        <Modal
          title={current?.projectId ? '编辑项目' : '新增项目'}
          open={editVisible}
          onCancel={() => setEditVisible(false)}
          onOk={() => {
            form.validateFields().then(handleSubmit);
          }}
        >
          <Form form={form} layout="vertical">
            <Form.Item name="projectName" label="项目名称" rules={[{ required: true }]}>
              <Input />
            </Form.Item>
            <Form.Item name="description" label="描述">
              <Input.TextArea />
            </Form.Item>
            <Form.Item name="status" label="状态" initialValue="active">
              <Select>
                <Select.Option value="active">激活</Select.Option>
                <Select.Option value="inactive">不活跃</Select.Option>
              </Select>
            </Form.Item>
            {/* TODO: 补充其他字段 */}
          </Form>
        </Modal>
      </Card>
    </Content>
  );
};

export default TrackerProjectPage;
