import React, { ReactNode, useCallback, useEffect, useMemo } from "react";
import {
  ControllerProps,
  ControllerRenderProps,
  FieldErrors,
} from "react-hook-form";

import { Asset, useAssets } from "../useAssets";
import { useDefaultCurrency } from "../useDefaultCurrency";
import { useDisplayDecimalDigits } from "../useDisplayDecimalDigits";
import { BuySellContext, BuySellFormProps } from "./context";
import { useBuySellAmountValidation } from "./useBuySellAmountValidation";
import { useBuySellMarketConfigs } from "./useBuySellConfigs";
import { useUpdatePreview } from "./useUpdatePreview";

type SellSpendRenderProps = {
  render: (state: {
    field: ControllerRenderProps<BuySellFormProps, "fromAmount"> & {
      assets: Asset[];
      asset?: Asset;
      minQuantity: number;
      maxQuantity: number;
      hasError?: boolean;
      availableRemain: number;
      onSelect?: (value?: Asset | undefined) => void;
      onFocus?: (e: any) => void;
      getMaxSize?: (value: number) => string | number;
      stepSize?: number;
    };
  }) => React.ReactElement;
  renderErrorComponent?: (mesfromAmounte?: string) => ReactNode;
};

export const SellSpendController = ({
  render,
  renderErrorComponent,
}: SellSpendRenderProps) => {
  // const { control } = BuySellContext.useFormContext();
  // const [ lastChangedField] = useWatch({
  //   name: ["fromAsset", "toAsset", "lastChangedField"],
  //   control,
  //   defaultValue: {
  //     lastChangedField: "from",
  //   },
  // });

  const { lastChangedField } = BuySellContext.useWatch();
  // console.log({3:lastChangedField})
  const { allAssets } = useAssets();
  const { request, resetRefreshCount } = useUpdatePreview({
    mode: "from",
    type: "sell",
  });
  const { filterLotSize, getMaxSize, selectedCurrency } =
    useBuySellMarketConfigs({
      mode: "from",
    });

  const { setValue, clearErrors, register, getValues } =
    BuySellContext.useFormContext();
  const { defaultCrypto } = useDefaultCurrency();

  register("shouldCharge");

  const assets = useMemo(
    () =>
      allAssets?.filter(
        (item) => item.canTrade && item.currencyType === "Crypto",
      ) || [],
    [allAssets],
  );

  const { truncFix } = useDisplayDecimalDigits();

  useEffect(() => {
    const { fromAsset } = getValues();
    if (fromAsset === undefined) {
      const symbol = assets?.find(
        ({ symbol }) => symbol === defaultCrypto,
      )?.symbol;
      setValue("fromAsset", symbol);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [assets]);

  const { checkAmount, minimumFrom, maximumFrom } =
    useBuySellAmountValidation();

  const clearFormErrors = useCallback(
    (errors: FieldErrors<BuySellFormProps>) => {
      if (Object.values(errors).length > 0) {
        clearErrors();
      }
    },
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [],
  );

  const rules = useMemo(
    () => ({
      validate: {
        check: (value: string | null | undefined) =>
          checkAmount({
            value,
            mode: "from",
          }),
      },
    }),
    [checkAmount],
  );

  const renderForm: ControllerProps<BuySellFormProps, "fromAmount">["render"] =
    useCallback(
      ({ field: { onChange, value, ...rest }, formState, fieldState }) => {
        return (
          <>
            {render({
              field: {
                value: value,
                assets,
                availableRemain: truncFix(
                  selectedCurrency?.availableRemain || 0,
                  selectedCurrency?.symbol,
                ),
                minQuantity: minimumFrom || 0,
                maxQuantity: maximumFrom || 0,
                asset: selectedCurrency,
                hasError: value ? !!fieldState.error : false,
                getMaxSize,

                async onSelect(asset?: Asset) {
                  if (selectedCurrency?.symbol !== asset?.symbol) {
                    onChange("");
                    setValue("toAmount", "");
                    const symbol = await new Promise<string | undefined>(
                      (res) => {
                        res(asset?.symbol);
                      },
                    );
                    setValue("fromAsset", symbol);
                    clearFormErrors(formState.errors);
                  }
                },
                onFocus() {
                  lastChangedField !== "from" &&
                    setValue("lastChangedField", "from");
                },
                onChange(value) {
                  if (value === "") {
                    setValue("toAmount", "");
                  }
                  clearFormErrors(formState.errors);
                  request();

                  resetRefreshCount();
                  onChange(value);
                  lastChangedField !== "from" &&
                    setValue("lastChangedField", "from");
                },
                stepSize: filterLotSize?.stepSize,
                ...rest,
              },
            })}
            {renderErrorComponent &&
              renderErrorComponent(
                fieldState.error ? fieldState.error.message : "",
              )}
          </>
        );
      },
      // eslint-disable-next-line react-hooks/exhaustive-deps
      [
        assets,
        clearFormErrors,
        getMaxSize,
        lastChangedField,
        render,
        selectedCurrency,
        truncFix,
        minimumFrom,
        maximumFrom,
        resetRefreshCount,
      ],
    );

  return (
    <BuySellContext.Controller
      name="fromAmount"
      rules={rules}
      render={renderForm}
    />
  );
};
