import { Button, Checkbox, Modal, Select } from 'antd'
import Table, { ColumnsType } from 'antd/lib/table/Table'
import { Key, useEffect, useMemo, useState } from 'react'
import { Link } from 'react-router-dom'

import { cloudConfigControllerGetTemplate } from 'apiClient/services/devops'
import {
  CloudConfigControllerGetTemplateClusterType,
  CloudconfigNamedParameter,
  CloudconfigTemplateDefaultCaseBindingChange
} from 'apiClient/services/devops/interface'

import DiffTemplate from '../Form/DiffTemplateForm'

import ExpandTemplateTable from './ExpandTemplateTable'

export function UniqueAndSortComponents(array: string[]): string[] {
  const weights = new Map<string, number>([
    ['tidb', 4],
    ['tikv', 3],
    ['pd', 2],
    ['tiflash', 1],
    ['tiflash_learner', 1]
  ])

  const set = new Set(array)

  return Array.from(set).sort((a, b) => {
    const weightA = weights.get(a) || 0
    const weightB = weights.get(b) || 0
    if (weightA === weightB) {
      return a.localeCompare(b)
    }

    return weightB - weightA
  })
}

function TemplateModifyTable({
  scope,
  selectedRowKeys,
  setSelectedRowKeys
}: {
  scope: CloudconfigTemplateDefaultCaseBindingChange[]
  selectedRowKeys?: React.Key[]
  setSelectedRowKeys?: React.Dispatch<React.SetStateAction<Key[]>>
}) {
  const [modalDiff, setModalDiff] = useState(false)
  const [checkboxChecked, setCheckboxChecked] = useState(false)

  const [diffParam, setDiffParam] = useState<{
    source: number | undefined
    current: number | undefined
  }>({ source: undefined, current: undefined })
  const onSelectChange = (newSelectedRowKeys: React.Key[]) => {
    if (setSelectedRowKeys) {
      setSelectedRowKeys(newSelectedRowKeys)
    }
  }
  const handleCancelDiff = () => {
    setModalDiff(false)
  }
  const [configType, setConfigType] = useState('')
  useEffect(() => {
    setConfigType(
      UniqueAndSortComponents(
        scope.map((v) => {
          return v.origin?.default_case?.config_type!
        })
      )[0]
    )
  }, [scope])
  const columnsTemplateModify: ColumnsType<
    CloudconfigTemplateDefaultCaseBindingChange & { key: string }
  > = [
    {
      title: 'Version',
      render: (_: any, record) => {
        return record.origin?.default_case?.version
      }
    },
    {
      title: 'Cloud Provider',
      render: (_: any, record) => {
        return record.origin?.default_case?.cloud_provider || 'Any'
      }
    },
    {
      title: 'Instance Type',
      render: (_: any, record) => {
        return record.origin?.default_case?.instance_type || 'Any'
      }
    },
    {
      title: 'Config Type',
      render: (_: any, record) => {
        return record.origin?.default_case?.config_type
      }
    },
    {
      title: 'Source Template',
      render: (_: any, record) => {
        return (
          <div>
            <Button type="link">
              <Link
                target="_blank"
                to={`/template/${record.origin?.template_id}`}
              >
                {record.origin?.template_id}
              </Link>
            </Button>
          </div>
        )
      }
    },
    {
      title: 'Current Template',
      render: (_: any, record) => {
        return (
          <div>
            <Button type="link">
              <Link
                target="_blank"
                to={`/template/${record.modified?.template_id}`}
              >
                {record.modified?.template_id}
              </Link>
            </Button>
          </div>
        )
      }
    },
    {
      title: 'Action',
      render: (_: any, record) => {
        return (
          <div>
            <Button
              type="link"
              onClick={() => {
                setDiffParam({
                  source: record.origin?.template_id,
                  current: record.modified?.template_id
                })
                setModalDiff(true)
              }}
            >
              Diff
            </Button>
          </div>
        )
      }
    }
  ]

  const [expandedRowKeys, setExpandedRowKeys] = useState<Key[]>([])
  const [expandedData, setExpandedData] = useState<
    Record<string, CloudconfigNamedParameter[]>
  >({})

  const rowSelection = {
    selectedRowKeys,
    onChange: onSelectChange
  }

  const onExpand = async (
    expanded: boolean,
    record: CloudconfigTemplateDefaultCaseBindingChange & { key: string }
  ) => {
    if (expanded) {
      const params = (
        await cloudConfigControllerGetTemplate(
          String(record.modified?.template_id),
          {
            cluster_type:
              CloudConfigControllerGetTemplateClusterType.DEDICATED_TIDB
          }
        )
      ).data.template?.parameters
      let arr: CloudconfigNamedParameter[] = []
      for (let key in params) {
        arr.push({ ...params[key] })
      }
      setExpandedData((prev) => ({ ...prev, [record.key]: arr }))
    }
  }

  useEffect(() => {
    expandedRowKeys.forEach(async (key: string) => {
      if (!expandedData[key]) {
        const record = scope
          .map((v1) => {
            let v = v1!
            let arr = []
            arr.push(v1.origin?.template_id)
            arr.push(v.origin?.default_case?.version)
            arr.push(v.origin?.default_case?.cloud_provider)
            arr.push(v.origin?.default_case?.instance_type)
            arr.push(v.origin?.default_case?.config_type)
            arr.push(v.origin?.cluster_type)
            arr.push(v.modified?.template_id)
            return {
              ...v,
              key: arr.join(', ')
            }
          })
          .filter((v) => {
            return v.key === key
          })
        await onExpand(true, record![0])
      }
    })
  }, [expandedRowKeys])
  return (
    <div>
      <Select
        options={UniqueAndSortComponents(
          scope.map((v) => {
            return v.origin?.default_case?.config_type!
          })
        ).map((v) => {
          return { label: v, value: v }
        })}
        value={configType}
        onChange={(e) => {
          setConfigType(e)
          if (setSelectedRowKeys) {
            setSelectedRowKeys([])
            setCheckboxChecked(false)
          }
        }}
        dropdownMatchSelectWidth={false}
      ></Select>
      &nbsp;
      {setSelectedRowKeys ? (
        <Checkbox
          checked={checkboxChecked}
          onChange={() => {
            if (checkboxChecked) {
              setSelectedRowKeys([])
              setCheckboxChecked(false)
            } else {
              setSelectedRowKeys(
                scope
                  .filter((v) => {
                    return v.origin?.default_case?.config_type === configType
                  })
                  .map((v1) => {
                    let v = v1!
                    let arr = []
                    arr.push(v1.origin?.template_id)
                    arr.push(v.origin?.default_case?.version)
                    arr.push(v.origin?.default_case?.cloud_provider)
                    arr.push(v.origin?.default_case?.instance_type)
                    arr.push(v.origin?.default_case?.config_type)
                    arr.push(v.origin?.cluster_type)
                    arr.push(v.modified?.template_id)
                    return arr.join(', ')
                  })
              )
              setCheckboxChecked(true)
            }
          }}
        >
          select all
        </Checkbox>
      ) : (
        <></>
      )}
      <Table<CloudconfigTemplateDefaultCaseBindingChange & { key: string }>
        expandable={{
          expandedRowRender: (record) => (
            <ExpandTemplateTable
              params={expandedData[record.key]}
            ></ExpandTemplateTable>
          ),
          onExpand,
          expandedRowKeys,
          onExpandedRowsChange: (expandedKeys) => {
            setExpandedRowKeys(expandedKeys.slice())
          }
        }}
        rowSelection={
          setSelectedRowKeys !== undefined ? rowSelection : undefined
        }
        columns={columnsTemplateModify}
        dataSource={scope
          .filter((v) => {
            return v.origin?.default_case?.config_type === configType
          })
          .map((v1) => {
            let v = v1!
            let arr = []
            arr.push(v1.origin?.template_id)
            arr.push(v.origin?.default_case?.version)
            arr.push(v.origin?.default_case?.cloud_provider)
            arr.push(v.origin?.default_case?.instance_type)
            arr.push(v.origin?.default_case?.config_type)
            arr.push(v.origin?.cluster_type)
            arr.push(v.modified?.template_id)
            return {
              ...v,
              key: arr.join(', ')
            }
          })}
        size="small"
      />
      <Modal
        title={'Template Diff'}
        visible={!!modalDiff}
        onCancel={handleCancelDiff}
        width={1000}
        destroyOnClose={true}
        okText={'OK'}
        onOk={handleCancelDiff}
      >
        <DiffTemplate
          source={diffParam.source}
          current={diffParam.current}
        ></DiffTemplate>
      </Modal>
    </div>
  )
}

export default TemplateModifyTable
