import type { FC } from 'react';
import React from 'react';
import {
    ExpandableContent,
    Sidebar,
    Stepper,
} from '@theorchard/suite-components';
import moment from 'moment';
import {
    APPROVAL,
    ESCALATION_QUEUE_ID,
    INITIAL_QUEUE_ID,
    QUEUEMOVE,
    RE_SUBMISSION,
    REJECTION,
    SUBMISSION,
    UNDER_INVESTIGATION_QUEUE_ID,
} from 'src/constants';
import { trackContentReviewEvent } from 'src/utils/product';
import type { Step } from '@theorchard/suite-components';
import type { Product } from 'src/data/queries/product/types';
import { useSpotifyWatchlistArtistFF } from 'src/utils/features';

export const CLASS_NAME = 'ProductReviewHistorySidebar';
const INTL_PREFIX = 'contentReview.productReviewHistorySidebar';

export interface Props {
    product: Product;
    isOpen: boolean;
    closeModal: () => void;
    sidebarRef: Element | null | undefined;
    isRevisedProduct: boolean;
}

const ProductReviewHistorySidebar: FC<Props> = ({
    product,
    isOpen,
    closeModal,
    sidebarRef,
    isRevisedProduct,
}) => {
    const isSpotifyWatchlistArtistEnabled = useSpotifyWatchlistArtistFF();

    const getMoveTitle = (destinationQueueName: string) => {
        switch (destinationQueueName) {
            case INITIAL_QUEUE_ID:
                return $t(`${INTL_PREFIX}.moveTitle`, { queue: 'Review' });
            case UNDER_INVESTIGATION_QUEUE_ID:
                return $t(`${INTL_PREFIX}.moveTitle`, {
                    queue: 'Under Investigation',
                });
            case ESCALATION_QUEUE_ID:
                return $t(`${INTL_PREFIX}.moveTitle`, { queue: 'Escalation' });
        }
    };

    const getRejectionNoteBody = (notes: string) => {
        const parsedNotes = notes
            .replace(/\n{3}/g, '\n\n')
            .replace(/\]/g, ']\n');
        return getNoteBody(parsedNotes, REJECTION);
    };

    const formatNote = (note?: string) => {
        if (!note) return null;

        const lines = note
            .split('\n')
            .map(l => l.trim())
            .filter(Boolean);

        if (lines.length === 0) return null;

        const isTitle = (line: string) =>
            line.startsWith('[') && line.endsWith(']');

        return (
            <>
                {lines.map((line, i) => {
                    if (isTitle(line)) {
                        return (
                            <div key={i} className="note-title">
                                {line.slice(1, -1)}
                            </div>
                        );
                    }

                    return (
                        <div key={i} className="note-line">
                            {line}
                        </div>
                    );
                })}
            </>
        );
    };

    const getNoteBody = (
        note: string | null,
        timelineEvent: string,
        props?: object | null
    ) =>
        note ? (
            <ExpandableContent
                expandLabel={$t(`${INTL_PREFIX}.notesToggle`)}
                className="mt-3"
                onClick={(isExpanded: boolean) => {
                    const noteLabel =
                        timelineEvent.charAt(0).toUpperCase() +
                        timelineEvent.slice(1);
                    const label = isExpanded
                        ? `See ${noteLabel} Notes`
                        : `Close ${noteLabel} Notes`;
                    trackContentReviewEvent(
                        'Click',
                        label,
                        { ...props },
                        product,
                        null,
                        isRevisedProduct
                    );
                }}
            >
                <div className="note-body">
                    {isSpotifyWatchlistArtistEnabled ? (
                        formatNote(note)
                    ) : (
                        <>{note}</>
                    )}
                </div>
            </ExpandableContent>
        ) : null;

    const getDescription = (timestamp: string, escalationType = '') => {
        return (
            <>
                <div className="desc-0">{timestamp}</div>
                {escalationType && (
                    <div className="desc-1">
                        {$t('common.fieldNames.escalationType') +
                            ': ' +
                            escalationType}
                    </div>
                )}
            </>
        );
    };

    const steps = product.reviewHistory.items.map(item => {
        const date = moment(item.createdDatetime).format('DD MMM yyyy');
        const name = item.userInfo?.name;
        const timestamp = `${date} ${name ? 'by ' + name : ''}`;

        switch (item.userAction) {
            case SUBMISSION:
                return {
                    icon: {
                        variant: 'info',
                        glyphIcon: 'arrowUp',
                    },
                    title:
                        item.submissionType == RE_SUBMISSION
                            ? $t(`${INTL_PREFIX}.resubmissionTitle`)
                            : $t(`${INTL_PREFIX}.submissionTitle`),
                    description: getDescription(timestamp),
                };
            case QUEUEMOVE:
                return {
                    icon: {
                        variant: 'warning',
                        glyphIcon: 'arrowRight',
                    },
                    title: getMoveTitle(item.destinationQueueName as string),
                    description: getDescription(
                        timestamp,
                        item.escalationType ?? ''
                    ),
                    body: getNoteBody(item.note, 'Move', {
                        queueName: item.destinationQueueName,
                    }),
                };
            case APPROVAL:
                return {
                    icon: {
                        variant: 'success',
                        glyphIcon: 'check',
                    },
                    title: $t(`${INTL_PREFIX}.approvalTitle`),
                    description: getDescription(timestamp),
                    body: getNoteBody(item.note, APPROVAL),
                };
            case REJECTION:
                return {
                    icon: {
                        variant: 'danger',
                        glyphIcon: 'close',
                    },
                    title: $t(`${INTL_PREFIX}.rejectionTitle`),
                    description: getDescription(timestamp),
                    body: getRejectionNoteBody(item.note ?? ''),
                };
        }
    });
    return (
        <div>
            <Sidebar
                className={CLASS_NAME}
                title={$t(`${INTL_PREFIX}.title`)}
                isOpen={isOpen}
                onRequestClose={closeModal}
                portalElement={sidebarRef}
                testId={CLASS_NAME}
            >
                <Stepper layout="vertical" steps={steps as Step[]} />
            </Sidebar>
        </div>
    );
};

export default ProductReviewHistorySidebar;
