import type { FC } from 'react';
import React from 'react';
import { Alert, Pill } from '@theorchard/suite-components';
import { formatMessage } from '@theorchard/suite-frontend';
import cx from 'classnames';
import { values } from 'lodash';
import { EMPTY_CHAR } from 'src/constants';
import {
    isRevisionWithTrackOSRWarning,
    getValidationCodesToIgnore,
} from 'src/utils/product';
import type { CellProps } from '@theorchard/suite-components/dist/esm/src/components/table/base/types';
import type {
    ReviewQueueSearchItem,
    ReviewQueueSearchItemNotices,
} from 'src/data/queries/reviewQueueSearch/types';

type NoticeByCode = ReviewQueueSearchItemNotices[number] & {
    count: number;
};

const CLASS_NAME = 'ReviewQueueNotice';
const CLASS_NAME_ALERT = `${CLASS_NAME}-alert`;
const CLASS_NAME_COUNT = `${CLASS_NAME_ALERT}-count`;

const formatNoticeAlert = (notice: NoticeByCode, index: number) => {
    const variant = notice.level === 'errors' ? 'error' : 'warn';
    const alertContent = (
        <div className={CLASS_NAME_ALERT}>
            <div className={`${CLASS_NAME_ALERT}-title`}>
                <strong>
                    {formatMessage(
                        `common.productValidations.codes.${notice.code}_TITLE`
                    )}
                </strong>
            </div>
            <div
                className={cx(
                    CLASS_NAME_COUNT,
                    `${CLASS_NAME_COUNT}-${variant}`
                )}
            >
                {notice.count}
            </div>
        </div>
    );

    return (
        <Alert
            key={`${notice.code}-${index}`}
            variant={variant}
            text={alertContent}
        />
    );
};

const NoticesCell: FC<CellProps<ReviewQueueSearchItem>> = ({ data }) => {
    const { notices, productId, submissionType } = data;
    const validationCodes = notices?.map(notice => notice.code) || [];
    const filteredNotices =
        notices?.filter(notice =>
            Boolean(
                !(
                    getValidationCodesToIgnore(validationCodes).includes(
                        notice.code
                    ) ||
                    isRevisionWithTrackOSRWarning(
                        submissionType,
                        null,
                        notice.code
                    )
                )
            )
        ) ?? [];

    const levelClass = filteredNotices.find(notice => notice.level === 'errors')
        ? 'error'
        : 'warning';

    const groupedNotices = filteredNotices.reduce<Record<string, NoticeByCode>>(
        (noticeByCode, notice) => {
            const { code } = notice;

            noticeByCode[code] = {
                ...notice,
                count: (noticeByCode[code]?.count ?? 0) + 1,
            };

            return noticeByCode;
        },
        {}
    );

    return (
        <div data-testid="NoticeCell" className="NoticeCell">
            {filteredNotices.length ? (
                <Pill
                    testId={`product-${productId}-pill`}
                    iconName={levelClass}
                    indicator={levelClass}
                    variant={levelClass}
                    text={String(filteredNotices.length)}
                    popoverOptions={{
                        id: 'errorPopover',
                        content: (
                            <div className={CLASS_NAME}>
                                {values(groupedNotices).map(formatNoticeAlert)}
                            </div>
                        ),
                    }}
                />
            ) : (
                <span>{EMPTY_CHAR}</span>
            )}
        </div>
    );
};

export default NoticesCell;
