import React from 'react';
import { useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next';
import { Box, Flex, FormControl, FormLabel, VStack } from '@chakra-ui/react';

import { CarBodySelect } from './car-body';
import { CarColorInput } from './car-color';
import { CarNumberInput } from './car-number';
import { FormInputField, FormControllerField } from './field';
import { OrderFormProps, OrderFormValues } from './types';
import { PhoneInput } from './phone';
import { SubmitButton } from './submit';
import { defaultValues, useGetValidationRules } from './helper';
import { DateTimeInput } from './date-time';
import {
  LocationInput,
  MapComponent,
  StringLocation,
  YMapsProvider,
} from './location';

export const OrderForm = ({ onSubmit, loading }: OrderFormProps) => {
  const {
    handleSubmit,
    control,
    formState: { errors, isSubmitting },
    watch,
    setValue,
  } = useForm<OrderFormValues>({ defaultValues, shouldFocusError: true });

  const { t } = useTranslation('~', {
    keyPrefix: 'dry-wash.order-create.form',
  });

  const RULES = useGetValidationRules();

  const [availableDatetimeBegin, availableDatetimeEnd, carLocation] = watch([
    'availableDatetimeBegin',
    'availableDatetimeEnd',
    'carLocation',
  ]);

  return (
    <Box p={4} marginInline='auto'>
      <VStack
        as='form'
        noValidate
        onSubmit={handleSubmit(onSubmit)}
        align='flex-start'
        gap={6}
      >
        <FormControllerField
          control={control}
          name='phone'
          label={t('phone-field.label')}
          isRequired
          rules={RULES.isValidPhoneNumber}
          errors={errors}
          Controller={PhoneInput}
        />
        <FormInputField
          control={control}
          name='carNumber'
          label={t('car-number-field.label')}
          isRequired
          rules={RULES.isValidCarNumber}
          errors={errors}
          Input={CarNumberInput}
        />
        <FormInputField
          control={control}
          name='carColor'
          label={t('car-color-field.label')}
          errors={errors}
          Input={CarColorInput}
        />
        <FormInputField
          control={control}
          name='carBody'
          label={t('car-body-field.label')}
          isRequired
          errors={errors}
          Input={CarBodySelect}
        />
        <FormControl isRequired>
          <FormLabel>{t('washing-datetime-field.label')}</FormLabel>
          <Flex flexWrap='wrap' gap={4}>
            <Box flex='1 0 100px'>
              <FormInputField
                control={control}
                name='availableDatetimeBegin'
                isRequired
                errors={errors}
                Input={DateTimeInput}
                inputProps={{
                  max: availableDatetimeEnd,
                }}
              />
            </Box>
            <Box flex='1 0 100px'>
              <FormInputField
                control={control}
                name='availableDatetimeEnd'
                isRequired
                errors={errors}
                Input={DateTimeInput}
                inputProps={{
                  min: availableDatetimeBegin,
                }}
              />
            </Box>
          </Flex>
        </FormControl>
        <YMapsProvider>
          <FormInputField
            control={control}
            name='carLocation'
            label={t('washing-location-field.label')}
            help={t('washing-location-field.help')}
            isRequired
            errors={errors}
            Input={LocationInput}
          />
          <MapComponent
            selectedLocation={carLocation as StringLocation}
            onMapClick={(location) => {
              setValue('carLocation', location);
            }}
          />
        </YMapsProvider>
        <SubmitButton isLoading={isSubmitting || loading} mt={4} />
      </VStack>
    </Box>
  );
};

// todo: remove layout shift, when a validation message is displayed
// todo: fix time range available values
