import { TreeSelect } from 'antd'
import { DefaultValueType } from 'rc-tree-select/lib/interface'
import { useState, useEffect, ReactNode } from 'react'
import { useHistory, useRouteMatch } from 'react-router-dom'

import { isRawDate } from '../utils'
import LoaderPortal from './LoaderPortal'
import { WellIcon, WellIconState } from './icons'
import { invokeWebApiWrapperAsync } from './factory'
import { DepositService, DepositDto } from '../services/api'

import { ReactComponent as DepositIcon } from '../images/DepositIcon.svg'
import { ReactComponent as ClusterIcon } from '../images/ClusterIcon.svg'

import '../styles/wellTreeSelect.css'

export const getWellState = (idState?: number): WellIconState => idState === 1 ? 'active' : 'unknown'
export const checkIsWellOnline = (lastTelemetryDate: unknown): boolean =>
    isRawDate(lastTelemetryDate) && (Date.now() - +new Date(lastTelemetryDate) < 600_000)

export type TreeNodeData = {
    title?: string | null
    key?: string
    value?: DefaultValueType
    icon?: ReactNode
    children?: TreeNodeData[]
}

const getLabel = (wellsTree: TreeNodeData[], value?: string): string | undefined => {
    if (!value) return value
    const type = value.replaceAll('/', ' ').trim().split(' ')[0]
    let deposit: TreeNodeData | undefined
    let cluster: TreeNodeData | undefined
    let well: TreeNodeData | undefined
    switch (type) {
        case 'cluster':
            deposit = wellsTree.find((deposit) => (
                cluster = deposit.children?.find((cluster: TreeNodeData) => cluster.key === value)
            ))
            if (deposit && cluster)
                return `${deposit.title} / ${cluster.title}`
            break
        case 'well':
            deposit = wellsTree.find((deposit) => (
                cluster = deposit.children?.find((cluster: TreeNodeData) => (
                    well = cluster.children?.find((well: TreeNodeData) => well.key === value)
                ))
            ))
            if (deposit && cluster && well)
                return `${deposit.title} / ${cluster.title} / ${well.title}`
            break
        default: break
    }
    return value
}

export const WellTreeSelector = () => {
    const [wellsTree, setWellsTree] = useState<any[]>([]) // TODO: Исправить тип (необходимо разобраться с типом value rc-select)
    const [showLoader, setShowLoader] = useState<boolean>(false)
    const [value, setValue] = useState<string>()
    const history = useHistory()
    const routeMatch = useRouteMatch('/:route/:id')

    useEffect(() => {
        invokeWebApiWrapperAsync(
            async () => {
                const deposits: Array<DepositDto> = await DepositService.getDeposits()
                const wellsTree: TreeNodeData[] = deposits.map(deposit =>({
                    title: deposit.caption,
                    key: `/deposit/${deposit.id}`,
                    value: `/deposit/${deposit.id}`,
                    icon: <DepositIcon width={24} height={24}/>,
                    children: deposit.clusters?.map(cluster => ({
                        title: cluster.caption,
                        key: `/cluster/${cluster.id}`,
                        value: `/cluster/${cluster.id}`,
                        icon: <ClusterIcon width={24} height={24}/>,
                        children: cluster.wells?.map(well => ({
                            title: well.caption,
                            key: `/well/${well.id}`,
                            value: `/well/${well.id}`,
                            icon: <WellIcon
                                width={24}
                                height={24}
                                state={getWellState(well.idState)}
                                online={checkIsWellOnline(well.lastTelemetryDate)}
                            />
                        })),
                    })),
                }))
                setWellsTree(wellsTree)
            },
            setShowLoader,
            `Не удалось загрузить список скважин`
        )
    }, [])

    useEffect(() => {
        setValue(getLabel(wellsTree, routeMatch?.url))
    }, [wellsTree, routeMatch])

    const onChange = (value: string): void => {
        if (wellsTree)
            setValue(getLabel(wellsTree, value))
    }

    const onSelect = (value: string): void => {
        if (value) history.push(value)
    }

    return (
        <LoaderPortal show={showLoader}>
            <TreeSelect
                treeIcon
                className={'header-tree-select'}
                bordered={false}
                dropdownMatchSelectWidth={false}
                placeholder={'Выберите месторождение'}
                treeData={wellsTree}
                treeDefaultExpandAll
                onSelect={onSelect}
                onChange={onChange}
                value={value}
                style={{ width: '350px' }}
            />
        </LoaderPortal>
    )
}

export default WellTreeSelector
