import { isEmpty, difference } from 'lodash-es';
import type { GetContractWithAttachmentsQuery } from 'src/apollo/queries/contract/__generated__/get-contract-attachments';
import type {
    ValidationError,
    ValidationErrorType,
} from 'src/types/validation';

type AbacusContract = NonNullable<
    GetContractWithAttachmentsQuery['abacusContract']
>;
export type ContractTerms =
    NonNullable<AbacusContract['contractTerms']> extends (infer T)[] ? T : null;

export const getContractTermAttachments = (
    contractTerms: ContractTerms[],
    contractTermId: string
) => {
    const result = contractTerms?.find(
        (term: ContractTerms) => term.contractTermId === contractTermId
    )?.attachments;
    return result ? result : [];
};

export const getOtherAttachmentsWithinContract = (
    contractTerms: ContractTerms[],
    contractTermId: string,
    termType: string
) => {
    return contractTerms.flatMap((term: ContractTerms) =>
        term.contractTermId !== contractTermId &&
        term.termType === termType &&
        term.attachments
            ? term.attachments
            : []
    );
};
export const getNewAttachmentsWithinContractAndTerm = (
    selectedAttachmentsWithinTerm: string[],
    originalAttachmentsWithinTerm: string[],
    otherAttachmentsWithinContract: string[]
) => {
    return difference(selectedAttachmentsWithinTerm, [
        ...originalAttachmentsWithinTerm,
        ...otherAttachmentsWithinContract,
    ]);
};

export const validateSelectedAttachmentsWithinContract = (
    selectedAttachmentsWithinTerm: string[],
    otherAttachmentsWithinContract: string[],
    errorType: ValidationErrorType,
    fieldName: string,
    errorMessage: string
) => {
    const errors: ValidationError[] = [];
    if (!isEmpty(selectedAttachmentsWithinTerm)) {
        const conflictingAttachments = selectedAttachmentsWithinTerm.filter(
            value => otherAttachmentsWithinContract.includes(value)
        );

        if (!isEmpty(conflictingAttachments)) {
            const message = `${errorMessage} ${conflictingAttachments.join(
                ', '
            )}`;
            errors.push({
                errorType: errorType,
                fieldName: fieldName,
                messageOverride: message,
            });
        }
    }
    return errors;
};

export const validateSelectedAttachmentsWithinAccount = (
    allAttachmentsWithinAccountExceptFromCurrentTerm: string[],
    newAttachmentsWithinContractAndTerm: string[],
    errorType: ValidationErrorType,
    fieldName: string,
    errorMessage: string
) => {
    const errors: ValidationError[] = [];

    const conflictingAttachments = newAttachmentsWithinContractAndTerm.filter(
        attachment =>
            allAttachmentsWithinAccountExceptFromCurrentTerm.includes(
                attachment
            )
    );

    if (!isEmpty(conflictingAttachments)) {
        const message = `${errorMessage} ${conflictingAttachments.join(', ')}`;
        errors.push({
            errorType: errorType,
            fieldName: fieldName,
            messageOverride: message,
        });
    }

    return errors;
};
