import { PageContainer, ProCard } from '@ant-design/pro-components';
import { Table, Space, Button, Select, Row, Col, notification } from 'antd';
import { useEffect, useState } from 'react';
import type { ColumnsType } from 'antd/es/table';
import { history } from 'umi';
import axios from 'axios';

type OptionType = {
  value: string;
  label: string;
};

interface TestReport {
  key: number;
  id: number;
  pass_rate: number;
  generating_pass_rate: number;
  executing_pass_rate: number;
  chart_match_rate: number;
  chart_non_table_rate: number;
  type: string;
  template: string;
  plan_name: string;
  test_run: string;
  start_time: string;
  status: string;
  token_used: number;
}

function handleShowReportDetail(recordID: number) {
  console.log('handleRunPlan', recordID);
  history.push({
    pathname: '/report/detail',
    query: { report_id: recordID.toString() },
  });
}

const columns: ColumnsType<TestReport> = [
  {
    title: 'ID',
    dataIndex: 'id',
  },
  {
    title: 'PassRate',
    dataIndex: 'pass_rate',
    render: (text, record) => (Number(text) * 100).toFixed(2) + '%',
  },
  {
    title: 'Generate PassRate',
    dataIndex: 'generating_pass_rate',
    render: (text, record) => (Number(text) * 100).toFixed(2) + '%',
  },
  {
    title: 'Execute PassRate',
    dataIndex: 'executing_pass_rate',
    render: (text, record) => (Number(text) * 100).toFixed(2) + '%',
  },
  {
    title: 'Chart Match PassRate',
    dataIndex: 'chart_match_rate',
    render: (text, record) => (Number(text) * 100).toFixed(2) + '%',
  },
  {
    title: 'Chart Non-Table PassRate',
    dataIndex: 'chart_non_table_rate',
    render: (text, record) => (Number(text) * 100).toFixed(2) + '%',
  },
  {
    title: 'Template',
    dataIndex: 'template',
  },
  {
    title: 'Type',
    dataIndex: 'type',
  },
  {
    title: 'Test plan name',
    dataIndex: 'plan_name',
  },
  {
    title: 'Test Run',
    dataIndex: 'test_run',
  },
  {
    title: 'Start',
    dataIndex: 'start_time',
  },
  {
    title: 'Token Used',
    dataIndex: 'token_used',
    render: (text) => text + ' / $' + ((Number(text) / 1000) * 0.02).toFixed(2),
  },
  {
    title: 'Status',
    dataIndex: 'status',
    render(value: number) {
      if (value === 0) {
        return 'Init';
      } else if (value === 1) {
        return 'Running';
      } else if (value === 2) {
        return 'Done';
      } else {
        return '-';
      }
    },
  },
  {
    title: 'Action',
    key: 'action',
    render: (_, record) => (
      <Space size="middle">
        <Button
          type="primary"
          onClick={() => handleShowReportDetail(record.id)}
        >
          Detail
        </Button>
      </Space>
    ),
  },
];

export default () => {
  const [tableData, setTableData] = useState<TestReport[]>([]);
  const [plansData, setPlansData] = useState<OptionType[]>();
  const [runsData, setRunsData] = useState<OptionType[]>();
  const [pagination, setPagination] = useState({
    pageSize: 20,
    current: 1,
    total: 100,
    runID: 0,
    planID: 0,
    onChange: onChange,
  });

  async function onChange(page, pageSize) {
    pagination.pageSize = pageSize;
    pagination.current = page;
    setPagination(pagination);
    loadData();
  }

  let selectedRunID = 0;
  let selectedPlanID = 0;

  const handlePlanChange = (value: string) => {
    pagination.planID = Number(value);
    setPagination(pagination);
    loadData();
  };

  const handleRunChange = (value: string) => {
    pagination.runID = Number(value);
    setPagination(pagination);
    loadData();
  };

  function openRequestErrorNotification(url: string, statusText: string) {
    notification.error({
      message: 'Error',
      description: 'fetch ' + url + ' got ' + statusText,
    });
  }

  function openBackendNotification(error: Error) {
    notification.error({
      message: 'Error',
      description: error,
    });
  }

  async function loadPlans() {
    const resp = await axios.get(`/api/v1/plans`);

    let plans = [];
    for (let plan of resp.data.result.plans) {
      plans.push({
        label: plan.plan.name,
        value: plan.plan.ID,
      });
    }

    setPlansData(plans);
  }

  async function loadRuns() {
    const resp = await axios.get(`/api/v1/runs`);

    let runs = [];
    for (let run of resp.data.result.runs) {
      runs.push({
        label: run.run.name,
        value: run.run.ID,
      });
    }

    setRunsData(runs);
  }

  function loadData() {
    fetch(
      `/api/v1/reports?plan_id=${pagination.planID}&run_id=${pagination.runID}&page=${pagination.current}&per_page=${pagination.pageSize}`,
    )
      .then((res) => {
        if (res.status != 200) {
          res.json().then(
            (result) => {
              openBackendNotification(result.error);
            },
            (error) => {
              openRequestErrorNotification(res.url, res.statusText);
            },
          );
          throw new Error('Request Error');
        }
        return res.json();
      })
      .then(
        (result) => {
          let data: TestReport[] = [];
          for (const i of result.result.reports) {
            data.push({
              key: i.report.ID,
              id: i.report.ID,
              pass_rate: i.report.pass_rate,
              type: i.plan.type,
              template: i.prompt_template.version,
              plan_name: i.plan.name,
              test_run: i.run.name,
              start_time: i.start,
              status: i.report.status,
              token_used: i.report.token_used,
              generating_pass_rate: i.generating_pass_rate,
              executing_pass_rate: i.executing_pass_rate,
              chart_match_rate: i.chart_type_match_rate,
              chart_non_table_rate: i.non_table_chart_rate,
            });
          }

          pagination.total = result.result.total;
          console.log('set pagination', pagination);
          setPagination(pagination);
          setTableData(data);
        },
        (error) => {
          console.log(error);
        },
      );
  }

  useEffect(() => {
    const fetchData = async () => {
      await loadPlans();
      await loadRuns();
    };

    fetchData()
      .then(() => loadData())
      .catch(console.error);
  }, []);

  return (
    <PageContainer>
      <ProCard ghost gutter={8}>
        <ProCard
          style={{ minHeight: '90vh', height: '100px', overflowY: 'scroll' }}
          colSpan={24}
          bordered
        >
          <Space direction="vertical" size="middle" style={{ display: 'flex' }}>
            <Row>
              <Col span={24}>
                <Space>
                  <Select
                    style={{ width: 200 }}
                    defaultValue="Test Plan"
                    onChange={handlePlanChange}
                    options={plansData}
                  />
                  <Select
                    style={{ width: 200 }}
                    defaultValue="Test Run"
                    onChange={handleRunChange}
                    options={runsData}
                  />
                </Space>
              </Col>
            </Row>
            <Row>
              <Col span={24}>
                <Table
                  pagination={pagination}
                  columns={columns}
                  dataSource={tableData}
                />
              </Col>
            </Row>
          </Space>
        </ProCard>
      </ProCard>
    </PageContainer>
  );
};
