import { getConfigValue } from '@brojs/cli';
import { useEffect, useState } from 'react';

import { CreateOrder, GetOrder } from '../models/api';

import { QueryState, Trigger } from './types';

enum LandingEndpoints {
  ORDER = '/order',
  ORDER_CREATE = '/order/create',
}

const endpoint = getConfigValue('dry-wash.api');

const useCreateOrderMutation = <D extends CreateOrder.Response>(): [
  Trigger<CreateOrder.Params, QueryState<D>['data']>,
  QueryState<D>,
] => {
  const [isLoading, setIsLoading] = useState<QueryState<D>['isLoading']>(false);
  const [isSuccess, setIsSuccess] = useState<QueryState<D>['isSuccess']>();
  const [data, setData] = useState<QueryState<D>['data']>();
  const [isError, setIsError] = useState<QueryState<D>['isError']>();
  const [error, setError] = useState<QueryState<D>['error']>();

  const createOrder = async ({ body }: CreateOrder.Params) => {
    setIsLoading(true);

    try {
      const response = await fetch(
        `${endpoint}${LandingEndpoints.ORDER_CREATE}`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(body),
        },
      );

      if (!response.ok) {
        const errorResponseObject =
          (await response.json()) as QueryState<D>['error'];
        setIsError(true);
        setError(errorResponseObject);
        throw errorResponseObject;
      }

      const dataResponseObject =
        (await response.json()) as QueryState<D>['data'];
      setIsSuccess(true);
      setData(dataResponseObject);

      return dataResponseObject;
    } catch (error) {
      setIsError(true);
      setError(error);
      throw error;
    } finally {
      setIsLoading(false);
    }
  };

  return [createOrder, { isLoading, isSuccess, data, isError, error }];
};

const useGetOrderQuery = <D extends GetOrder.Response>({
  orderId,
}: GetOrder.Params): QueryState<D> => {
  const [isLoading, setIsLoading] = useState<QueryState<D>['isLoading']>(true);
  const [isSuccess, setIsSuccess] = useState<QueryState<D>['isSuccess']>();
  const [data, setData] = useState<QueryState<D>['data']>();
  const [isError, setIsError] = useState<QueryState<D>['isError']>();
  const [error, setError] = useState<QueryState<D>['error']>();
  
  useEffect(() => {
    (async () => {
      try {
        const response = await fetch(
          `${endpoint}${LandingEndpoints.ORDER}/${orderId}`,
        );

        if (!response.ok) {
          const errorResponseObject =
            (await response.json()) as QueryState<D>['error'];
          setIsError(true);
          setError(errorResponseObject);
          throw errorResponseObject;
        }

        const dataResponseObject =
          (await response.json()) as QueryState<D>['data'];
        setIsSuccess(true);
        setData(dataResponseObject);
      } catch (error) {
        setIsError(true);
        setError(error);
        throw error;
      } finally {
        setIsLoading(false);
      }
    })();
  }, []);

  return { isLoading, isSuccess, data, isError, error };
};

export { useCreateOrderMutation, useGetOrderQuery };