import { Alert, Modal } from '@theorchard/suite-components';
import dayjs from 'dayjs';
import { isEmpty } from 'lodash';
import React, { useState } from 'react';
import ReleaseScheduleDisplay from '../releaseScheduleDisplay';
import ReleaseScheduleTable from '../releaseScheduleTable';
import TimedReleaseScheduleEditor from '../timedReleaseScheduleEditor';
import type { FC } from 'react';
import type {
    AddToTimedReleaseParams,
    DeliveryStore,
    Product,
    ReleaseSchedule,
    TimedReleaseSchedule,
    UnsupportedTimedReleaseSchedule,
} from 'src/types';

export const calcProcessAtDisplayDate = (
    dateString: string,
    offset: string
) => {
    const [hours, minutes] = offset.split(':');
    const datetime = dayjs.utc(dateString);
    const dateOffset = datetime
        .subtract(parseInt(hours), 'hour')
        .subtract(parseInt(minutes), 'minute');
    return dateOffset.format('hh:mma [GMT on] DD MMM YYYY');
};

interface TimedSchedules {
    timed: TimedReleaseSchedule[];
    unsupportedTimed: UnsupportedTimedReleaseSchedule[];
}

export interface TimedReleaseScheduleModalProps {
    isOpen: boolean;
    setIsOpen: (isOpen: boolean) => void;
    deliveryStores: DeliveryStore[];
    carvedOutStores: DeliveryStore[];
    product: Product;
    onSave: (schedules: TimedSchedules) => void;
}

const TimedReleaseScheduleModal: FC<TimedReleaseScheduleModalProps> = ({
    isOpen,
    setIsOpen,
    deliveryStores,
    carvedOutStores,
    product,
    onSave,
}) => {
    const [releaseSchedule, setReleaseSchedule] = useState<TimedSchedules>({
        ...product.releaseSchedule,
    });

    const { timed, unsupportedTimed } = releaseSchedule;

    const unscheduledStores: DeliveryStore[] = deliveryStores.filter(
        store =>
            ![...timed, ...unsupportedTimed].some(
                timeStore => timeStore.deliveryStore.id === store.id
            )
    );

    const alreadySelectedStores: DeliveryStore[] = [
        ...timed,
        ...unsupportedTimed,
        ...product.releaseSchedule.staggered,
    ].map(releaseEntry => releaseEntry.deliveryStore);

    const noSchedules = isEmpty(timed) && isEmpty(unsupportedTimed);
    const existingSaleDateTime = !noSchedules
        ? isEmpty(timed)
            ? unsupportedTimed[0].saleDateTime
            : timed[0].saleDateTime
        : undefined;

    const existingTimeOffset = isEmpty(unsupportedTimed)
        ? undefined
        : unsupportedTimed[0].timeOffset;

    const handleRemove = (schedules: ReleaseSchedule[] | ReleaseSchedule) => {
        const scheduledStores = Array.isArray(schedules)
            ? schedules
            : [schedules];
        setReleaseSchedule({
            timed: timed.filter(
                time => !scheduledStores.some(schedule => schedule === time)
            ),
            unsupportedTimed: unsupportedTimed.filter(
                time => !scheduledStores.some(schedule => schedule === time)
            ),
        });
    };

    const handleAddToSchedule = (params: AddToTimedReleaseParams) => {
        const update: TimedSchedules = {
            timed: [...timed, ...params.timed],
            unsupportedTimed: [...unsupportedTimed, ...params.unsupportedTimed],
        };
        setReleaseSchedule(update);
    };

    return (
        <Modal
            testId="timed-release-schedule-modal"
            className="TimedReleaseScheduleModal"
            title={$t('releaseScheduler.timedReleaseScheduleModal.header')}
            isOpen={isOpen}
            onRequestClose={() => {
                setReleaseSchedule({ ...product.releaseSchedule });
                setIsOpen(false);
            }}
            onConfirm={() => {
                setIsOpen(false);
                onSave({ timed, unsupportedTimed });
            }}
            confirmTitle={$t(
                'releaseScheduler.timedReleaseScheduleModal.saveAndClose'
            )}
        >
            <div className="TimedReleaseScheduleModal">
                <TimedReleaseScheduleEditor
                    hasTimedReleases={
                        !isEmpty(timed) || !isEmpty(unsupportedTimed)
                    }
                    product={product}
                    className="TimedReleaseScheduleModal-editor"
                    deliveryStores={unscheduledStores}
                    disabledStores={alreadySelectedStores}
                    carvedOutStores={carvedOutStores}
                    onAddToSchedule={handleAddToSchedule}
                    existingSaleDateTime={
                        existingSaleDateTime
                            ? dayjs.utc(existingSaleDateTime).toDate()
                            : undefined
                    }
                    existingTimeOffset={existingTimeOffset}
                />
                <ReleaseScheduleDisplay
                    title={$t(
                        'releaseScheduler.timedReleaseScheduleModal.releaseScheduleDisplayTitle'
                    )}
                    product={product}
                >
                    {(!isEmpty(timed) || noSchedules) && (
                        <ReleaseScheduleTable
                            testId="timed-supported-table"
                            className="TimedReleaseScheduleModal-table"
                            onRemove={handleRemove}
                            releaseSchedule={timed}
                            editable={true}
                            totalServicesPrompt={$t(
                                'releaseScheduler.timedReleaseScheduleModal.supportedServicesPrompt',
                                { storeCount: timed.length }
                            )}
                        />
                    )}
                    {!isEmpty(unsupportedTimed) && (
                        <>
                            {existingSaleDateTime && existingTimeOffset && (
                                <Alert
                                    testId="timed-unsupported-alert"
                                    className="TimedReleaseScheduleModal-timed-unsupported-alert"
                                    text={$t(
                                        'releaseScheduler.timedReleaseScheduleModal.nonTimedReleaseSupport',
                                        {
                                            dateString:
                                                calcProcessAtDisplayDate(
                                                    existingSaleDateTime,
                                                    existingTimeOffset
                                                ),
                                        }
                                    )}
                                    variant="information"
                                />
                            )}
                            <ReleaseScheduleTable
                                testId="timed-unsupported-table"
                                className="TimedReleaseScheduleModal-table"
                                onRemove={handleRemove}
                                releaseSchedule={unsupportedTimed}
                                editable={true}
                                totalServicesPrompt={$t(
                                    'releaseScheduler.timedReleaseScheduleModal.unsupportedServicesPrompt',
                                    {
                                        storeCount: unsupportedTimed.length,
                                    }
                                )}
                            />
                        </>
                    )}
                </ReleaseScheduleDisplay>
            </div>
        </Modal>
    );
};

export default TimedReleaseScheduleModal;
