import dayjs, {Dayjs} from 'dayjs'
import {Component, MouseEvent} from 'react'
import {UiPanel} from '../ui-comps/ui-panel'
import {DatePickerState, TypeInnerDatePicker} from '../inner-comps/create-inner-date-picker'
import {UiPanelTitle} from '../ui-comps/ui-panel-title'
import {UiItemLayout} from '../ui-comps/ui-item-layout'
import {getQuarterRows} from '../utils/date-utils'
import {TypeLayoutItem} from '../module-defs/ui-types'
import {UILayoutItem} from '../ui-comps/ui-item'
import {createAside} from './create-aside'
import {createInitOpts} from './create-init-opts'
import {createDisplayedDateSwitcher} from './create-date-switcher'


export interface TypeInitOpts {
    onSelected: (value: Dayjs) => void
    onZoomIn?: () => void
}

export function createQuarterPanel(
    comp: TypeInnerDatePicker,
    {
        isRange = false,
        isStartPanel = false,

        valueProp,
        displayProp,

        onMouseDown,

        getTitle,
    }: {
        isForDateZooming?: boolean
        isRange?: boolean
        isStartPanel?: boolean

        valueProp: 'value' | 'displayedDate'
        displayProp: 'displayedDate' | 'zoomedDisplayedDate'

        onMouseDown?: (e: MouseEvent) => void

        getTitle: (date: Dayjs) => string
    }
) {

    const initOpts = createInitOpts<TypeInitOpts>('MonthPanel')
    const displayedSwitcher = createDisplayedDateSwitcher(
        comp,
        {
            displayProp,
        }
    )

    const aside = createAside(
        comp,
        {
            displayProp,
        }
    )

    const getDisplayed = () => comp.state[displayProp]!;

    const getPanelTitleText = () => {
        return getTitle(getDisplayed())
    }

    const handleZoomIn = () => {
        initOpts.get().onZoomIn!()
    };

    const getSelectedValueTimestamp = () => {
        const value = comp.state[valueProp]
        return value && value.startOf('quarter').valueOf()
    };

    const handleSelectDate = (selectedTimestamp?: number) => {
        const selectedDate = dayjs(selectedTimestamp);

        (comp as Component<unknown, Partial<DatePickerState>>).setState({
            [valueProp]: selectedDate,
        })

        initOpts.get().onSelected(selectedDate)
    };

    const renderContentItem = (
        today: Dayjs,
        selectedValueTimestamp: number | null,
        item: TypeLayoutItem
    ) => {
        const data = item.data!
        let disabled = false

        if (comp.props.getDisabledItem) {
            disabled = comp.props.getDisabledItem(data.date, today)
        }

        const itemValue = item.data!.date.valueOf()

        return {
            elem: <UILayoutItem
                key={item.key}
                value={itemValue}
                text={item.text}
                selected={itemValue === selectedValueTimestamp}
                disabled={disabled}
                onClick={handleSelectDate}
            />,
        }
    };

    const renderPanelContent = () => {
        const displayed = getDisplayed()
        return (
            <UiItemLayout
                rows={
                    getQuarterRows(displayed.year())
                }
                /* eslint-disable-next-line react/jsx-no-bind */
                renderItem={
                    renderContentItem.bind(
                        null,
                        dayjs().startOf('quarter'),
                        getSelectedValueTimestamp()
                    )
                }
            />
        )
    };

    const renderPanelTitle = () => {
        const {
            goBackwardYear,
            goForwardYear,
            goBackwardMonth,
            goForwardMonth,
        } = displayedSwitcher

        return (
            <UiPanelTitle
                text={getPanelTitleText()}
                withZoomingIcon={false}
                isZooming
                shouldShowInner={false}
                rangeControl={
                    !isRange ? 'none'
                        : isStartPanel ? 'right' : 'left'
                }
                rangeShowType={
                // @todo:impl 考虑上年份的区别
                    !isRange ? 'both' : 'none'
                }
                onFastLeftClick={goBackwardYear}
                onFastRightClick={goForwardYear}
                onPlainLeftClick={goBackwardMonth}
                onPlainRightClick={goForwardMonth}
                onZoomingClick={handleZoomIn}
            />
        )
    };


    const api = {
        init(
            opts: TypeInitOpts
        ) {
            initOpts.init(opts)

            const switcherOpts = {
                onDisplayDateChange: (displayedDate: Dayjs) => {
                    aside.setYearRangeAnchor(displayedDate.year())
                    aside.syncAsideScroll()
                },
            }
            displayedSwitcher.init(switcherOpts)
        },

        renderPanel() {
            return (
                <UiPanel
                    titleElem={renderPanelTitle()}
                    contentElem={renderPanelContent()}
                    asideElem={aside.render()}
                    contentType={'quarter'}
                    onMouseDown={onMouseDown}
                />
            )
        },
    }

    return aside.extendApi(api)
}
