import React, { useEffect, type FC } from 'react';
import {
    Button,
    Control,
    Field,
    Label,
    NumberInput,
    Section,
    Select,
} from '@theorchard/suite-components';
import { formatMessage } from '@theorchard/suite-frontend';
import { GlyphIcon } from '@theorchard/suite-icons';
import { IPI_LENGTH, PRO_LIST } from 'src/constants';
import { type UpdatePublishingSongWriterMetaDataInput } from 'src/data/schemaTypes';
import { pkaError } from 'src/utils/error';
import { isValidIpi } from 'src/utils/validators';
import { CLASSNAME } from '../../songWriterEditModal';
import { type AssociatedComposition } from '../../utils';

interface Props {
    updateSongWriter: UpdatePublishingSongWriterMetaDataInput;
    setUpdateSongWriter: React.Dispatch<
        React.SetStateAction<UpdatePublishingSongWriterMetaDataInput>
    >;
    setBaseModalErrors: React.Dispatch<React.SetStateAction<boolean>>;
    hasSubmitted: boolean;
    songWriterValidationErrorKeys?: string[];
    setSongWriterValidationErrorKeys: React.Dispatch<
        React.SetStateAction<string[] | undefined>
    >;
    controlledComps: AssociatedComposition[];
}

const SongWriterModalBasics: FC<Props> = ({
    updateSongWriter,
    setUpdateSongWriter,
    setBaseModalErrors,
    hasSubmitted,
    songWriterValidationErrorKeys,
    setSongWriterValidationErrorKeys,
    controlledComps,
}) => {
    const isControlled = !!controlledComps.length;
    const nameIsInvalid = !/\w \w/.exec(updateSongWriter.name);
    const pkaIsInvalid = updateSongWriter.professionallyKnownAs?.some(pkaError);
    const songWriterIpiIsInvalid =
        updateSongWriter.ipi && !isValidIpi(updateSongWriter.ipi);
    const songWriterIpiCollision = songWriterValidationErrorKeys?.includes(
        'songWriterIPICollision'
    );
    const invalidMetadata =
        nameIsInvalid ||
        pkaIsInvalid ||
        songWriterIpiIsInvalid ||
        !!songWriterIpiCollision;

    useEffect(() => {
        setBaseModalErrors(invalidMetadata);
    }, [invalidMetadata, setBaseModalErrors]);

    const addPKA = () => {
        const newPKA = [...(updateSongWriter.professionallyKnownAs ?? []), ''];
        setUpdateSongWriter(prevState => ({
            ...prevState,
            professionallyKnownAs: newPKA,
        }));
    };
    const setPKA = (value: string, i: number) => {
        const newValues = [...(updateSongWriter.professionallyKnownAs ?? [])];
        newValues[i] = value;
        setUpdateSongWriter(prevState => ({
            ...prevState,
            professionallyKnownAs: newValues.length ? newValues : null,
        }));
    };

    const removePKA = (i: number) => {
        const copy = [...(updateSongWriter.professionallyKnownAs ?? [])];
        copy.splice(i, 1);
        setUpdateSongWriter(prevState => ({
            ...prevState,
            professionallyKnownAs: copy,
        }));
    };

    const onIpiChange = (value: string) => {
        setSongWriterValidationErrorKeys(undefined);
        let formatted = value.slice(-IPI_LENGTH);
        if (value.length < IPI_LENGTH)
            formatted = `00000000000${value}`.slice(-IPI_LENGTH);
        setUpdateSongWriter(prevState => ({ ...prevState, ipi: formatted }));
    };

    return (
        <Section>
            <Section.Header title="Basics" />
            <Section.Body className={CLASSNAME + '-basics-body'}>
                <form>
                    <Field
                        controlId="legal-name"
                        labelText={formatMessage(
                            'songWriterManager.writerLegalName'
                        )}
                        errorMessage={
                            (hasSubmitted &&
                                nameIsInvalid &&
                                formatMessage('errors.nameNeedsSpace')) ||
                            undefined
                        }
                    >
                        <input
                            type="text"
                            className="form-control"
                            placeholder={formatMessage(
                                'songWriterManager.songWriterLegalNamePlaceholder'
                            )}
                            value={updateSongWriter.name}
                            onChange={e => {
                                setUpdateSongWriter(prevState => ({
                                    ...prevState,
                                    name: e.target.value,
                                }));
                            }}
                        />
                    </Field>

                    {updateSongWriter?.professionallyKnownAs?.length !== 0 && (
                        <Label
                            text={formatMessage(
                                'songWriterManager.professionallyKnownAs'
                            )}
                        />
                    )}
                    {updateSongWriter?.professionallyKnownAs?.map((pka, i) => (
                        <Control
                            key={i}
                            className="SongWriterManager-pka-field-control"
                            errorMessage={
                                (hasSubmitted && pkaError(pka)) || undefined
                            }
                        >
                            <div className="SongWriterManager-pka-field">
                                <input
                                    type="text"
                                    className="form-control"
                                    value={pka}
                                    placeholder={formatMessage(
                                        'songWriterManager.professionallyKnownAsPlaceholder'
                                    )}
                                    onChange={e => setPKA(e.target.value, i)}
                                />
                                <div
                                    className="SongWriterManager-pka-field-x"
                                    onClick={() => removePKA(i)}
                                >
                                    <GlyphIcon name="close" size={16} />
                                </div>
                            </div>
                        </Control>
                    ))}

                    <Button
                        variant="link"
                        className="icon-left"
                        onClick={addPKA}
                    >
                        <GlyphIcon name="plus" size={16} />
                        {formatMessage('songWriterManager.addAnotherName')}
                    </Button>
                    <hr />

                    <div className={CLASSNAME + '-half-size-wrapper'}>
                        <Field
                            className={CLASSNAME + '-half-size'}
                            controlId="pro"
                            labelText="PRO"
                            isOptional={!isControlled}
                        >
                            <Select
                                options={PRO_LIST.map((p: string) => ({
                                    value: p,
                                    label: p,
                                }))}
                                selectedValue={
                                    updateSongWriter.pro || undefined
                                }
                                onChange={option =>
                                    setUpdateSongWriter(prevState => ({
                                        ...prevState,
                                        pro: option?.value ?? '',
                                    }))
                                }
                            />
                        </Field>
                        <Field
                            className={CLASSNAME + '-half-size'}
                            controlId="ipi"
                            labelText="IPI"
                            isOptional={!isControlled}
                            errorMessage={
                                (hasSubmitted &&
                                    ((songWriterIpiIsInvalid &&
                                        formatMessage(
                                            'errors.ipiNeeds9Chars'
                                        )) ||
                                        (songWriterIpiCollision &&
                                            formatMessage(
                                                'errors.songWriterIPICollision'
                                            )))) ||
                                undefined
                            }
                        >
                            <NumberInput
                                className="ipi-input"
                                value={updateSongWriter.ipi || ''}
                                onChange={(value: string) => onIpiChange(value)}
                                allowNegatives={false}
                                placeholder={formatMessage(
                                    'songWriterManager.songwriterIpiPlaceholder'
                                )}
                            />
                        </Field>
                    </div>
                </form>
            </Section.Body>
        </Section>
    );
};

export default SongWriterModalBasics;
