import React, { useState, useReducer, useCallback } from 'react';
import { useApolloClient } from '@apollo/client';
import {
    Alert,
    Button,
    Radio,
    Field,
    Form,
    HelpTooltip,
} from '@theorchard/suite-components';
import { RouteLink, useIdentity } from '@theorchard/suite-frontend';
import cx from 'classnames';
import { isString } from 'lodash';
import { type SubmitHandler, useForm } from 'react-hook-form';
import ContributorsSearchDropdown from 'src/components/contributorsSearchDropdown';
import DeliveryStoresDropdown from 'src/components/deliveryStoresDropdown';
import { useCreateNrDeliveryOrderMutation } from 'src/data/mutations';
import { evictRootQueryFromCache } from 'src/data/utils';
import { type ParamValue } from 'src/utils/route';
import {
    recordGenerateOrderClicked,
    recordReDeliverCatalogClicked,
    recordDeliveryContributorFilter,
    recordDeliveryStoreFilter,
} from 'src/utils/segment';
import { type NrContributorsSearch_nrContributorSearch_contributors as NrContributors } from '../../data/queries/nrContributorSearch/__generated__/NrContributorsSearch';

export const CLASSNAME = 'CreateOrder';
export const TRANSLATION_KEY = 'neighbouringRights.createOrder';

export interface FormFields {
    cmoId: string;
    reDeliver: boolean;
    nrContributorIds: string[] | null;
}

let defaultSelection: NrContributors | null;

