import { Button, Tag, Modal, Typography } from "antd";
import axios from "axios";
import { useState } from "react";
import { FaWandMagicSparkles } from "react-icons/fa6";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { useNotification } from "../../contexts/Notifications/notificationContext";
import { selectBillEnterModal } from "../../redux/modals/modals.selectors";
import { selectBodyshop } from "../../redux/user/user.selectors";
import { useTranslation } from "react-i18next";

const mapStateToProps = createStructuredSelector({
  billEnterModal: selectBillEnterModal,
  bodyshop: selectBodyshop
});

function BillEnterAiScan({
  billEnterModal,
  bodyshop,
  pollingIntervalRef,
  setPollingIntervalRef,
  form,
  fileInputRef,
  scanLoading,
  setScanLoading,
  setIsAiScan,
  setRawAIData
}) {
  const notification = useNotification();
  const { t } = useTranslation();
  const [showBetaModal, setShowBetaModal] = useState(false);
  const BETA_ACCEPTANCE_KEY = "ai_scan_beta_acceptance";
  const handleBetaAcceptance = () => {
    localStorage.setItem(BETA_ACCEPTANCE_KEY, "true");
    setShowBetaModal(false);
    fileInputRef.current?.click();
  };

  const checkBetaAcceptance = () => {
    const hasAccepted = localStorage.getItem(BETA_ACCEPTANCE_KEY);
    if (hasAccepted) {
      fileInputRef.current?.click();
    } else {
      setShowBetaModal(true);
    }
  };

  // Polling function for multipage PDF status
  const pollJobStatus = async (textractJobId) => {
    try {
      const { data } = await axios.get(`/ai/bill-ocr/status/${textractJobId}`);

      if (data.status === "COMPLETED") {
        // Stop polling
        if (pollingIntervalRef.current) {
          clearInterval(pollingIntervalRef.current);
          setPollingIntervalRef(null);
        }
        setScanLoading(false);

        setRawAIData(data.data);
        // Update form with the extracted data
        if (data?.data?.billForm) {
          form.setFieldsValue(data.data.billForm);
          await form.validateFields(["billlines"], { recursive: true });
          notification.success({
            title: t("bills.labels.ai.scancomplete")
          });
        }
      } else if (data.status === "FAILED") {
        // Stop polling on failure
        if (pollingIntervalRef.current) {
          clearInterval(pollingIntervalRef.current);
          setPollingIntervalRef(null);
        }
        setScanLoading(false);

        notification.error({
          title: t("bills.labels.ai.scanfailed"),
          description: data.error || ""
        });
      }
      // If status is IN_PROGRESS, continue polling
    } catch (error) {
      // Stop polling on error
      if (pollingIntervalRef.current) {
        clearInterval(pollingIntervalRef.current);
        setPollingIntervalRef(null);
      }
      setScanLoading(false);

      notification.error({
        title: t("bills.labels.ai.scanfailed"),
        description: error.response?.data?.message || error.message || "Failed to check scan status"
      });
    }
  };

  return (
    <>
      <input
        ref={fileInputRef}
        type="file"
        accept="image/*,application/pdf"
        style={{ display: "none" }}
        onChange={async (e) => {
          const file = e.target.files?.[0];
          if (file) {
            setScanLoading(true);
            setIsAiScan(true);
            const formdata = new FormData();
            formdata.append("billScan", file);
            formdata.append("jobid", form.getFieldValue("jobid") || billEnterModal.context.job?.id);
            formdata.append("bodyshopid", bodyshop.id);
            formdata.append("partsorderid", billEnterModal.context.parts_order?.id);

            try {
              const { data, status } = await axios.post("/ai/bill-ocr", formdata);

              // Add the scanned file to the upload field
              const currentUploads = form.getFieldValue("upload") || [];
              form.setFieldValue("upload", [
                ...currentUploads,
                {
                  uid: `ai-scan-${Date.now()}`,
                  name: file.name,
                  originFileObj: file,
                  status: "done"
                }
              ]);
              if (status === 202) {
                // Multipage PDF - start polling
                notification.info({
                  title: t("bills.labels.ai.scanstarted"),
                  description: t("bills.labels.ai.multipage")
                });

                //Workaround needed to bypass react-compiler error about manipulating refs in child components. Refactor may be needed in the future to clean this up.
                setPollingIntervalRef(
                  setInterval(() => {
                    pollJobStatus(data.textractJobId);
                  }, 3000)
                );

                // Initial poll
                pollJobStatus(data.textractJobId);
              } else if (status === 200) {
                // Single page - immediate response
                setScanLoading(false);

                form.setFieldsValue(data.data.billForm);
                setRawAIData(data.data);
                await form.validateFields(["billlines"], { recursive: true });

                notification.success({
                  title: t("bills.labels.ai.scancomplete")
                });
              }
            } catch (error) {
              setScanLoading(false);
              notification.error({
                title: t("bills.labels.ai.scanfailed"),
                description: error.response?.data?.message || error.message || t("bills.labels.ai.generic_failure")
              });
            }
          }
          // Reset the input so the same file can be selected again
          e.target.value = "";
        }}
      />

      <Button onClick={checkBetaAcceptance} icon={<FaWandMagicSparkles />} loading={scanLoading} disabled={scanLoading}>
        {scanLoading ? t("bills.labels.ai.processing") : t("bills.labels.ai.scan")}
        <Tag color="red">{t("general.labels.beta")}</Tag>
      </Button>

      <Modal
        title={t("bills.labels.ai.disclaimer_title")}
        open={showBetaModal}
        onOk={handleBetaAcceptance}
        onCancel={() => setShowBetaModal(false)}
        okText={t("bills.labels.ai.accept_and_continue")}
        cancelText={t("general.actions.cancel")}
      >
        {
          //This is explicitly not translated.
        }
        <Typography.Text>
          This AI scanning feature is currently in <strong>beta</strong>. While it can accelerate data entry, you{" "}
          <strong>must carefully review all extracted results</strong> for accuracy.
        </Typography.Text>
        <Typography.Text>The AI may make mistakes or miss information. Always verify:</Typography.Text>
        <ul>
          <li>All line items and quantities</li>
          <li>Prices and totals</li>
          <li>Part numbers and descriptions</li>
          <li>Any other critical invoice details</li>
        </ul>
        <Typography.Text>
          By continuing, you acknowledge that you will review and verify all AI-generated data before posting.
        </Typography.Text>
      </Modal>
    </>
  );
}
export default connect(mapStateToProps, null)(BillEnterAiScan);
