import {
  IonButton,
  IonButtons,
  IonCol,
  IonContent,
  IonGrid,
  IonHeader,
  IonIcon,
  IonImg,
  IonInput,
  IonItem,
  IonLabel,
  IonList,
  IonLoading,
  IonPage,
  IonRow,
  IonSkeletonText,
  IonToolbar,
  useIonViewDidEnter,
  useIonViewWillEnter,
} from "@ionic/react";
import { BarcodeScanner } from "@capacitor-community/barcode-scanner";
import { Camera } from "@capacitor/camera";
import {
  Expr,
  XConsole,
  AuthenticationClient,
  i18,
} from "@team_eureka/eureka-ionic-core";
import { Fragment, useState } from "react";
import { RouteComponentProps } from "react-router";
import moment, { Moment } from "moment";
import ProductDetail from "./components/product-detail";
import NotFoundComponent from "./components/not-found";
import BarCodeScannerComponent from "./components/barcode-scanner";
import ModalAlertComponent from "./components/modal-alert";
import FloatingMessageComponent from "./components/floating-message";
import { arrowBack } from "ionicons/icons";
import ButtonScannerSvg from "../../../assets/media/button-scanner.svg";
import checkIcon from "../../../assets/media/check.svg";
import Done from "../../../assets/media/done.svg";
import Yogurt from "../../../assets/image/yogurt.jpeg";
import "./index.sass";
import locales from "./locales";

const CencoX = XConsole({ label: "Product-inquiry" });
const localize = i18(locales);

interface IProps extends RouteComponentProps<{}> {
  match: any;
}

interface IProduct {
  ean: string;
  article_number: number;
  price: number;
  provider: string;
  brand: string;
  block_type: any;
  average_sale: number;
  transit_stock: any;
  transit_stock_date: Moment;
  rubro: string;
  image: any;
  description: string;
  stock_nrt: string;
}

const products: IProduct[] = [
  {
    ean: "1",
    article_number: 39580034,
    price: 2.34,
    provider: "Consectetur adipiscing",
    brand: "ipsum dolor",
    block_type: "123",
    average_sale: 345.1,
    transit_stock: 23,
    transit_stock_date: moment(),
    rubro: "dolor sit",
    image: Yogurt,
    description: "Ut enim ad minim veniam, quis nostrud exercitation equat.",
    stock_nrt: "230",
  },
  {
    ean: "2",
    article_number: 74958389,
    price: 0.55,
    provider: "Magna aliqua",
    brand: "Cuartum exod",
    block_type: "123",
    average_sale: 345.1,
    transit_stock: 23,
    transit_stock_date: moment(),
    rubro: "dolor sit",
    image: Yogurt,
    description: "Ut enim ad minim veniam, quis nostrud exercitation.",
    stock_nrt: "104",
  },
  {
    ean: "3",
    article_number: 10200345,
    price: 1.99,
    provider: "Incididunt ut",
    brand: "Setium it",
    block_type: "123",
    average_sale: 345.1,
    transit_stock: 23,
    transit_stock_date: moment(),
    rubro: "dolor sit",
    image: Yogurt,
    description: "Sed do eiusmod tempor incididunt ut labore.",
    stock_nrt: "77",
  },
];

