import React, { type FC, useCallback, useEffect, useState } from 'react';
import {
    Alert,
    DateRangePicker,
    type DateRangePickerValue,
    Field,
    Form,
    Select,
    Sidecar,
} from '@theorchard/suite-components';
import AccountSearchDropdown from 'src/components/accountSearchDropdown';
import SongWriterSearchDropDown from 'src/components/songWriterSearchDropDown';
import { ReportType } from 'src/data/globalTypes';
import { useCreateChangelogReport } from 'src/data/mutations';
import {
    useVendorCompsLazyQuery,
    usePubSongWriterLazyQuery,
} from 'src/data/queries';
import { type Account } from 'src/data/types';
import {
    DATE_RANGE_OPTIONS,
    REPORT_OPTIONS_LIST,
    REPORT_SELECT_BY_LIST,
    REPORT_START_DATE,
} from 'src/pages/pubSongChangesPage/constants';
import {
    AdhocReportType,
    type KeysWithNever,
    type ExtendedReportTypes,
    type ReportOptions,
} from '../../types';
import { getErrorMessage } from '../../utils/errorMessage';
import { dateToString, getTimeNow } from '../../utils/parseReportsData';
import CompositionSearchDropdown from '../compositionSearchDropdown/compositionSearchDropdown';
import type { I18nTerms } from 'src/../../locale/types';
import type { Composition, SongWriter } from 'src/data/types';

interface Props {
    open: boolean;
    closeModal: () => void;
}

export const CLASSNAME = 'CreateChangelogReport';

