﻿import type { FC } from 'react';
import { useState } from 'react';
import React from 'react';
import { Form, Sidecar, Select } from '@theorchard/suite-components';
import { useToast } from '@theorchard/suite-frontend';
import {
    ESCALATION_QUEUE_ID,
    INITIAL_QUEUE_ID,
    UNDER_INVESTIGATION_QUEUE_ID,
} from 'src/constants';
import { useReviewEscalationGroupsQuery } from 'src/data/queries/reviewEscalationGroups';
import { trackContentReviewEventMerged } from 'src/utils/product';
import type { TargetGroup } from 'src/data/queries/reviewQueueItem/types';
import type { MergedProduct } from 'src/product/product';
import type { QueueNameIdentifier } from 'src/types';

export const CLASS_NAME = 'ProductModalQueueMoveSidecar';
export const INTL_PREFIX = 'contentReview.productModalQueueMoveSidecar';

const ESCALATION_TYPE_DEFINITIONS_LINK =
    'https://docs.google.com/spreadsheets/d/1z5g9lfU9Yl33mYvLPwOJhzfKPcONdKgM1u2-w32xpCY/edit?gid=1431010267#gid=1431010267';

export interface Props {
    isOpen: boolean;
    closeModal: () => void;
    currentQueueName?: string;
    product: MergedProduct | null;
    productTargetGroup?: TargetGroup | null;
    onQueueMove: (
        destinationQueueName: string,
        movedToTargetId?: number,
        moveNote?: string
    ) => void;
}

