import React, { useState } from 'react'

import {
  Button,
  Typography,
  Form,
  DatePicker,
  Select,
  Alert,
  Modal,
  message
} from 'antd'
import dayjs from 'dayjs'
import { useParams } from 'react-router-dom'

import { ClusterCluster, ClusterDataInfo } from '@clinic/client'
import { triggerModelAnalysis } from '~/api'
import { useCurOrg } from '~/hooks/state'
import { clusterDetailTelemetry } from '~/telemetry'

import { DetailItemCard } from '../components/DetailItemCard'
import type { TimeRange } from '../components/TimeWindowSelect'

export interface DiagModelProps {
  type: 'log' | 'metrics'
  cluster: ClusterCluster
  models: DiagModel[]
  packages?: ClusterDataInfo[]
  timeRange?: TimeRange
}

export interface DiagModel {
  id: string
  task_id: string
}

const { Paragraph } = Typography
const { Option } = Select

export const DiagModelLink: React.FC<DiagModelProps> = ({
  type,
  cluster,
  packages,
  models,
  timeRange
}) => {
  const [showModal, setShowModal] = useState(false)
  const name = `Diagnostic Model (${type.slice(0, 1).toUpperCase()}${type
    .slice(1)
    .toLowerCase()})`

  return (
    <>
      <DetailItemCard
        onClick={() => {
          clusterDetailTelemetry.clickDetailItem(name)
          setShowModal(true)
        }}
        name={name}
        tag={{ name: 'Experimental', color: 'purple' }}
      />

      <Modal
        visible={showModal}
        title={name}
        onCancel={() => setShowModal(false)}
        destroyOnClose
        footer={null}
      >
        <ModalContent
          type={type}
          cluster={cluster}
          timeRange={timeRange}
          models={models}
          packages={packages}
        />
      </Modal>
    </>
  )
}

const ModalContent: React.FC<DiagModelProps> = ({
  type,
  cluster,
  packages = [],
  models,
  timeRange: _timeRange
}) => {
  const timeRange = _timeRange || {
    start: dayjs().subtract(1, 'h').unix(),
    end: dayjs().unix()
  }
  const { orgId } = useParams<'orgId'>()
  const [form] = Form.useForm()
  const [loading, setLoading] = useState(false)
  const [url, setUrl] = useState('')
  const orgType = useCurOrg().curOrg!.orgType

  const requestDiagnostic = async () => {
    const fv = form.getFieldsValue()
    const validPackages = packages.filter((p) => {
      const startTime = p.startTime! * 1000
      const endTime = p.endTime! * 1000
      return (
        fv.start_ts.isAfter(startTime) ||
        fv.start_ts.isSame(startTime) ||
        fv.end_ts.isBefore(endTime) ||
        fv.end_ts.isSame(endTime)
      )
    })
    const model = models.find((m) => m.id === fv.function_name)!
    const req = {
      ...fv,
      org_type: orgType,
      org_id: orgId,
      task_id: model.task_id,
      start_ts: fv.start_ts.unix(),
      end_ts: fv.end_ts.unix(),
      packages: validPackages.map((p) => p.itemID)
    }

    clusterDetailTelemetry.requestDiagModel(type, {
      cluster_id: cluster.id!,
      model_name: model.id,
      time_range: timeRange as any
    })
    setLoading(true)

    try {
      const res = await triggerModelAnalysis(req)
      let fullUrl = res.data.url
      if (fullUrl.startsWith('/')) {
        fullUrl = `${window.location.protocol}//${window.location.host}${fullUrl}`
      }
      setUrl(fullUrl)
    } catch (e: any) {
      message.error(
        e?.message || `Failed to request diagnostic model, reason: ${e}`
      )
    } finally {
      setLoading(false)
    }
  }

  const RequestForm = () => (
    <div>
      <Form
        name='dianositc_metrics'
        initialValues={{
          tidb_cluster: cluster.id,
          function_name: models[0].id,
          start_ts: dayjs(timeRange.start * 1000),
          end_ts: dayjs(timeRange.end * 1000)
        }}
        form={form}
        labelCol={{ span: 6 }}
        wrapperCol={{ span: 12 }}
        autoComplete='off'
      >
        <Form.Item label='Cluster Name' name='tidb_cluster'>
          <Select disabled>
            <Option value={cluster.id}>
              {cluster.name || '(Unknown Name)'}
            </Option>
          </Select>
        </Form.Item>

        <Form.Item label='Model Name' name='function_name'>
          <Select>
            {models.map((m) => (
              <Option value={m.id}>{m.id}</Option>
            ))}
          </Select>
        </Form.Item>

        <Form.Item
          label='Start Time'
          name='start_ts'
          className={!!_timeRange ? '' : 'hidden'}
        >
          <DatePicker
            showTime
            disabledDate={(c) => c.isAfter(form.getFieldValue('end_ts'))}
          />
        </Form.Item>

        <Form.Item
          label='End Time'
          name='end_ts'
          className={!!_timeRange ? '' : 'hidden'}
        >
          <DatePicker
            showTime
            disabledDate={(c) => c.isBefore(form.getFieldValue('start_ts'))}
          />
        </Form.Item>

        <Form.Item wrapperCol={{ offset: 10 }}>
          <Button type='primary' loading={loading} onClick={requestDiagnostic}>
            Request
          </Button>
        </Form.Item>
      </Form>
    </div>
  )

  const Result = () => (
    <div>
      <Paragraph type='danger'>This is an Experimental Feature</Paragraph>
      <Paragraph>
        Your request will calculate for a while, please check the link below
        after 10 mins.
      </Paragraph>
      <Paragraph>
        The results URL:{' '}
        <a
          href={url}
          target='_blank'
          onClick={() => clusterDetailTelemetry.clickDiagModelLink(type, url)}
        >
          {url}
        </a>
      </Paragraph>
      <Alert
        className='mt-6'
        message='You will be able to view this URL here only once! It is not stored, so be sure to open it before you leave this page.'
        type='warning'
        showIcon
      />
    </div>
  )

  return !!url ? <Result /> : <RequestForm />
}
