'use client';

import React, { FC, useEffect, useState } from 'react';
import classNames from 'classnames';
import { Modal, Menu, Calendar, Radio, Button, Input, message } from 'antd';
import type { CalendarProps, RadioChangeEvent, MenuProps } from 'antd';
import { ArrowLeftOutlined } from '@ant-design/icons';
import { CloseOutlined } from '@ant-design/icons';
import locale_ru from 'antd/lib/calendar/locale/ru_RU';
import locale_en from 'antd/lib/calendar/locale/en_GB';
import locale_de from 'antd/lib/calendar/locale/de_DE';
import locale_it from 'antd/lib/calendar/locale/it_IT';
import locale_es from 'antd/lib/calendar/locale/es_ES';
import locale_fr from 'antd/lib/calendar/locale/fr_FR';
import { RegisterContent, ResetContent, FinishContent, EnterContent } from './authModalContent';
import dayjs, { Dayjs } from 'dayjs';
import 'dayjs/locale/ru';
import 'dayjs/locale/en';
import 'dayjs/locale/de';
import 'dayjs/locale/it';
import 'dayjs/locale/fr';
import 'dayjs/locale/es';
import { ExpertScheduler, SignupSessionData } from "../../types/experts";
import { Tag } from "../../types/tags";
import { useLocalStorage } from "../../hooks/useLocalStorage";
import { AUTH_TOKEN_KEY } from "../../constants/common";
import { getSchedulerByExpertId, getSchedulerSession } from "../../actions/experts";
import { ElementsForm } from "../stripe/ElementsForm";
import { i18nText } from '../../i18nKeys';
import { CustomSelect } from '../../components/view/CustomSelect';

type ScheduleModalProps = {
    open: boolean;
    handleCancel: () => void;
    mode: 'data' | 'time' | 'pay' | 'finish';
    updateMode: (mode: 'data' | 'time' | 'pay' | 'finish') => void;
    sessionCost: number;
    expertId: string;
    locale: string;
};

type MenuItem = Required<MenuProps>['items'][number];

const getLocale = (locale: string) => {
    if (locale) {
        switch (locale) {
            case 'ru':
                return locale_ru;
            case 'de':
                return locale_de;
            case 'fr':
                return locale_fr;
            case 'it':
                return locale_it;
            case 'es':
                return locale_es;
            default:
                return locale_en;
        };
    }

    return locale_en;
};

const getCalendarMenu = (start: Dayjs): MenuItem[] => Array.from({ length: 3 })
    .map((_: unknown, index: number) => {
        const date = index ? start.add(index, 'M') : start.clone();
        return {
            label: <span className="b-calendar-month">{date.format('MMMM')}</span>,
            key: date.format('YYYY-MM-DD')
        }
    });

