import { SubmitHandler, useForm } from 'react-hook-form';
import { FetchResult, useMutation } from '@apollo/client';
import { BILLING_DETAILS } from 'components/billing/schema/queries';
import { UPDATE_BILLING_DETAILS } from 'components/billing/schema/mutations';
import {
  UpdateBillingDetailsMutation,
  UpdateBillingDetailsMutationVariables,
} from 'types/graphql';
import { call } from 'utils/call';

import { Box, Button, Spinner } from 'components/common';
import { FormRow } from 'components/FormRow';
import { Input } from 'components/inputs';
import { SelectCountryLazy } from 'components/inputs/country/SelectCountryLazy';

export type BillingInformationFormValues = {
  company: string;
  email: string;
  name: string;
  phone: string;
  vat: string;
  line1: string;
  line2: string;
  city: string;
  state: string;
  country: string;
  postalCode: string;
};

interface BillingDetailsFormProps {
  initialState: BillingInformationFormValues;
  onUpdate: (res: FetchResult<UpdateBillingDetailsMutation>) => void;
}

export const BillingDetailsForm = ({
  initialState,
  onUpdate,
}: BillingDetailsFormProps) => {
  const [submit, mutation] = useMutation<
    UpdateBillingDetailsMutation,
    UpdateBillingDetailsMutationVariables
  >(UPDATE_BILLING_DETAILS, {
    refetchQueries: [{ query: BILLING_DETAILS }],
    awaitRefetchQueries: true,
  });
  const {
    register,
    formState: { errors },
    handleSubmit,
    watch,
  } = useForm<BillingInformationFormValues>({
    defaultValues: initialState,
  });

  const required = (key: string) =>
    (errors as Record<string, any>)[key] ? 'Required' : undefined;

  const onSubmit: SubmitHandler<BillingInformationFormValues> = async (
    data,
    ev
  ) => {
    (ev as React.MouseEvent<HTMLButtonElement>).preventDefault();
    try {
      const res = await submit({
        variables: {
          input: {
            city: data.city,
            company: data.company,
            country: data.country,
            email: data.email,
            line1: data.line1,
            line2: data.line2,
            name: data.name,
            phone: data.phone,
            postalCode: data.postalCode,
            state: data.state,
            vat: data.vat,
          },
        },
      });
      call(onUpdate, res);
    } catch (error) {
      console.log(error);
    }
  };

  const loading = mutation.loading;

  return (
    <Box position="relative">
      <FormRow label="Company">
        <Input
          {...register('company')}
          placeholder="Company name"
          disabled={loading}
        />
      </FormRow>
      <FormRow label="Email *">
        <Input
          {...register('email', { required: true })}
          error={required('email')}
          placeholder="Email address"
          disabled={loading}
        />
      </FormRow>
      <FormRow label="Name *">
        <Input
          {...register('name', { required: true })}
          error={required('name')}
          placeholder="Full name"
          disabled={loading}
        />
      </FormRow>
      <FormRow label="Phone">
        <Input
          {...register('phone')}
          placeholder="Billing phone number (including extension)"
          disabled={loading}
        />
      </FormRow>
      <FormRow label="VAT">
        <Input {...register('vat')} placeholder="12345678" disabled={loading} />
      </FormRow>

      <FormRow label="Address line 1 *">
        <Input
          {...register('line1', { required: true })}
          error={required('line1')}
          placeholder="Street, PO Box, or company name"
          disabled={loading}
        />
      </FormRow>
      <FormRow label="Address line 2">
        <Input
          {...register('line2')}
          placeholder="Apartment, suite, unit, or building"
          disabled={loading}
        />
      </FormRow>
      <FormRow label="City *">
        <Input
          {...register('city', { required: true })}
          error={required('city')}
          placeholder="City, district, suburb, town, or village"
          disabled={loading}
        />
      </FormRow>
      <FormRow label="State *">
        <Input
          {...register('state', { required: true })}
          error={required('state')}
          placeholder="State, county, province, or region"
          disabled={loading}
        />
      </FormRow>
      <FormRow label="Country *">
        <SelectCountryLazy
          {...register('country', { required: true })}
          // error={required('country')} // TODO add 'error' prop to Select component
          value={watch('country')}
          disabled={loading}
        />
      </FormRow>
      <FormRow label="Postal code *">
        <Input
          {...register('postalCode', { required: true })}
          error={required('postalCode')}
          placeholder="ZIP or postal code"
          disabled={loading}
        />
      </FormRow>

      <Box display="flex" justify="end">
        <Button onClick={handleSubmit(onSubmit)} size="l" disabled={loading}>
          Save
        </Button>
      </Box>
      <Spinner show={loading} />
    </Box>
  );
};
