import React from 'react';
import { formatMessage } from '@theorchard/suite-frontend';
import { upperFirst } from 'lodash';
import { TrackValidationWarningCode } from 'src/constants';
import {
    isPotentialAudioInfringementVal,
    isRevisionWithTrackOSRWarning,
} from 'src/utils/product';
import PotentialAudioInfringement from '../components/potentialAudioInfringement/potentialAudioInfringement';
import TrackOSRValidation from '../components/trackOSRValidation/trackOSRValidation';
import type { MergedProduct } from 'src/product/product';
import type { TrackMetadata } from 'src/product/track';
import type {
    CrossAccountOsrConflictValidationMatches,
    Validation,
    ValidationExtra,
} from 'src/types';

export const INTL_PREFIX = 'contentReview.productValidation';

const formatAccountBlocklistReason = () =>
    $tx('common.productValidations.codes.ACCOUNT_BLOCKLIST_BODY', {
        // Disabling react/jsx-no-target-blank for mailto links as they don't pose a security risk
        /* eslint-disable react/jsx-no-target-blank */
        qcEmailLink: ({ children }) => (
            <a target="_blank" href="mailto:qc@theorchard.com">
                {children}
            </a>
        ),
        operationsEmailLink: ({ children }) => (
            <a target="_blank" href="mailto:operations@theorchard.com">
                {children}
            </a>
        ),
        contractAdminEmailLink: ({ children }) => (
            <a target="_blank" href="mailto:contractadmin@theorchard.com">
                {children}
            </a>
        ),
        /* eslint-disable react/jsx-no-target-blank */
    });

const formatBlocklistReason = (item: string) => {
    const parsed = JSON.parse(item) as {
        word: string;
        reason: string;
        matched_field: string;
    };

    const intlParsedReason = formatMessage(
        'common.productValidations.parsedReason',
        {
            word: parsed.word,
            reason: parsed.reason,
            intlFields: formatMessage(
                `common.fieldNames.${parsed.matched_field}`
            ),
        }
    );

    return intlParsedReason;
};

const formatTrackOSRValidationReason = (item: string, code: string) => {
    const { matches } = JSON.parse(
        item
    ) as CrossAccountOsrConflictValidationMatches;
    return <TrackOSRValidation matches={matches} code={code} />;
};

const formatPotentialAudioInfringementReason = (
    item: string,
    extra?: ValidationExtra
) => {
    const input = JSON.parse(item);
    const { potentialAudioInfringement, crossAccountOSRConflict } = input;
    const potentailAudioInfringementMatches =
        potentialAudioInfringement &&
        Array.isArray(potentialAudioInfringement.matches)
            ? potentialAudioInfringement.matches
            : [];
    const crossAccountOSRConflictMatches =
        crossAccountOSRConflict &&
        Array.isArray(crossAccountOSRConflict.matches)
            ? crossAccountOSRConflict.matches
            : [];

    return (
        <PotentialAudioInfringement
            potentialAudioInfringementMatches={
                potentailAudioInfringementMatches
            }
            crossAccountOSRConflictMatches={crossAccountOSRConflictMatches}
            validationExtra={extra}
        />
    );
};

const formatAwalArtistApplicationMismatchReason = (item: string) => {
    const parsed = JSON.parse(item) as {
        awal_application_artist: string;
    };

    const intlReason = formatMessage(
        'common.productValidations.codes.AWAL_ARTIST_APPLICATION_MISMATCH_BODY',
        {
            artistName: parsed.awal_application_artist,
        }
    );

    return intlReason;
};

const formatSpotifyWatchlistArtistReason = (reason: string) =>
    $tx('common.productValidations.codes.SPOTIFY_WATCHLIST_ARTIST_BODY', {
        artistNames: reason,
        lineBreak: () => <br />,
        bullet: () => <>• </>,
        bold: ({ children }) => <strong>{children}</strong>,
    });

const formatMissingComposer = (item: string) => {
    const parsed = JSON.parse(item) as {
        genre: string;
        subgenre: string;
    };
    const { genre, subgenre } = parsed;

    return formatMessage(
        'common.productValidations.codes.MISSING_COMPOSER_BODY',
        {
            genre: upperFirst(genre),
            subgenre,
        }
    );
};

interface GqlValidationReason {
    reason: string;
    code: string;
    extra?: ValidationExtra;
}

export const formatValidationMessage = (
    { code, reason, extra }: GqlValidationReason,
    isMissingComposerMsgUpdate?: boolean
) => {
    if (code === 'ACCOUNT_BLOCKLIST') {
        return formatAccountBlocklistReason();
    }

    if (code === 'BLOCKLIST') {
        return formatBlocklistReason(reason);
    }

    if (code === 'POTENTIAL_AUDIO_INFRINGEMENT')
        return formatPotentialAudioInfringementReason(reason, extra);

    if (
        code === 'CROSS_ACCOUNT_OSR_CONFLICT' ||
        code === 'CROSS_ISRC_OSR_MISMATCH' ||
        code === 'CROSS_TRACK_ISRC_MISMATCH'
    ) {
        return formatTrackOSRValidationReason(reason, code);
    }

    if (code === TrackValidationWarningCode.SPOTIFY_WATCHLIST_ARTIST) {
        return formatSpotifyWatchlistArtistReason(reason);
    }

    if (code === 'AWAL_ARTIST_APPLICATION_MISMATCH') {
        return formatAwalArtistApplicationMismatchReason(reason);
    }

    if (code === 'MISSING_COMPOSER') {
        if (isMissingComposerMsgUpdate) {
            return formatMissingComposer(reason);
        }
        return formatMessage(
            'common.productValidations.codes.COMPOSER_REQUIRED_BODY'
        );
    }

    return formatMessage(`common.productValidations.codes.${code}_BODY`);
};

export const filterValidations = (
    validations: Validation[],
    tuid: number,
    trackName: TrackMetadata['trackName'],
    contributors: TrackMetadata['contributors'],
    product: MergedProduct
) => {
    let audioInfringement: {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        potentialAudioInfringement?: any;
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        crossAccountOSRConflict?: any;
    } = {};
    const filteredValidations = validations.filter(val => {
        if (isRevisionWithTrackOSRWarning(null, product?.isRevision, val.code))
            return false;

        if (isPotentialAudioInfringementVal(val.code)) {
            audioInfringement = {
                ...audioInfringement,
                ...(val.code === 'POTENTIAL_AUDIO_INFRINGEMENT'
                    ? { potentialAudioInfringement: JSON.parse(val.reason) }
                    : { crossAccountOSRConflict: JSON.parse(val.reason) }),
            };
            return false;
        }
        return true;
    });
    if (Object.keys(audioInfringement).length) {
        filteredValidations.push({
            code: 'POTENTIAL_AUDIO_INFRINGEMENT',
            severity: 'warn',
            reason: JSON.stringify(audioInfringement),
            target: `${tuid}-field:${filteredValidations.length}`,
            targetId: tuid,
            extra: {
                trackName: trackName.get(),
                label: product.label.name.get(),
                imprint: product.basics.imprint.get(),
                artists: contributors.primaryArtists.get() as string[],
            } as ValidationExtra,
            type: 'track',
        });
    }
    return filteredValidations;
};
