import React, { useEffect, useState } from 'react';
import { Form, Section, Select } from '@theorchard/suite-components';
import { GlyphIcon } from '@theorchard/suite-icons';
import { entries, uniq, values } from 'lodash';
import { MIXED_REASON } from './constants';
import IndividualTrackForm from './IndividualTrackForm';
import type { TrackLevelForm } from './types';
import type { TrackMetadata } from 'src/product/track';

interface TrackLevelApprovalFormProps {
    formState: TrackLevelForm;
    approvalReasons: Record<string, string>;
    infringedTracks: TrackMetadata[];
    updateForm: (formPatch: Partial<TrackLevelForm>) => void;
    withTitle?: boolean;
}

const CLASS_NAME = 'TrackLevelForm';
const INTL_PREFIX = 'contentReview.productModalApprovalSidecarV2';
const TEST_PREFIX = 'track-approval-form';

const TrackLevelApprovalForm = ({
    formState,
    approvalReasons,
    infringedTracks,
    updateForm,
    withTitle,
}: TrackLevelApprovalFormProps) => {
    const { approvalReason, tracksApprovalReasons } = formState;

    const [isTracksOpen, setIsTracksOpen] = useState(false);

    const approvalReasonOptions =
        entries(approvalReasons)?.map(([cannedResponseId, keyword]) => ({
            value: cannedResponseId,
            label: keyword,
        })) ?? [];

    const tracksGlyphIcon = isTracksOpen
        ? 'doubleChevronUp'
        : 'doubleChevronDown';

    // When all tracks reasons are same - update the main reason to that reason
    useEffect(() => {
        const trackReasons = uniq(values(tracksApprovalReasons));
        const reasonsList = trackReasons.filter(Boolean);

        if (reasonsList.length === 0) return;

        // If all tracks share the same reason - also set as main reason
        if (reasonsList.length === 1) {
            const [unifiedReason] = reasonsList;
            const isMixedReason = unifiedReason === MIXED_REASON;

            if (!isMixedReason && approvalReason !== unifiedReason)
                updateForm({
                    approvalReason: unifiedReason,
                    approvalReasonNote: approvalReasons[unifiedReason] ?? '',
                });

            return;
        }

        // If tracks have different reasons - set main reason to "Mixed"
        if (approvalReason !== MIXED_REASON)
            updateForm({
                approvalReason: MIXED_REASON,
                approvalReasonNote: MIXED_REASON,
            });

        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [tracksApprovalReasons, approvalReason]);

    const handleReasonChange = (
        cannedResponseId: string = '',
        cannedResponseNote: string = ''
    ) => {
        const tracksApprovalReasons = infringedTracks.reduce(
            (acc, track) => ({
                ...acc,
                [track.tuid]: cannedResponseId,
            }),
            {}
        );

        updateForm({
            approvalReason: cannedResponseId,
            approvalReasonNote: cannedResponseNote,
            tracksApprovalReasons,
        });
    };

    const handleIndividualReasonChange = (
        tuid: string,
        cannedResponseId: string
    ) =>
        updateForm({
            tracksApprovalReasons: {
                ...formState.tracksApprovalReasons,
                [tuid]: cannedResponseId,
            },
        });

    return (
        <div className={CLASS_NAME}>
            {withTitle && (
                <div>
                    <Section.Divider className={`${CLASS_NAME}-divider`} />
                    <h4>{$t(`${INTL_PREFIX}.trackLevelValidation`)}</h4>
                </div>
            )}

            <Form.Group className={`${CLASS_NAME}-group`}>
                <Form.Label>
                    {$t(`${INTL_PREFIX}.potentialAudioInfringement`)}
                </Form.Label>

                <Select
                    testId={`${TEST_PREFIX}-reason`}
                    options={approvalReasonOptions}
                    placeholder={$t(`${INTL_PREFIX}.selectApprovalReason`)}
                    selectedValue={formState.approvalReason ?? ''}
                    onChange={option =>
                        handleReasonChange(option?.value, option?.label)
                    }
                />

                {formState.approvalReason.length > 0 && (
                    <div className={`${CLASS_NAME}-reason-notice`}>
                        {$t(`${INTL_PREFIX}.selectApprovalReasonNotice`)}
                    </div>
                )}
            </Form.Group>

            <div className={`${CLASS_NAME}-tracks`}>
                <div
                    role="button"
                    tabIndex={0}
                    data-testid="open-tracks-header"
                    className={`${CLASS_NAME}-tracks-header`}
                    onClick={() => setIsTracksOpen(isOpened => !isOpened)}
                >
                    <Form.Label>
                        {$t(`${INTL_PREFIX}.seeTracksIndividually`)}
                    </Form.Label>

                    <GlyphIcon name={tracksGlyphIcon} size={12} />
                </div>

                {isTracksOpen && (
                    <div className={`${CLASS_NAME}-tracks-form`}>
                        {infringedTracks.map(track => (
                            <IndividualTrackForm
                                key={track.tuid}
                                track={track}
                                reasonOptions={approvalReasonOptions}
                                onReasonChange={handleIndividualReasonChange}
                                selectedReason={
                                    formState.tracksApprovalReasons[track.tuid]
                                }
                            />
                        ))}
                    </div>
                )}
            </div>

            <Form.Group className={`${CLASS_NAME}-group`}>
                <Form.Label>{$t('common.additionalNotes')}</Form.Label>
                <Form.Control
                    data-testid={`${TEST_PREFIX}-note`}
                    className={`${CLASS_NAME}-note`}
                    as="textarea"
                    rows={3}
                    value={formState.approvalNote}
                    placeholder={$t(`${INTL_PREFIX}.notesPlaceholder`)}
                    onChange={({ currentTarget }) =>
                        updateForm({ approvalNote: currentTarget.value })
                    }
                />
            </Form.Group>
        </div>
    );
};

export default TrackLevelApprovalForm;
