import {
  BackHistoryButton,
  CancelButton,
  ColorBadge,
  ErrorOverlay,
  LoadingOverlay,
  SubmitButton,
} from "@/components";
import { calculateQuoteItemTotals, calculateQuoteTotals } from "@/lib/calc";
import { useUnsavedChangesNotifier } from "@/lib/hooks";
import { useUrlId } from "@/lib/hooks/useUrlId";
import { Button, Form, Tabs, TabsContent, TabsList, TabsTrigger } from "@/ui";
import { useToast } from "@/ui/use-toast";
import {
  CurrencyData,
  IGetQuote_QuoteItem_Response_DTO,
  IGetQuote_Response_DTO,
  Language,
} from "@shared/contexts";
import { t } from "i18next";
import { useEffect, useMemo, useState } from "react";
import { useForm } from "react-hook-form";
import { useNavigate } from "react-router-dom";
import { QuotePricesResume } from "./components";
import { QuoteDetailsCardEditor, QuoteGeneralCardEditor } from "./components/editors";
import { useQuotes } from "./hooks";

export type QuoteDataForm = IGetQuote_Response_DTO;
export type QuoteDataFormItem = IGetQuote_QuoteItem_Response_DTO;

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const QuoteEdit = () => {
  const navigate = useNavigate();
  const quoteId = useUrlId();
  const { toast } = useToast();

  const [activeTab, setActiveTab] = useState("general");

  const [quoteCurrency, setQuoteCurrency] = useState<CurrencyData>(
    CurrencyData.createDefaultCode().object
  );
  const [quoteLanguage, setQuoteLanguage] = useState<Language>(Language.createDefaultCode().object);

  const { useOne, useUpdate } = useQuotes();

  const { data, status, error: queryError } = useOne(quoteId);

  const defaultValues = useMemo(
    () => ({
      date: "",
      reference: "",
      customer_reference: "",
      customer_information: "",
      lang_code: "",
      currency_code: "",
      payment_method: "",
      notes: "",
      validity: "",
      subtotal_price: {
        amount: undefined,
        scale: 2,
        currency_code: data?.currency_code ?? quoteCurrency.code,
      },
      discount: {
        amount: undefined,
        scale: 0,
      },
      discount_price: {
        amount: undefined,
        scale: 2,
        currency_code: data?.currency_code ?? quoteCurrency.code,
      },
      before_tax_price: {
        amount: undefined,
        scale: 2,
        currency_code: data?.currency_code ?? quoteCurrency.code,
      },
      tax: {
        amount: undefined,
        scale: 0,
      },
      tax_price: {
        amount: undefined,
        scale: 2,
        currency_code: data?.currency_code ?? quoteCurrency.code,
      },
      total_price: {
        amount: undefined,
        scale: 2,
        currency_code: data?.currency_code ?? quoteCurrency.code,
      },
      items: [
        {
          id_article: "",
          description: "",
          quantity: {
            amount: null,
            scale: 2,
          },
          unit_price: {
            amount: null,
            scale: 2,
            currency_code: data?.currency_code ?? quoteCurrency.code,
          },
          subtotal_price: {
            amount: null,
            scale: 2,
            currency_code: data?.currency_code ?? quoteCurrency.code,
          },
          discount: {
            amount: null,
            scale: 2,
          },
          total_price: {
            amount: null,
            scale: 2,
            currency_code: data?.currency_code ?? quoteCurrency.code,
          },
        },
      ],
    }),
    [data, quoteCurrency]
  );

  const { mutate, isPending } = useUpdate(String(quoteId));

  const form = useForm<QuoteDataForm>({
    mode: "onBlur",
    values: data,
    defaultValues,
    //shouldUnregister: true,
  });

  const { getValues, reset, handleSubmit, formState, watch, setValue } = form;
  const { isSubmitting, isDirty } = formState;

  useUnsavedChangesNotifier({
    isDirty,
  });

  const onSubmit = async (data: QuoteDataForm, shouldRedirect: boolean) => {
    // Transformación del form -> typo de request

    mutate(data, {
      onError: (error) => {
        console.debug(error);
        toast({ title: "Error", description: error.message, variant: "destructive" });
        //alert(error.message);
      },
      //onSettled: () => {},
      onSuccess: () => {
        reset(getValues());
        toast({ title: "Cotización guardada", variant: "success" });
        if (shouldRedirect) {
          navigate("/quotes");
        }
        //clear();
      },
    });
  };

  useEffect(() => {
    const { unsubscribe } = watch((_, { name }) => {
      const quote = getValues();

      if (name) {
        switch (true) {
          case name === "currency_code":
            setQuoteCurrency(
              CurrencyData.createFromCode(quote.currency_code ?? CurrencyData.DEFAULT_CURRENCY_CODE)
                .object
            );

            break;

          case name === "lang_code":
            setQuoteLanguage(
              Language.createFromCode(quote.lang_code ?? Language.DEFAULT_LANGUAGE_CODE).object
            );
            break;

          case name === "discount" || name === "tax": {
            const quoteTotals = calculateQuoteTotals(quote);
            setValue("subtotal_price", quoteTotals.subtotalPrice.toObject());
            setValue("discount_price", quoteTotals.discountPrice.toObject());
            setValue("before_tax_price", quoteTotals.priceBeforeTaxes.toObject());
            setValue("tax_price", quoteTotals.taxesPrice.toObject());
            setValue("total_price", quoteTotals.totalPrice.toObject());
            break;
          }

          case name === "items": {
            quote.items &&
              quote.items.map((item, index) => {
                const quoteItemTotals = calculateQuoteItemTotals(item);
                setValue(`items.${index}.subtotal_price`, quoteItemTotals.subtotalPrice.toObject());
                setValue(`items.${index}.total_price`, quoteItemTotals.totalPrice.toObject());
              });

            const quoteTotals = calculateQuoteTotals(quote, true);
            setValue("subtotal_price", quoteTotals.subtotalPrice.toObject());
            setValue("discount_price", quoteTotals.discountPrice.toObject());
            setValue("before_tax_price", quoteTotals.priceBeforeTaxes.toObject());
            setValue("tax_price", quoteTotals.taxesPrice.toObject());
            setValue("total_price", quoteTotals.totalPrice.toObject());

            break;
          }

          case name.endsWith("quantity") ||
            name.endsWith("unit_price") ||
            name.endsWith("discount"): {
            const [, indexString] = String(name).split(".");
            const index = parseInt(indexString);

            const quoteItemTotals = calculateQuoteItemTotals(quote.items[index]);
            setValue(`items.${index}.subtotal_price`, quoteItemTotals.subtotalPrice.toObject());
            setValue(`items.${index}.total_price`, quoteItemTotals.totalPrice.toObject());

            // Cabecera
            const quoteTotals = calculateQuoteTotals(quote, true);
            setValue("subtotal_price", quoteTotals.subtotalPrice.toObject());
            setValue("discount_price", quoteTotals.discountPrice.toObject());
            setValue("before_tax_price", quoteTotals.priceBeforeTaxes.toObject());
            setValue("tax_price", quoteTotals.taxesPrice.toObject());
            setValue("total_price", quoteTotals.totalPrice.toObject());

            break;
          }

          default:
            break;
        }
      }
    });
    return () => unsubscribe();
  }, [watch, getValues, setValue]);

  const handleClose = () => {
    navigate("/quotes", {
      state: {
        id: quoteId,
      },
    });
  };

  if (isSubmitting || isPending) {
    return <LoadingOverlay title='Guardando cotización' />;
  }

  if (status === "error") {
    return <ErrorOverlay errorMessage={queryError.message} />;
  }

  if (status !== "success") {
    return <LoadingOverlay />;
  }

  return (
    <Form {...form}>
      <form onSubmit={handleSubmit((data) => onSubmit(data, false))}>
        <div className='mx-auto grid max-w-[90rem] flex-1 auto-rows-max gap-6'>
          <div className='flex items-center gap-4'>
            <BackHistoryButton />
            <h1 className='flex-1 text-xl font-semibold tracking-tight shrink-0 whitespace-nowrap sm:grow-0'>
              {t("quotes.edit.title")} {data.reference}
            </h1>
            <ColorBadge label={t(`quotes.status.${data.status}`)} className='ml-auto sm:ml-0' />

            <div className='items-center hidden gap-2 md:ml-auto md:flex'>
              <CancelButton
                label={t("common.close")}
                variant='secondary'
                size='sm'
                onClick={handleClose}
              />

              <SubmitButton
                label={t("common.save")}
                size='sm'
                disabled={formState.isSubmitting || formState.isLoading || formState.isValidating}
              />

              <Button
                size='sm'
                disabled={formState.isSubmitting || formState.isLoading || formState.isValidating}
                onClick={handleSubmit((data) => onSubmit(data, true))}
              >
                {t("common.save_close")}
              </Button>
            </div>
          </div>

          <QuoteGeneralCardEditor />
          <QuotePricesResume />
          <QuoteDetailsCardEditor
            currency={quoteCurrency}
            language={quoteLanguage}
            defaultValues={defaultValues}
          />

          <Tabs
            defaultValue='items'
            className='hidden space-y-4 '
            value={activeTab}
            onValueChange={setActiveTab}
          >
            <TabsList>
              <TabsTrigger value='general'>{t("quotes.create.tabs.general")}</TabsTrigger>
              <TabsTrigger value='items'>{t("quotes.create.tabs.items")}</TabsTrigger>
              {/* <TabsTrigger value='history'>{t("quotes.create.tabs.history")}</TabsTrigger>*/}
            </TabsList>

            <TabsContent value='general' forceMount hidden={"general" !== activeTab}></TabsContent>
            <TabsContent value='items' forceMount hidden={"items" !== activeTab}></TabsContent>
          </Tabs>

          <div className='flex items-center justify-center gap-2 md:hidden'>
            <Button variant='outline' size='sm'>
              {t("common.discard")}
            </Button>
            <Button size='sm'>{t("quotes.edit.buttons.save_quote")}</Button>
          </div>
        </div>
      </form>
    </Form>
  );
};