export const ScheduleModal: FC<ScheduleModalProps> = ({
    open,
    handleCancel,
    mode,
    updateMode,
    sessionCost,
    locale,
    expertId,
}) => {
    const [selectDate, setSelectDate] = useState<Dayjs>(dayjs());
    const [dates, setDates] = useState<any>();
    const [tags, setTags] = useState<Tag[] | undefined>();
    const [sessionData, setSesssionData] = useState<SignupSessionData>({ coachId: +expertId });
    const [sessionId, setSessionId] = useState<number>(-1);
    const [rawScheduler, setRawScheduler] = useState<ExpertScheduler | null>(null);
    const [jwt] = useLocalStorage(AUTH_TOKEN_KEY, '');
    const [isPayLoading, setIsPayLoading] = useState<boolean>(false);

    dayjs.locale(locale);

    useEffect(()=> {
        if (open) {
            getSchedulerByExpertId(expertId as string, locale as string)
                .then((data) => {
                    setRawScheduler(data);
                })
                .catch((err) => {
                    console.log(err);
                });
        }
    }, [open]);

    useEffect(() => {
        const map = {} as any
        rawScheduler?.availableSlots.forEach((el) => {
            const key = dayjs(el.startTime).format('YYYY-MM-DD');
            if (!map[key]){
                map[key] = []
            }
            map[key].push(el);
        })
        setDates(map);
        setTags(rawScheduler?.tags)
    }, [rawScheduler]);

    const onPanelChange = (value: Dayjs) => setSelectDate(value);

    const onDateChange: CalendarProps<Dayjs>['onSelect'] = (value, selectInfo) => {
        if (selectInfo.source === 'date') {
            setSelectDate(value);
            updateMode('time');
        }
    };

    const disabledDate = (currentDate: Dayjs) => !dates || !dates[currentDate.format('YYYY-MM-DD')];

    const onChangeTimeSlot = (e: RadioChangeEvent) => setSesssionData({ ...sessionData, startAtUtc: e.target.value.startTime });

    const onChangeTag = (tagId: number) => setSesssionData({ ...sessionData, tagId });

    const singupSession = () => {
        console.log(sessionData);
        if (sessionData?.startAtUtc && sessionData?.tagId) {
            if (jwt) {
                setIsPayLoading(true);
                getSchedulerSession(sessionData, locale, jwt)
                    .then((session) => {
                        console.log(session);
                        // тут должна быть проверка все ли с регистрацией сессии
                        setSessionId(+session?.sessionId);
                        updateMode('pay');
                    })
                    .catch((err) => {
                        console.log(err);
                        message.error('Не удалось провести оплату')
                    })
                    .finally(() => {
                        setIsPayLoading(false);
                    })
            } else {

            }
        }
    }

    const cellRender: CalendarProps<Dayjs>['fullCellRender'] = (date, info) => {
        const isWeekend = date.day() === 6 || date.day() === 0;
        return React.cloneElement(info.originNode, {
            ...info.originNode.props,
            className: classNames('b-calendar-cell', {
                ['b-calendar-cell__select']: selectDate.isSame(date, 'date'),
                ['b-calendar-cell__today']: date.isSame(dayjs(), 'date'),
                ['b-calendar-cell__weekend']: isWeekend,
            }),
            children: (
                <div>
                    <span>
                        {date.get('date')}
                    </span>
                </div>
            ),
        });
    };

    return (
        <Modal
            className="b-modal"
            open={open}
            title={undefined}
            onOk={undefined}
            onCancel={handleCancel}
            footer={false}
            width={498}
            closeIcon={<CloseOutlined style={{ fontSize: 20, color: '#000' }}/>}
        >
            {mode === 'data' && (
                <Calendar
                    className="b-calendar"
                    fullscreen={false}
                    onPanelChange={onPanelChange}
                    fullCellRender={cellRender}
                    onSelect={onDateChange}
                    value={selectDate}
                    disabledDate={disabledDate}
                    locale={getLocale(locale)}
                    validRange={[selectDate.startOf('M'), selectDate.endOf('M')]}
                    headerRender={({ onChange }) => {
                        const start = dayjs().startOf('M');
                        const [activeMonth, setActiveMonth] = useState<string>(start.format('YYYY-MM-DD'));

                        const onClick: MenuProps['onClick'] = (e) => {
                            setActiveMonth(e.key);
                            onChange(dayjs(e.key));
                        };

                        return (
                            <Menu
                                className="b-calendar-header"
                                onClick={onClick}
                                selectedKeys={[activeMonth]}
                                mode="horizontal"
                                items={getCalendarMenu(start)}
                            />
                        );
                    }}
                />
            )}
            {mode === 'time' && (
                <div className="b-schedule-time">
                    <div className="b-schedule-time-header">
                        <Button
                            className="b-button-link-big"
                            type="link"
                            onClick={() => updateMode('data')}
                            icon={<ArrowLeftOutlined />}
                            iconPosition="start"
                        >
                            {selectDate.locale(locale).format('DD MMMM YYYY')}
                        </Button>
                    </div>
                    <div className="b-schedule-select-tag">
                        {tags && (
                            <CustomSelect
                                label={i18nText('selectTopic', locale)}
                                value={sessionData?.tagId}
                                options={tags?.map(({ id, name }) => ({ value: id, label: name }))}
                                onChange={onChangeTag}
                            />
                        )}
                    </div>
                    <div className="b-schedule-radio-list">
                        <Radio.Group name="radiogroupSlots" onChange={onChangeTimeSlot}>
                            {dates[selectDate.format('YYYY-MM-DD')].map((el) => {
                                return (<Radio key={dayjs(el.startTime).format()} value={el}>{dayjs(el.startTime).format('HH:mm')} - {dayjs(el.endTime).format('HH:mm')}</Radio>)
                            })}
                        </Radio.Group>
                    </div>
                    <div>
                        <Input.TextArea
                            className="b-textarea"
                            rows={1}
                            value={sessionData?.clientComment}
                            placeholder={i18nText('sessionWishes', locale)}
                            onChange={(e) => setSesssionData({ ...sessionData, clientComment: e.target.value })}
                        />
                    </div>
                    <Button
                        className="btn-apply"
                        onClick={singupSession}
                        loading={isPayLoading}
                    >
                        {i18nText('pay', locale)}
                    </Button>
                </div>
            )}
            {mode === 'pay' && (
                <ElementsForm amount={sessionCost}/>
            )}
        </Modal>
    );
};
