import React, {
    type ChangeEventHandler,
    useContext,
    useEffect,
    useState,
} from 'react';
import { Col, Container, Label, Row } from '@theorchard/suite-components';
import { isEmpty } from 'lodash-es';
import { useParams } from 'react-router-dom';
import { useContractAttachments } from 'src/apollo/queries/contract';
import TrackSearchableSelect from 'src/components/shared/track-searchable-select';
import {
    SET_DEFAULT_CONDITION,
    SET_CONTRACT_TERM_ATTACHMENTS,
    CONTRACT_TERM_TYPES,
    SET_ERRORS,
    TRACKS_ALREADY_ATTACHED_TO_CONTRACT_ERROR,
} from 'src/constants';
import { ContractTermContext } from 'src/contexts/contract-term-context';
import { ContractTermConditionsList } from './contract-term-conditions-list';
import type { AbacusContractAttachmentsAccount } from 'src/types/abacus-account';

export default function TrackExceptionForm() {
    let labelAttachmentIds;
    const { contractId, contractTermId } = useParams<{
        contractId: string;
        contractTermId: string;
    }>();
    const { state, dispatch } = useContext(ContractTermContext);
    const { data: contract, loading } = useContractAttachments(contractId);
    const [labelIds, setLabelIds] = useState<number[] | undefined>([]);
    const [accountData, setAccountData] = useState(
        {} as AbacusContractAttachmentsAccount
    );
    const [existingIsrcs, setExistingIsrcs] = useState<
        string[] | null | undefined
    >([]);
    const [selectedTrackExceptionIsrcs, setSelectedTrackExceptionIsrcs] =
        useState<string[] | null | undefined>([]);
    const setErrors = (attachmentsValidError: string[]) =>
        dispatch({ type: SET_ERRORS, attachmentsValidError, error: [] });

    const formChangeHandler: ChangeEventHandler<HTMLInputElement> = e => {
        const {
            target: { value },
        } = e;
        const attachments = value || [];
        dispatch({ type: SET_CONTRACT_TERM_ATTACHMENTS, attachments });
    };

    useEffect(() => {
        if (state.attachments.length > 0 && state.conditions.length === 0)
            dispatch({ type: SET_DEFAULT_CONDITION });
    }, [state.attachments]);

    useEffect(() => {
        if (contract && contract.abacusContract) {
            const { account, contractTerms } = contract.abacusContract;
            setAccountData(account);
            if (!isEmpty(contractTerms)) {
                const labelTerms = contractTerms?.filter(
                    el => el.termType === CONTRACT_TERM_TYPES.LABEL
                );
                if (isEmpty(labelTerms)) {
                    const baseTerms = contractTerms?.filter(
                        term => term.isBaseTerm
                    );
                    labelAttachmentIds =
                        baseTerms?.[0]?.attachmentsRelations?.labelIds?.map(
                            attachmentId => parseInt(attachmentId, 10)
                        );
                } else
                    labelAttachmentIds = labelTerms?.[0].attachments?.map(
                        attachmentId => parseInt(attachmentId, 10)
                    );

                setLabelIds(labelAttachmentIds);
                const allTracksAttachments = [...(existingIsrcs ?? [])];
                const tracksTerms = contractTerms?.filter(
                    term =>
                        term.termType === CONTRACT_TERM_TYPES.TRACK &&
                        term.contractTermId !== contractTermId
                );
                const selectedTrackTerm = contractTerms?.filter(
                    term =>
                        term.termType === CONTRACT_TERM_TYPES.TRACK &&
                        term.contractTermId === contractTermId
                );
                if (!isEmpty(selectedTrackTerm))
                    setSelectedTrackExceptionIsrcs(
                        selectedTrackTerm?.[0]?.attachments
                    );
                tracksTerms?.forEach(trackTerm => {
                    allTracksAttachments.push(
                        ...(trackTerm?.attachments ?? [])
                    );
                });
                setExistingIsrcs(allTracksAttachments);
            }
        }
    }, [contract]);

    useEffect(() => {
        const conflictAttachments = existingIsrcs?.filter(isrc =>
            state.attachments.includes(isrc)
        );
        if (!isEmpty(conflictAttachments))
            setErrors([
                `${TRACKS_ALREADY_ATTACHED_TO_CONTRACT_ERROR} (${conflictAttachments?.join(
                    ', '
                )})`,
            ]);
    }, [state.attachments, state.conditions]);

    return (
        <div className="ContractTrackExceptionForm-block">
            <h2>Track Exception</h2>
            <Container>
                <Row className="BaseRateHorizontalRow">
                    <Col sm={2}>
                        <Label text="Track(s)" />
                    </Col>
                    <Col sm={5}>
                        {!loading && (
                            <TrackSearchableSelect
                                accountId={
                                    accountData ? accountData.accountId : ''
                                }
                                contractTermId={contractTermId}
                                onChange={formChangeHandler}
                                selectedTrackExceptionIsrcs={
                                    selectedTrackExceptionIsrcs
                                }
                                tracksIsrcs={state.attachments}
                                labelIds={labelIds}
                                setErrors={setErrors}
                            />
                        )}
                    </Col>
                </Row>
                {(state.attachments.length > 0 ||
                    state.conditions.length > 0) && (
                    <ContractTermConditionsList />
                )}
            </Container>
        </div>
    );
}