const CreateChangelogReport: FC<Props> = ({ open, closeModal }) => {
    const [reportType, setReportType] = useState<ExtendedReportTypes | null>(
        null
    );
    const [adhocReportType, setAdhocReportType] =
        useState<ExtendedReportTypes | null>(null);
    const [entityId, setEntityId] = useState<string | undefined>();
    const [songWriterUuid, setSongWriterUuid] = useState<string | undefined>();
    const [date, setDate] = useState<DateRangePickerValue | undefined>();
    const [isReportError, setIsReportError] = useState<boolean>(false);
    const [isSaveBtnDisabled, setIsSaveBtnDisabled] = useState<boolean>(true);

    const { createChangelogReport } = useCreateChangelogReport({
        type: reportType as ReportType,
    });

    const [
        doGetVendorComps,
        { data: vendorCompsCount, loading: vendorCompLoading },
    ] = useVendorCompsLazyQuery({
        draft: false,
        labelUuid: '',
    });

    const [
        doSongWriterSearch,
        { data: pubSongWriter, loading: pubSongWriterLoading },
    ] = usePubSongWriterLazyQuery({ draft: false, publishingSongWriterId: '' });

    const resetAndClose = () => {
        setIsSaveBtnDisabled(false);
        setReportType(null);
        setEntityId(undefined);
        setDate(undefined);
        setAdhocReportType(null);
        closeModal();
    };

    const onSave = async (reportType: ExtendedReportTypes) => {
        if (isSaveBtnDisabled) return;
        setIsSaveBtnDisabled(true);

        const formattedReportType =
            reportType === AdhocReportType.ADHOC_REPORT
                ? (adhocReportType as ReportType)
                : (reportType as ReportType);
        const formattedEndDate = new Date(`${date?.end} ${getTimeNow()}`);

        let selectedEntityId = undefined;
        if (reportType === AdhocReportType.ADHOC_REPORT)
            selectedEntityId =
                adhocReportType === ReportType.ADHOC_WRITER
                    ? songWriterUuid
                    : entityId;

        await createChangelogReport({
            variables: {
                type: formattedReportType,
                entityId: selectedEntityId,
                startDate:
                    reportType === AdhocReportType.ADHOC_REPORT && date?.start
                        ? new Date(date.start)
                        : undefined,
                endDate:
                    reportType === AdhocReportType.ADHOC_REPORT && date?.end
                        ? formattedEndDate
                        : undefined,
            },
        });

        resetAndClose();
    };

    const handleAccountChange = useCallback(
        (account?: Account) => {
            setEntityId(account?.id.toString());
            doGetVendorComps({
                variables: { draft: false, labelUuid: account?.uuid ?? '' },
            });
        },
        [setEntityId, doGetVendorComps]
    );

    const handleCompositionChange = useCallback(
        (composition?: Composition) => {
            setEntityId(composition?.id);
        },
        [setEntityId]
    );

    const handleSongWriterChange = useCallback(
        (sw: SongWriter | undefined) => {
            setSongWriterUuid(sw?.id);
            doSongWriterSearch({
                variables: {
                    draft: false,
                    publishingSongWriterId: sw?.id ?? '',
                },
            });
        },
        [doSongWriterSearch]
    );

    useEffect(() => {
        setIsSaveBtnDisabled(
            !reportType ||
                (reportType.startsWith('ADHOC') &&
                    ((!songWriterUuid && !entityId) || !date))
        );
    }, [reportType, entityId, songWriterUuid, date]);

    useEffect(() => {
        const isVendorCompositionsEmpty =
            entityId && !vendorCompLoading && vendorCompsCount === 0;
        const isSwCompositionsEmpty =
            songWriterUuid &&
            !pubSongWriterLoading &&
            !pubSongWriter?.compositions.length;

        if (isVendorCompositionsEmpty || isSwCompositionsEmpty) {
            setIsSaveBtnDisabled(true);
            setIsReportError(true);
        } else if (isReportError) {
            setIsSaveBtnDisabled(false);
            setIsReportError(false);
        }
    }, [
        entityId,
        vendorCompsCount,
        isReportError,
        vendorCompLoading,
        pubSongWriter?.compositions,
        pubSongWriterLoading,
        songWriterUuid,
    ]);

    const selectOptions = (options: ReportOptions[]) =>
        options.map(option => ({
            value: option.value,
            label: $t(option.label as KeysWithNever<I18nTerms>),
        }));

    const handleModalClose = () => {
        setIsReportError(false);
        resetAndClose();
    };

    return (
        <Sidecar
            isOpen={open}
            onRequestClose={() => handleModalClose()}
            title="Generate Report"
            onConfirm={() => {
                void onSave(reportType as ReportType);
            }}
            confirmDisabled={isSaveBtnDisabled}
        >
            <Form
                className={`${CLASSNAME}-form`}
                data-testid={`${CLASSNAME}-form`}
            >
                <Field
                    controlId="report-layout"
                    labelText={$t('tools.pubSongChangesPage.labelReportLayout')}
                >
                    <Select
                        options={selectOptions(REPORT_OPTIONS_LIST)}
                        placeholder={$t(
                            'tools.pubSongChangesPage.placeholderReportLayout'
                        )}
                        hideFilter={true}
                        onChange={option =>
                            setReportType(option?.value || null)
                        }
                        testId="layout-dropdown"
                        menuWidth="100%"
                    />
                </Field>
                {reportType === AdhocReportType.ADHOC_REPORT && (
                    <Field
                        controlId="adhoc-report-select"
                        labelText={$t('tools.pubSongChangesPage.selectBy')}
                        className={`${CLASSNAME}-adhoc-block`}
                    >
                        <Select
                            options={selectOptions(REPORT_SELECT_BY_LIST)}
                            placeholder={$t(
                                'tools.pubSongChangesPage.selectValue'
                            )}
                            hideFilter={true}
                            onChange={option => {
                                setEntityId(undefined);
                                setAdhocReportType(option?.value || null);
                            }}
                            testId="selectBy-dropdown"
                        />
                    </Field>
                )}
                {reportType === AdhocReportType.ADHOC_REPORT &&
                    adhocReportType === ReportType.ADHOC_VENDOR && (
                        <Field
                            controlId="adhoc-report-vendor"
                            labelText={$t('tools.pubSongChangesPage.account')}
                        >
                            <AccountSearchDropdown
                                menuWidth="100%"
                                onChange={handleAccountChange}
                                placeholder={$t(
                                    'tools.artistNameUpdateSidecar.accountDropdownPlaceHolder'
                                )}
                                testId="account-search-dropdown"
                            />
                        </Field>
                    )}
                {reportType === AdhocReportType.ADHOC_REPORT &&
                    adhocReportType === ReportType.ADHOC_WRITER && (
                        <Field
                            controlId="adhoc-report-sw"
                            labelText={$t(
                                'tools.pubSongChangesPage.songwriter'
                            )}
                        >
                            <SongWriterSearchDropDown
                                onChange={handleSongWriterChange}
                                placeholder={$t(
                                    'tools.artistNameUpdateSidecar.songWriterDropdownPlaceHolder'
                                )}
                                testId="sw-search-dropdown"
                            />
                        </Field>
                    )}
                {reportType === AdhocReportType.ADHOC_REPORT &&
                    adhocReportType === ReportType.ADHOC_COMPOSITION && (
                        <Field
                            controlId="adhoc-report-composition"
                            labelText={$t(
                                'tools.pubSongChangesPage.composition'
                            )}
                        >
                            <CompositionSearchDropdown
                                compositionId={entityId}
                                onChange={handleCompositionChange}
                                placeholder={$t(
                                    'tools.pubSongChangesPage.compositionSearchPlaceholder'
                                )}
                                testId="composition-search-dropdown"
                            />
                        </Field>
                    )}
                {reportType === AdhocReportType.ADHOC_REPORT &&
                    !!adhocReportType && (
                        <Field
                            controlId="report-date"
                            labelText={$t('tools.pubSongChangesPage.dateRange')}
                        >
                            <DateRangePicker
                                customDateRange={{
                                    start: REPORT_START_DATE,
                                    end: dateToString(new Date()),
                                }}
                                selectedValue={date}
                                options={DATE_RANGE_OPTIONS}
                                onChange={date => setDate(date)}
                                showOptionLabel
                            />
                        </Field>
                    )}
                {isReportError && (
                    <Alert
                        text={getErrorMessage(adhocReportType)}
                        variant="error"
                    />
                )}
            </Form>
        </Sidecar>
    );
};

export default CreateChangelogReport;