const ProductModalQueueMoveSidecar: FC<Props> = ({
    isOpen,
    product,
    closeModal,
    onQueueMove,
    productTargetGroup,
    currentQueueName,
}) => {
    const [note, setNote] = useState<string>('');
    const [destinationQueue, setDestinationQueue] = useState<string>('');
    const [successMessage, setSuccessMessage] = useState<string>('');
    const [selectedTargetGroupId, setSelectedTargetGroupId] = useState<
        number | null
    >(null);
    const [selectedMoveTargetId, setSelectedMoveTargetId] = useState<
        number | null
    >(null);
    const toast = useToast();

    const { data } = useReviewEscalationGroupsQuery();

    const reviewEscalationGroups = data?.reviewEscalationGroups;
    const showEscalationFormGroup = Boolean(
        currentQueueName === ESCALATION_QUEUE_ID ||
            destinationQueue === ESCALATION_QUEUE_ID
    );
    const showDefaultFormGroup = Boolean(
        currentQueueName != ESCALATION_QUEUE_ID
    );

    const handleDestinationQueueChange = (destination: QueueNameIdentifier) => {
        setDestinationQueue(destination);
        setSelectedTargetGroupId(null);
        setSelectedMoveTargetId(null);
        setSuccessMessage(
            $t(`${INTL_PREFIX}.toastMessage`, {
                destination: $t(`common.queueName.${destination}`),
            })
        );
    };

    const getEscalationTypeOptions = () => {
        const targetGroup = reviewEscalationGroups?.find(
            group => group.targetGroupId === selectedTargetGroupId
        );
        const escalationTypes = targetGroup?.targets.filter(t => t?.showInUI);
        const escalationTypeSorted = escalationTypes?.sort((a, b) => {
            const nameA = a?.escalationType ?? '';
            const nameB = b?.escalationType ?? '';
            return nameA.localeCompare(nameB);
        });
        return (
            escalationTypeSorted?.map(option => ({
                label: option?.escalationType ?? '',
                value: (option?.movedToTargetId ?? 0).toString(),
            })) || []
        );
    };

    const handleTargetGroupChange = (targetGroupId: number | null) => {
        setSelectedTargetGroupId(targetGroupId);
        if (targetGroupId == 3) {
            setSelectedMoveTargetId(3);
            setDestinationQueue(INITIAL_QUEUE_ID);
            setSuccessMessage(
                $t(`${INTL_PREFIX}.toastMessage`, {
                    destination: $t(`common.queueName.${INITIAL_QUEUE_ID}`),
                })
            );
        } else {
            setSelectedMoveTargetId(null);
        }
    };

    const handleEscalationTypeChange = (movedToTargetId: number | null) => {
        setSelectedMoveTargetId(movedToTargetId);
        setDestinationQueue(ESCALATION_QUEUE_ID);
        setSuccessMessage(
            $t(`${INTL_PREFIX}.toastMessage`, {
                destination:
                    reviewEscalationGroups
                        ?.filter(
                            group =>
                                group.targetGroupId === selectedTargetGroupId
                        )
                        .pop()?.displayName ?? '',
            })
        );
    };

    const clearForm = () => {
        setNote('');
        setSelectedMoveTargetId(null);
        setSelectedTargetGroupId(null);
        setDestinationQueue('');
    };

    const getDefaultQueueMoveOptions = () => {
        const options = [];
        if (currentQueueName !== INITIAL_QUEUE_ID)
            options.push({
                label: $t(`common.queueName.${INITIAL_QUEUE_ID}`),
                value: INITIAL_QUEUE_ID,
            });
        if (currentQueueName !== UNDER_INVESTIGATION_QUEUE_ID)
            options.push({
                label: $t(`common.queueName.${UNDER_INVESTIGATION_QUEUE_ID}`),
                value: UNDER_INVESTIGATION_QUEUE_ID,
            });
        options.push({
            label: $t(`common.queueName.${ESCALATION_QUEUE_ID}`),
            value: ESCALATION_QUEUE_ID,
        });
        return options;
    };

    const getTargetGroupOptions = () => {
        const options: { value: string; label: string }[] = [];
        if (reviewEscalationGroups) {
            reviewEscalationGroups.forEach(group => {
                let showGroup = false;
                group.targets.forEach(target => {
                    // target group is not current target group and is visible in UI
                    if (
                        target?.showInUI &&
                        target?.targetGroupId.toString() !==
                            productTargetGroup?.id
                    )
                        showGroup = true;
                    // Assigned reviewer should not show if product is not in escalation queue
                    if (
                        target?.escalationType === 'Assigned Reviewer' &&
                        !productTargetGroup
                    )
                        showGroup = false;
                });
                if (showGroup)
                    options.push({
                        value: group.targetGroupId.toString(),
                        label: group.displayName,
                    });
            });
        }
        return options;
    };

    const handleMissingFields = () => {
        const missingFields: string[] = [];
        if (currentQueueName !== ESCALATION_QUEUE_ID && !destinationQueue) {
            missingFields.push('Destination Queue');
        }
        if (
            (currentQueueName === ESCALATION_QUEUE_ID ||
                destinationQueue === ESCALATION_QUEUE_ID) &&
            !selectedTargetGroupId
        ) {
            missingFields.push('Escalation Type');
        }
        if (!note) {
            missingFields.push('Note');
        }
        if (missingFields.length)
            toast(
                $t(`${INTL_PREFIX}.missingFields`, {
                    fields: missingFields.join(', '),
                }),
                {
                    variant: 'danger',
                }
            );
        return missingFields.length > 0;
    };

    const handleMoveConfirm = () => {
        if (!handleMissingFields()) {
            onQueueMove(destinationQueue, undefined, note);
            toast(successMessage);
            clearForm();
            closeModal();
        }
    };

    const handleEscalationConfirm = () => {
        if (selectedTargetGroupId && selectedMoveTargetId && note) {
            onQueueMove(destinationQueue, selectedMoveTargetId, note);
            toast(successMessage);
            clearForm();
            closeModal();
            return;
        } else {
            handleMissingFields();
        }
    };
    return (
        <Sidecar
            className={CLASS_NAME}
            isOpen={isOpen}
            onRequestClose={closeModal}
            title={$t(`${INTL_PREFIX}.title`)}
            onConfirm={
                showEscalationFormGroup
                    ? handleEscalationConfirm
                    : handleMoveConfirm
            }
            testId={CLASS_NAME}
            cancelTitle={$t(`${INTL_PREFIX}.cancel`)}
        >
            <Form
                className={`${CLASS_NAME}-Form`}
                data-testid={`${CLASS_NAME}-Form`}
                style={{ width: '95%' }}
            >
                {showDefaultFormGroup && (
                    <Form.Group
                        controlId="default"
                        data-testid="form-group-move"
                    >
                        <Form.Label>{$t(`${INTL_PREFIX}.prompt`)}</Form.Label>
                        <Select
                            testId="form-control-move"
                            options={getDefaultQueueMoveOptions()}
                            onChange={option =>
                                handleDestinationQueueChange(
                                    option?.value as QueueNameIdentifier
                                )
                            }
                            onSelect={() =>
                                trackContentReviewEventMerged(
                                    'Click',
                                    'Where would you like to send this product to?',
                                    null,
                                    product,
                                    null,
                                    product?.isRevision
                                )
                            }
                            selectedValue={destinationQueue}
                            placeholder={$t('common.select')}
                        />
                    </Form.Group>
                )}
                {showEscalationFormGroup && (
                    <Form.Group
                        controlId="targetGroup"
                        data-testid="form-group-target-group"
                    >
                        <Form.Label>
                            {$t(`${INTL_PREFIX}.escalationPrompt`)}
                        </Form.Label>
                        <Select
                            testId="form-control-target-group"
                            options={getTargetGroupOptions()}
                            onChange={option => {
                                handleTargetGroupChange(
                                    option ? parseInt(option.value) : null
                                );
                            }}
                            onSelect={() =>
                                trackContentReviewEventMerged(
                                    'Click',
                                    'Who would you like to send this product to?',
                                    null,
                                    product,
                                    null,
                                    product?.isRevision
                                )
                            }
                            selectedValue={selectedTargetGroupId?.toString()}
                            placeholder={$t('common.select')}
                        />
                    </Form.Group>
                )}
                {Boolean(showEscalationFormGroup && selectedTargetGroupId) && (
                    <Form.Group
                        controlId="escalationType"
                        data-testid="form-group-escalation-type"
                    >
                        <Form.Label>
                            {$t(`${INTL_PREFIX}.escalationTypePrompt`)}
                        </Form.Label>
                        <Select
                            testId="form-control-escalation-type"
                            options={getEscalationTypeOptions()}
                            onChange={option => {
                                handleEscalationTypeChange(
                                    option ? parseInt(option.value) : null
                                );
                            }}
                            onSelect={() =>
                                trackContentReviewEventMerged(
                                    'Click',
                                    'Escalation Type',
                                    null,
                                    product,
                                    null,
                                    product?.isRevision
                                )
                            }
                            selectedValue={selectedMoveTargetId?.toString()}
                            placeholder={$t('common.select')}
                        />
                        <p className={`${CLASS_NAME}-type-definitions`}>
                            {$tx(`${INTL_PREFIX}.typeDefinitions`, {
                                link: ({ children }) => (
                                    <a
                                        className={`${CLASS_NAME}-type-definitions-link`}
                                        href={ESCALATION_TYPE_DEFINITIONS_LINK}
                                        target="_blank"
                                        rel="noreferrer"
                                    >
                                        {children}
                                    </a>
                                ),
                            })}
                        </p>
                    </Form.Group>
                )}
                <Form.Group controlId="note" data-testid="form-group-note">
                    <Form.Label>{$t('common.note')}</Form.Label>
                    <Form.Control
                        as="textarea"
                        data-testid="form-control-note"
                        rows={12}
                        value={note}
                        placeholder={$t(`${INTL_PREFIX}.notePlaceholder`)}
                        onChange={e => setNote(e.currentTarget.value)}
                    />
                </Form.Group>
            </Form>
        </Sidecar>
    );
};

export default ProductModalQueueMoveSidecar;
