import type { FC } from 'react';
import React, { useCallback, useState } from 'react';
import {
    Alert,
    Card,
    GlyphButton,
    LoadingSpinner,
    UploadArea,
    Highlight,
} from '@theorchard/suite-components';
import { useIdentity } from '@theorchard/suite-frontend';
import { GlyphIcon } from '@theorchard/suite-icons';
import { validateCsvData } from 'src/components/isrcUpload/csvValidator';
import { useLazyOwnershipCherryPickUploadToken } from 'src/data/queries';
import { type OwnershipCherryPickUploadToken } from 'src/data/queries/nrOwnershipCherryPickUploadToken/__generated__/nrOwnershipCherryPickUploadToken';
import { uploadFileToS3 } from 'src/utils/aws';

const CLASSNAME = 'ISRCUpload';
const TRANSLATION_KEY = 'ownershipRights.isrcUpload';

export interface Props {
    disabled?: boolean;
    onChange: SetISRCListFileUUIDCallback;
}

export type SetISRCListFileUUIDCallback = (
    isrcListFileUUID: string | undefined
) => void;

/**
 * ISRC csv file upload box as seen here https://www.figma.com/design/vvtX6fjqvO0rtrmFes8Kia/OSR-Monitor---Deliver--2024-?node-id=92-40786&t=BvO9PYIKv1HcztOt-4
 *
 * This component also takes care of the upload process, validating the CSV file, and counting the rows
 * @param props
 * @constructor
 */
const ISRCUpload: FC<Props> = props => {
    const { onChange, disabled } = props;
    const { profileId, id, profileUUID } = useIdentity();

    const [isrcCount, setISRCCount] = useState<number>(0);
    const [isError, setError] = useState<boolean>(false);
    const [isS3Uploading, setIsS3Uploading] = useState<boolean>(false);
    const [startS3FileUpload, setStartS3FileUpload] = useState<boolean>(false);
    const [validFile, setValidFile] = useState<File>();
    const [showUpload, setShowUpload] = useState<boolean>(true);
    const [doGetOwnershipCherryPickUploadToken, { data: uploadToken }] =
        useLazyOwnershipCherryPickUploadToken({
            originalFilename: '',
        });

    const handleFileValidation = useCallback(
        async (file: File) => {
            try {
                const count = await validateCsvData(file);

                setISRCCount(count);

                await doGetOwnershipCherryPickUploadToken({
                    variables: {},
                });
                setValidFile(file);
            } catch (error) {
                setError(true);
                setIsS3Uploading(false);
                setStartS3FileUpload(false);
                setShowUpload(true);
                console.error('Error validating CSV file:', error);
            }
        },
        [
            setValidFile,
            setISRCCount,
            setShowUpload,
            setIsS3Uploading,
            setStartS3FileUpload,
            setError,
            doGetOwnershipCherryPickUploadToken,
        ]
    );

    const removeUploadedFile = (event: React.MouseEvent) => {
        event.stopPropagation(); // prevent this button from opening the file upload dialog

        setValidFile(undefined);
        setISRCCount(0);
        setShowUpload(true);
        onChange(undefined);
    };

    const onStartUpload = async (acceptedFiles: File[]) => {
        setError(false);
        setShowUpload(false);
        setStartS3FileUpload(true);

        void handleFileValidation(acceptedFiles[0]);
    };

    if (!isS3Uploading && validFile && uploadToken && startS3FileUpload) {
        setIsS3Uploading(true);

        const thenCallback = () => {
            // extract just the UUID from the generated filename - this is what we will need to create the order
            const match =
                uploadToken.nrOwnershipCherryPickUploadToken.filename.match(
                    /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/
                );

            if (match) {
                onChange(match[1]);
            }
        };

        const catchCallback = (error: Error) => {
            console.error('Error uploading file:', error);
            setError(true);
        };

        const finallyCallback = () => {
            setStartS3FileUpload(false);
            setIsS3Uploading(false);
        };

        const token: OwnershipCherryPickUploadToken['nrOwnershipCherryPickUploadToken'] =
            uploadToken.nrOwnershipCherryPickUploadToken;

        const fileExtension = validFile.name?.split('.').pop();
        const key = `${token.filename}.${fileExtension}`;
        const filename = `${validFile.name}`;
        void uploadFileToS3(validFile, token.bucket, key, token.credentials, {
            filename,
            profileId: `${profileId}`,
            identityId: `${id}`,
            profileUUID: `${profileUUID}`,
        })
            .catch(catchCallback)
            .then(thenCallback)
            .finally(finallyCallback);
    }

    return (
        <div className={`${CLASSNAME}-container`}>
            {isError && (
                <Alert variant="error" text={$t(`${TRANSLATION_KEY}.error`)} />
            )}
            {!isError && isrcCount > 0 && validFile && !isS3Uploading && (
                <Card suite className={'upload-summary'} layout={'horizontal'}>
                    <Card.Body>
                        <strong>
                            {$t(`${TRANSLATION_KEY}.isrcCount`)}&nbsp;
                        </strong>
                        <Highlight variant={'success'}>{isrcCount}</Highlight>
                    </Card.Body>

                    <GlyphButton
                        variant="tertiary"
                        size="lg"
                        name="trash"
                        tooltip="Remove"
                        onClick={event => removeUploadedFile(event)}
                    />
                </Card>
            )}
            {(showUpload || isS3Uploading || startS3FileUpload) && (
                <>
                    <p className="upload-instructions">
                        <span>
                            {$t(`${TRANSLATION_KEY}.uploadInstructions1`)}
                            &nbsp;
                        </span>
                        <a href="https://cdn.theorchard.io/assets/frontend-distribution/isrc-file-template.csv">
                            {$t(`${TRANSLATION_KEY}.uploadInstructionsLink`)}
                        </a>
                        <span>
                            &nbsp;
                            {$t(`${TRANSLATION_KEY}.uploadInstructions2`)}
                        </span>
                    </p>
                    <UploadArea
                        onUpload={onStartUpload}
                        disabled={disabled}
                        inputId={'isrcUpload'}
                        maxFiles={1}
                        multipleFileSelection={false}
                        accept={'text/csv'}
                        className={`${CLASSNAME}`}
                    >
                        {showUpload && (
                            <div className={'upload-prompt'}>
                                <GlyphIcon
                                    name={'upload'}
                                    size={16}
                                ></GlyphIcon>
                                <div className={'text'}>
                                    <h4 data-testid="uploadHeader">
                                        {$t(`${TRANSLATION_KEY}.uploadHeader`)}
                                    </h4>
                                    <small>
                                        {$t(`${TRANSLATION_KEY}.uploadSubtext`)}
                                    </small>
                                </div>
                            </div>
                        )}
                        {(isS3Uploading || startS3FileUpload) && (
                            <div className={'uploading'}>
                                <LoadingSpinner show size={48} />
                                <span>
                                    {$t(`${TRANSLATION_KEY}.uploading`)}
                                </span>
                            </div>
                        )}
                    </UploadArea>
                </>
            )}
        </div>
    );
};

export default ISRCUpload;
