import React, { type FC } from 'react';
import { useQuery } from '@apollo/client';
import { yupResolver } from '@hookform/resolvers/yup';
import {
    Button,
    ErrorMessage,
    Form,
    LoadingIndicator,
    Select,
} from '@theorchard/suite-components';
import { formatMessage } from '@theorchard/suite-frontend';
import { useForm } from 'react-hook-form';
import { ClearableInput } from 'src/components';
import FeatureFlagPanel from 'src/components/featureFlagPanel';
import { FEATURE_FLAGS } from 'src/constants';
import {
    TIER_TERM,
    COMPANY_TERM,
    CURRENCY_TERM,
    OWNER_TERM,
    ACCOUNT_NAME_TERM,
    CREATE_ACCOUNT_TERM,
    SELECT_ACCOUNT_NAME_TERM,
    YES_TERM,
    NO_TERM,
} from 'src/constants/staticFormatMessages';
import * as yup from 'yup';
import { query } from './query';
import { useSelectOptions } from './utils';
import type { ListViewItem } from '@theorchard/suite-components';
import type {
    accountOptionsQuery,
    accountOptionsQueryVariables,
} from 'src/pages/definitions/accountModal';
import type { WithQuery } from 'src/util';

const CLASSNAME = 'CreateAccountForm';

const schema = yup.object().shape({
    name: yup.string().required(),
    companyBrandName: yup.string().required(),
    serviceTierUuid: yup.string().required(),
    owner: yup.string().required(),
    currency: yup.string().required(),
    isDistributor: yup.boolean(),
});

type FormInput = yup.Asserts<typeof schema>;

interface Props {
    onSubmit: (
        data: FormInput & {
            serviceTierName?: string;
        }
    ) => void;
}

const d3Options = [
    { label: YES_TERM, value: 'true' },
    { label: NO_TERM, value: 'false' },
];

const CreateAccountForm: WithQuery<
    accountOptionsQuery,
    accountOptionsQueryVariables,
    FC<Props>
> = ({ onSubmit }) => {
    const {
        register,
        handleSubmit,
        formState: { isValid },
        watch,
        setValue,
        trigger,
    } = useForm<FormInput>({
        defaultValues: {
            isDistributor: false,
        },
        resolver: yupResolver(schema),
        reValidateMode: 'onChange',
    });

    // TODO: split this query and components, and make reusable independent filters;
    const { loading, error, data } = useQuery(CreateAccountForm.query, {
        fetchPolicy: 'cache-and-network',
    });

    const { brandOptions, tierOptions, currencyOptions, ownersOptions } =
        useSelectOptions(data);

    if (loading) return <LoadingIndicator />;
    if (error) return <ErrorMessage error={error} />;

    const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
        setValue(event.target.name as keyof FormInput, event.target.value);
    };

    const handleSelectChange =
        (name: keyof FormInput) => (list?: ListViewItem) => {
            const value =
                name === 'isDistributor'
                    ? list?.value === 'true'
                    : list?.value || '';

            setValue(name, value);
            void trigger(name);
        };

    const handleFormSubmit = (data: FormInput) => {
        onSubmit({
            ...data,
            serviceTierName: tierOptions.find(
                ({ value }) => data.serviceTierUuid === value
            )?.label,
        });
    };

    return (
        <form
            onSubmit={handleSubmit(handleFormSubmit)}
            data-testid={CLASSNAME}
            className={CLASSNAME}
        >
            <ClearableInput
                {...register('name')}
                placeholder={SELECT_ACCOUNT_NAME_TERM}
                autoComplete="off"
                labelText={ACCOUNT_NAME_TERM}
                selectedValue={watch('name')}
                onChange={handleInputChange}
            />
            <Form.Group>
                <Form.Label>{COMPANY_TERM}</Form.Label>
                <Select
                    options={brandOptions}
                    onChange={handleSelectChange('companyBrandName')}
                />
            </Form.Group>
            <Form.Group>
                <Form.Label>{TIER_TERM}</Form.Label>
                <Select
                    options={tierOptions}
                    onChange={handleSelectChange('serviceTierUuid')}
                />
            </Form.Group>
            <FeatureFlagPanel featureFlag={FEATURE_FLAGS.D3_FILTER}>
                <Form.Group>
                    <Form.Label>{formatMessage('isDistributor')}</Form.Label>
                    <Select
                        defaultValue={String(watch('isDistributor'))}
                        onChange={handleSelectChange('isDistributor')}
                        options={d3Options}
                        hideFilter
                        hideClearButton
                    />
                </Form.Group>
            </FeatureFlagPanel>
            <Form.Group>
                <Form.Label>{OWNER_TERM}</Form.Label>
                <Select
                    options={ownersOptions}
                    onChange={handleSelectChange('owner')}
                />
            </Form.Group>
            <Form.Group>
                <Form.Label>{CURRENCY_TERM}</Form.Label>
                <Select
                    onChange={handleSelectChange('currency')}
                    options={currencyOptions}
                />
            </Form.Group>
            <div className={`${CLASSNAME}-footer`}>
                <Button
                    variant="primary"
                    className={`${CLASSNAME}-submit-button`}
                    type="submit"
                    disabled={!isValid}
                >
                    {CREATE_ACCOUNT_TERM}
                </Button>
            </div>
        </form>
    );
};

CreateAccountForm.query = query;
export default CreateAccountForm;