const ProductScannerPage: React.FC<IProps> = (props) => {
  const [product, setProduct] = useState<any>();
  const [productPrice, setProductPrice] = useState<any>();
  const [showLoading, setShowLoading] = useState<boolean>(false);
  const [showReportModal, setShowReportModal] = useState<boolean>(false);
  const [manualEntry, setManualEntry] = useState<boolean>(false);
  const [showSuccessMessage, setShowSuccessMessage] = useState<boolean>(false);
  const [hasStockCountReport, setHasStockCountReport] =
    useState<boolean>(false);
  const [productEAN, setProductEAN] = useState<string>("");
  const [mode, setModeState] = useState<
    "INITIAL_STATE" | "PAGE_LOADED" | "NOT_FOUND" | "SHOW_PRODUCT_DETAIL"
  >("INITIAL_STATE");

  const didUserGrantPermission = async () => {
    const status = await BarcodeScanner.checkPermission({ force: false });

    if (status.granted) {
      return true;
    }

    return false;
  };

  const askCameraPermission = async () => {
    Expr.whenInNativePhone(async () => {
      const status = await BarcodeScanner.checkPermission({ force: false });
        if (status.neverAsked) {
          await Camera.requestPermissions({
            permissions: ["camera"],
          });
        }
    })
  };

  useIonViewDidEnter(() => {
    const params: any = props.match.params;

    setModeState("INITIAL_STATE");
    if (params?.productean) {
      (async () => {
        await showProductDetailByEan(params?.productean);
      })();
    } else {
      (async () => {
        await askCameraPermission();
        await onInitializedScanHandler();
      })();
    }

    Expr.whenInNativePhone(async () => {
      document.addEventListener("ionBackButton", async (ev: any) => {
        ev.detail.register(10, async (processNextHandler: any) => {
          stopScan();
          props.history.goBack();
          processNextHandler();
        });
      });
    });
  });

  useIonViewWillEnter(() => {
    clearState();
  });

  const clearState = () => {
    setShowLoading(false);
    setShowReportModal(false);
    setManualEntry(false);
    setShowSuccessMessage(false);
    setHasStockCountReport(false);
    setProductEAN("");
    setModeState("INITIAL_STATE");
  };

  const onBackButtonClickHandler = async () => {
    props.history.goBack();
  };

  const onGoHomeClickHandler = async () => {
    await stopScan();
    props.history.push("/");
  };

  const onInitializedScanHandler = async () => {
    Expr.whenNotInNativePhone(async () => {
      setManualEntry(true);
      setProductEAN("");
      setTimeout(() => {
        setModeState("PAGE_LOADED");
      }, 1000)
    });

    Expr.whenInNativePhone(async () => {
      setManualEntry(false);
      setProductEAN("");
      setTimeout(() => {
        setModeState("PAGE_LOADED");
      }, 1000)
      const isCameraPermissionGranted = await didUserGrantPermission();
      if (isCameraPermissionGranted) {
        await startScan();
      } else {
        setManualEntry(true);
      }
    });
  };

  const startScan = async () => {
    await BarcodeScanner.hideBackground();
    document.body.style.background = "transparent";
    document.querySelectorAll(".ion-page").forEach((element) => {
      element.setAttribute("style", "background: transparent");
    });
    const result = await BarcodeScanner.startScan();

    if (result.hasContent) {
      stopScan();
      showProductDetailByEan(result.content!);
      props.history.push(`product-detail/${result.content}`);
    }
  };

  const stopScan = async () => {
    await BarcodeScanner.showBackground();
    document.body.style.background = "";
    document.querySelectorAll(".ion-page").forEach((element) => {
      element.setAttribute("style", "");
    });
    return BarcodeScanner.stopScan();
  };

  const calculateHasStockCountReport = async (productEAN: string) => {
    // const {} = AuthenticationClient.getInfo();

    const meta_data = {
      "product.ean": productEAN,
    };

    // const filter: ITaskFilter = {
    //   taskType: "PRODUCTINQUIRY",
    //   state: "COMPLETED",
    //   sameOrBeforeDate: moment().format("YYYY-MM-DD"),
    //   sameOrAfterDate: moment().format("YYYY-MM-DD"),
    //   meta_data: JSON.stringify(meta_data),
    //   store: store,
    // };
    const filter = {
      taskType: "PRODUCTINQUIRY",
      state: "COMPLETED",
      sameOrBeforeDate: moment().format("YYYY-MM-DD"),
      sameOrAfterDate: moment().format("YYYY-MM-DD"),
      meta_data: JSON.stringify(meta_data),
      // store: store,
    };
    // const task = await UserClient.getTasks(filter);

    // if (task.total > 0) {
    //   return true;
    // }
    return true;
  };

  const showProductDetailByEan = async (productEAN: string) => {
    try {
      setShowLoading(true);
      const product = products.find((prod) => prod.ean === productEAN);
      if (product) {
        const hasStockCountReport = await calculateHasStockCountReport(
          productEAN
        );
        setProduct(product);
        setProductPrice([[productPrice]]);
        setProductEAN(productEAN);
        setModeState("SHOW_PRODUCT_DETAIL");
        setShowLoading(false);
        setHasStockCountReport(hasStockCountReport);
      } else {
        setModeState("NOT_FOUND");
        //  throw new Error();
      }
    } catch (error: any) {
      CencoX.error(
        "An error has ocurred trying to get the product byt EAN",
        error
      );
      CencoX.debug(error);
      if (
        error.isAxiosError &&
        error.response &&
        error.response!.status === 404
      ) {
        setProductEAN(productEAN);
        setModeState("NOT_FOUND");
        setShowLoading(false);
      } else {
        props.history.goBack();
      }
    } finally {
      setShowLoading(false);
    }
  };

  const inputChange = (event: any) => {
    setProductEAN(event.detail.value);
  };

  const handleBarScanneResult = async (result: string) => {
    await stopScan();
    props.history.push(`product-detail/${result}`);
  };

  const handleSearch = () => {
    props.history.push(`product-detail/${productEAN}`);
  };

  const onRequestStockCountHandler = async () => {
    setShowReportModal(true);
  };

  const onCloseReportModal = (): void => {
    setShowReportModal(false);
  };

  const onSaveReportHandler = async () => {
    setShowLoading(true);
    try {
      // const user = await getAuthFromCache();
      const userInfo = AuthenticationClient.getInfo();

      // const report: IReport = {
      //   response: 'No',
      //   reason: 'Desajuste de stock'
      // }
      const report = {
        response: "No",
        reason: "Desajuste de stock",
      };
      // const payload: IProductInquiry = {
      //   primarysid: userInfo.primarysid,
      //   report: report,
      //   product: this.state.product!,
      // }
      const payload = {
        primarysid: userInfo.primarysid,
        report: report,
        product,
      };
      // await TaskClient.createTask(payload, user.user, 'PRODUCTINQUIRY');
      setShowLoading(false);
      setShowSuccessMessage(true);
      setShowReportModal(false);
      setHasStockCountReport(false);
    } catch (error) {
      CencoX.error("An error has ocurred trying to create task", error);
    } finally {
      setShowLoading(false);
    }
  };

  const onCloseReportModalHandler = async () => {
    setShowReportModal(false);
  };

  const successModalContent = () => {
    return (
      <Fragment>
        <IonGrid>
          <IonRow class="ion-justify-content-center">
            <IonCol>
              <img src={Done}></img>
            </IonCol>
          </IonRow>
          <IonRow class="ion-justify-content-center">
            <IonCol>
              <h1>{localize("COUNT_STOCK_MODAL_SUCCESS_TEXT", "")}</h1>
            </IonCol>
          </IonRow>
        </IonGrid>
      </Fragment>
    );
  };

  const reportModalContent = () => {
    return (
      <Fragment>
        <div>
          <h1>{localize("COUNT_STOCK_MODAL_CONFIRMATION_TEXT", "")}</h1>
        </div>
      </Fragment>
    );
  };

  const showManualEntry = async () => {
    await stopScan();
    setManualEntry(true);
  };

  const renderSHOW_PRODUCT_DETAIL = () => (
    <Fragment>
      <IonContent>
        <div>
          <ProductDetail
            product={product}
            productPrice={product.price}
            goBackHandler={onBackButtonClickHandler}
            onRequestStockCount={onRequestStockCountHandler}
            hasStockCountReport={hasStockCountReport}
          ></ProductDetail>
        </div>
      </IonContent>
    </Fragment>
  );

  const renderINITIAL_STATE = () => {
    return (
      <Fragment>
        <IonContent>
          <IonGrid>
            <IonRow>
              <IonCol>
                <IonSkeletonText
                  animated={true}
                  className={'skeleton-first'}
                ></IonSkeletonText>
              </IonCol>
            </IonRow>
            <IonRow>
              <IonCol>
                <IonSkeletonText
                  animated={true}
                  className={'skeleton-second'}
                ></IonSkeletonText>
              </IonCol>
            </IonRow>
            <IonRow>
              <IonCol>
                <IonSkeletonText
                  animated={true}
                  className={'skeleton-third'}
                ></IonSkeletonText>
              </IonCol>
            </IonRow>
          </IonGrid>
        </IonContent>
      </Fragment>
    );
  };

  const renderPAGE_LOADED = () => {
    const showBarcodeScanner = !manualEntry;

    return (
      <Fragment>
        {manualEntry ? (
          <Fragment>
            <IonHeader>
              <IonToolbar>
                <IonButtons slot="start">
                  <IonButton
                    className="white"
                    onClick={() => props.history.push(`/`)}
                  >
                    <IonIcon icon={arrowBack} size="large"></IonIcon>
                  </IonButton>
                </IonButtons>
              </IonToolbar>
            </IonHeader>
            <IonContent>
              <div className="manual-entry">
                <IonList>
                  <IonItem>{/*Imagen de un codigo de barra*/}</IonItem>
                  <IonItem>
                    <IonLabel position="stacked">
                      {localize("LABEL_PRODUCT_CODE", "")}
                    </IonLabel>
                    <div>
                      <IonInput
                        inputmode="numeric"
                        onIonChange={inputChange}
                        value={productEAN}
                      ></IonInput>
                      <IonButton
                        disabled={productEAN.length < 1 ? true : false}
                        onClick={handleSearch}
                      >
                        Buscar
                      </IonButton>
                    </div>
                  </IonItem>
                </IonList>
              </div>
            </IonContent>
            <div className="scanner__button">
              <IonImg
                src={ButtonScannerSvg}
                onClick={() => onInitializedScanHandler()}
              ></IonImg>
            </div>
          </Fragment>
        ) : null}
        {
          <BarCodeScannerComponent
            onBarCodeScannerResultHandler={handleBarScanneResult}
            onGoBackHandler={onGoHomeClickHandler}
            onClickManuallyButtonHandler={() => showManualEntry()}
            show={showBarcodeScanner}
          ></BarCodeScannerComponent>
        }
      </Fragment>
    );
  };

  const renderNOT_FOUND = () => {
    return (
      <Fragment>
        <NotFoundComponent
          text="Producto no encontrado"
          buttonText="Volver"
          goBackHandler={onBackButtonClickHandler}
        ></NotFoundComponent>
      </Fragment>
    );
  };

  const renders: Record<typeof mode, any> = {
    INITIAL_STATE: renderINITIAL_STATE,
    PAGE_LOADED: renderPAGE_LOADED,
    NOT_FOUND: renderNOT_FOUND,
    SHOW_PRODUCT_DETAIL: renderSHOW_PRODUCT_DETAIL,
  };

  const render = () => {
    const buttonSendStockCountOk = {
      text: localize("REPORT_MODAL_BUTTON_TEXT", ""),
      onClickHandler: onSaveReportHandler,
    };

    return (
      <IonPage
        className={`product-inquiry-page ${mode
          .replace(/_/gi, "-")
          .toLowerCase()} `}
      >
        {(() => {
          if (!renders[mode]) {
            return <div>{mode}</div>;
          }
          return renders[mode]();
        })()}

        <IonLoading
          cssClass="my-custom-class"
          isOpen={showLoading}
          message={"Por favor espera..."}
        />

        <ModalAlertComponent
          isOpen={showReportModal}
          onClose={onCloseReportModalHandler}
          buttonOk={buttonSendStockCountOk}
          customClass="product-inquiry-page_report-modal"
        >
          {reportModalContent()}
        </ModalAlertComponent>

        <FloatingMessageComponent
          msg={localize("COUNT_STOCK_MODAL_SUCCESS_TEXT", "")}
          icon={checkIcon}
          show={showSuccessMessage}
          onHideHandler={() => setShowSuccessMessage(false)}
          duration={2000}
        ></FloatingMessageComponent>
      </IonPage>
    );
  };

  return render();
};

export default ProductScannerPage;