const CreateOrder = () => {
    const { roles } = useIdentity();
    const multipleRoles = roles && roles.length > 1;

    const [storeId, setStoreId] = useState<string | undefined>(undefined);
    const [reDeliver, setReDeliver] = useState<boolean>(false);
    const [deliver, setdeliver] = useState<boolean>(true);
    const [contributorId, setContributorId] = useState<string | undefined>(
        undefined
    );
    const { setValue, getValues, handleSubmit } = useForm<FormFields>({
        mode: 'onSubmit',
    });

    const [canSubmit, updateCanSubmit] = useReducer(
        () => !!getValues().cmoId,
        false
    );

    const client = useApolloClient();

    const handleContributorChange = useCallback(
        (contributor?: NrContributors | undefined) => {
            if (!contributor) {
                setValue('nrContributorIds', null);
                setContributorId(undefined);
            } else {
                setValue('nrContributorIds', [contributor.id]);
                setContributorId(contributor.id);
            }
            recordDeliveryContributorFilter(contributor?.name, contributor?.id);
            setReDeliver(false);
            updateCanSubmit();
        },
        [setValue, setContributorId]
    );

    if (!contributorId && storeId)
        defaultSelection = {
            id: '',
            name: $t(`${TRANSLATION_KEY}.allContributors`),
        };
    else if ((contributorId && storeId) || (!contributorId && !storeId))
        defaultSelection = null;

    const { createNrDeliveryOrder, data, loading, error } =
        useCreateNrDeliveryOrderMutation({
            cmoId: '',
            reDeliver: false,
            nrContributorIds: null,
        });

    const submitting = !!error || loading;

    const handleStoreChange = (
        value: string | Record<string, ParamValue | undefined>
    ) => {
        if (!value) setValue('cmoId', '');
        else if (isString(value)) setValue('cmoId', value);
        else setValue('cmoId', value.store?.toString() ?? '');
        recordDeliveryStoreFilter(getValues().cmoId);
        setStoreId(getValues().cmoId);
        updateCanSubmit();
    };

    const handleReDeliverChange = (checked: boolean) => {
        if (checked) recordReDeliverCatalogClicked();
        setValue('reDeliver', checked);
        setReDeliver(checked);
        setdeliver(!checked);

        updateCanSubmit();
    };

    const handleDeliverChange = (checked: boolean) => {
        if (checked) recordReDeliverCatalogClicked();
        setValue('reDeliver', !checked);
        setReDeliver(!checked);
        setdeliver(checked);

        updateCanSubmit();
    };

    const onSubmit: SubmitHandler<FormFields> = async formData => {
        recordGenerateOrderClicked();
        await createNrDeliveryOrder({ variables: formData });
        handleStoreChange('');
        handleContributorChange(undefined);
        handleReDeliverChange(false);
        updateCanSubmit();
        evictRootQueryFromCache('nrDeliveryOrders', client);
    };

    const WelcomeMessage = () => (
        <>
            <div className={`${CLASSNAME}-createOptionMessage`}>
                {$t(`${TRANSLATION_KEY}.selectServicesAndContributorsTitle`)}
            </div>
            <div className={`${CLASSNAME}-optionsMessage`}>
                {$t(
                    `${TRANSLATION_KEY}.selectServicesAndContributorsDescription`
                )}
            </div>
        </>
    );

    const SuccessMessage = () => (
        <>
            {data && (
                <>
                    <div className={`${CLASSNAME}-createOptionMessage`}>
                        {$t(`${TRANSLATION_KEY}.orderSuccessAlertTitle`)}
                    </div>
                    <Alert
                        className="alert-success"
                        variant="success"
                        testId="successMessage"
                        text={
                            <span>
                                {$t(
                                    `${TRANSLATION_KEY}.orderSuccessAlertMessage`,
                                    {
                                        orderId: data.id,
                                    }
                                )}
                            </span>
                        }
                    />
                    <div className={`${CLASSNAME}-successOrderMessage`}>
                        {$t(`${TRANSLATION_KEY}.trackOrderMessage`)}
                    </div>
                </>
            )}
        </>
    );

    return (
        <div className={CLASSNAME}>
            <div className={`${CLASSNAME}-container`}>
                <div className={`${CLASSNAME}-welcome`}>
                    {!data && <WelcomeMessage />}
                    {data && <SuccessMessage />}
                    {error && (
                        <Alert
                            variant="error"
                            testId="errorMessage"
                            text={$t(`${TRANSLATION_KEY}.orderErrorMessage`)}
                        />
                    )}
                </div>
            </div>

            <Form
                className={`${CLASSNAME}-form`}
                onSubmit={async e => {
                    await handleSubmit(onSubmit)(e);
                }}
            >
                <div className="row">
                    <Field
                        controlId="cmoId"
                        className="FormField wide service"
                        labelText={$t(`${TRANSLATION_KEY}.cmo`)}
                        testId="selectCmo"
                    >
                        <DeliveryStoresDropdown
                            data-testId="deliveryStoresDropdown"
                            placeholder={$t(`${TRANSLATION_KEY}.cmo`)}
                            onChange={value => handleStoreChange(value)}
                            storeId={storeId}
                        />
                    </Field>
                </div>
                <div className="row">
                    <HelpTooltip
                        id="contributors-tooltip"
                        className="HelpTooltip-dropdown"
                        message={$t(`${TRANSLATION_KEY}.contributorsTooltip`)}
                    >
                        <Field
                            controlId="nrContributorIds"
                            className="FormField wide contributor"
                            labelText={$t(
                                `${TRANSLATION_KEY}.selectContributors`
                            )}
                            testId="SearchDropdown"
                            isRequired
                        >
                            <ContributorsSearchDropdown
                                onChange={contributor =>
                                    handleContributorChange(contributor)
                                }
                                placeholder={$t(
                                    `${TRANSLATION_KEY}.contributorLegalName`
                                )}
                                contributorId={contributorId}
                                disabled={!storeId}
                                defaultSelection={defaultSelection}
                                storeId={storeId}
                                showEligible
                            />
                        </Field>
                    </HelpTooltip>
                </div>
                <div className={`${CLASSNAME}-redelivery-container`}>
                    <div className={`${CLASSNAME}-redelivery-title`}>
                        {$t(`${TRANSLATION_KEY}.redeliverTitle`)}
                    </div>
                </div>
                <div className={`${CLASSNAME}-redelivery-radio-container`}>
                    <div className={`${CLASSNAME}-redelivery-radio-button`}>
                        <HelpTooltip
                            id="redeliver-tooltip"
                            message={$t(`${TRANSLATION_KEY}.redeliverTooltip`)}
                        >
                            <Radio
                                id="redeliver"
                                className="FormField"
                                label={$t(`${TRANSLATION_KEY}.yes`)}
                                name="1"
                                checked={reDeliver}
                                disabled={!contributorId}
                                onChange={event =>
                                    handleReDeliverChange(event.target.checked)
                                }
                            />
                        </HelpTooltip>
                    </div>
                </div>
                <div className={`${CLASSNAME}-redelivery-radio-container`}>
                    <div className={`${CLASSNAME}-redelivery-radio-button`}>
                        <Radio
                            id="deliver"
                            className="FormField"
                            label={$t(`${TRANSLATION_KEY}.no`)}
                            name="1"
                            checked={deliver}
                            disabled={!contributorId}
                            onChange={event =>
                                handleDeliverChange(event.target.checked)
                            }
                        />
                    </div>
                </div>
                <div className={cx(`${CLASSNAME}-buttons`, 'row')}>
                    {multipleRoles && (
                        <div className="FormField">
                            <RouteLink
                                routeId="nrDelivery"
                                data-testid="back-to-delivery-button"
                                className={
                                    data
                                        ? `${CLASSNAME}-back-main-section-button`
                                        : `${CLASSNAME}-back-button`
                                }
                            >
                                {data
                                    ? $t(
                                          `${TRANSLATION_KEY}.backToMainSelection`
                                      )
                                    : $t(`${TRANSLATION_KEY}.back`)}
                            </RouteLink>
                        </div>
                    )}
                    <div className="FormField">
                        <Button
                            type="submit"
                            disabled={!canSubmit || submitting}
                            className={`${CLASSNAME}-submit-button`}
                            variant="primary"
                            data-testid="save-performance-button"
                        >
                            {$t(`${TRANSLATION_KEY}.generateOrder`)}
                        </Button>
                    </div>
                </div>
            </Form>
        </div>
    );
};

export default CreateOrder;
