import { useState, useEffect, useCallback } from "react";
import { API } from "aws-amplify";
import { useAuth } from "../../context/authContext";
import { Col, Container, Row } from "react-bootstrap";
import { listS3Objects, deleteS3Objects } from "../../util/s3Objects";
import MainModal from "../../components/modals/mainModal";
import FileExplorer from "../../components/fileComponents/fileExplorer";
import { errorLog } from "../../util/errorLog";
import WorkflowFileDownload from "../../components/fileComponents/WorkflowFileDownload";
//Functions
import { updateClientBanks } from "./functions/updateClientBanks";
import { getFiles } from "./functions/getFiles";
import { canGenerateWorkFlow } from "./functions/canGenerateWorkFlow";
import { getUploadProcess } from "./functions/getUploadProcess";
import { getExplorerMsg } from "./functions/getExplorerMsg";
import { setDefaultClient } from "./functions/setDefaultClient";

//Data
import FileExplorerButtons from "../../components/fileComponents/explorerButtons";
import MainDropdowns from "../../components/fileComponents/mainDropDown";
import WorkFlowUplaods from "../../components/fileComponents/WorkflowUploads";
import FileExplorerDropdowns from "../../components/fileComponents/FileExplorerDropdowns";


const Details = () => {
  const {
    userAuth,
    sessionId,
    currentUser,
    setCurrentUser,
    clients,
    getClients,
    clientBanks,
    getClientBanks,
  } = useAuth();

  const [excelFiles, setExcelFiles] = useState([]);
  const [pdfFiles, setPdfFiles] = useState([]);
  const [csvFiles, setCsvFiles] = useState([]);

  const [generated, setGenerated] = useState(false);
  const [canGenerate, setCanGenerate] = useState(false);

  const [loading, setLoading] = useState(false);
  const [newWorkflow, setNewWorkflow] = useState("");
  const [newClient, setNewClient] = useState("");
  const [loadingPage,setLoadingPage] = useState(true);

  const [modal, setModal] = useState(false);
  const [loadModal, setLoadModal] = useState(false);
  const [excelfilerequired, setExcelfilerequired] = useState(false);

  const [loadingProgress, setLoadingProgress] = useState(0);

  // eslint-disable-next-line react-hooks/exhaustive-deps
  useEffect(() => {
    getClients();
  }, [getClients]);

  const refreshFiles = useCallback(async () => {
    try {
      setLoadModal(true);
      setCanGenerate(false);
      setLoadingProgress((prev) => prev + 10);

      let newXlsxFiles = [];
      let newPdfFiles = [];
      let newCsvFiles = [];
      let newJsonfiles = [];

      let processing = true;

      while (processing) {
        const s3Files = await listS3Objects();
        if (s3Files) {
          const files = await getFiles(s3Files);
          newXlsxFiles = files.newXlsxFiles;
          newCsvFiles = files.newCsvFiles;
          newJsonfiles = files.newJsonfiles;
          newPdfFiles = files.newPdfFiles;

          processing = canGenerateWorkFlow(
            setCanGenerate,
            currentUser,
            newXlsxFiles,
            newPdfFiles,
            newJsonfiles
          );
        } else {
          processing = false;
        }

        setExcelFiles(newXlsxFiles);
        setPdfFiles(newPdfFiles);
        setCsvFiles(newCsvFiles);

        await new Promise((resolve) => setTimeout(resolve, 1000));
      }
      
      setLoadingProgress((prev) => (prev > 49 ? 90 : prev + 5));
      await updateClientBanks(currentUser, setCurrentUser, getClientBanks);
      setLoadingProgress((prev) => (prev > 90 ? 100 : prev + 5));
      setLoadingProgress(0);
      setLoadModal(false);
    } catch (err) {
      await errorLog(err, "pages -> workflow -> details.js", "refreshFiles");
    }
    setLoadingPage(false);
  }, [currentUser, setCurrentUser, getClientBanks, setCanGenerate, setExcelFiles, setPdfFiles, setCsvFiles, setLoadingProgress, setLoadModal, setLoadingPage]);

  useEffect(() => {
    refreshFiles();    
    if (clients.length > 0){
      setDefaultClient(clients ,currentUser,setCurrentUser);   
    }
    // Do not change this line as it goes into infinite loop if any other dependencies are added
  }, [clients]); // eslint-disable-line react-hooks/exhaustive-deps


 
  /**
   * Refreshes the list of files available for generating a report.
   * Retrieves the list of files from an S3 bucket, filters out unwanted files,
   * and updates the state variables that hold the lists of Excel, PDF, and CSV files.
   * It also checks if the necessary files are present to enable report generation.
   */

  const handleDeleteFile = async (file) => {
    setLoadModal(true);
    await deleteS3Objects(file.key);
    await refreshFiles();
  };

  /**
   * Handles the clearing of the workflow by updating the user's workflow type and current client,
   * deleting session uploads, clearing the master session table, and updating the user's upload process.
   */
  const handleClearWorkflow = async () => {
    try {
      setModal(false);
      setLoadModal(true);
      setLoadingProgress(10);
      if (newWorkflow && newWorkflow !== undefined && newWorkflow !== "") {
        setCurrentUser((prevUser) => ({
          ...prevUser,
          workflow_type: newWorkflow,
          current_bank: undefined,
        }));
        await API.post(
          "apibigpond",
          `/updateuserworkflowtype/${JSON.stringify({
            id: currentUser.id,
            workflowType: newWorkflow,
          })}`
        );
      }
      if (newClient && newClient !== undefined && newClient !== "") {
        const clientSelected = clients.filter((client) => String(client.id) === String(newClient))[0].name; 
        setCurrentUser((prevUser) => ({
          ...prevUser,
          current_client: newClient,
          current_client_name: clientSelected,
          current_bank: undefined,
        }));
        await API.post(
          "apibigpond",
          `/updateuserclient/${JSON.stringify({
            id: currentUser.id,
            client_id: newClient,
          })}`
        );
      }

      setLoadingProgress(45);
      
          await Promise.all([
            API.post(
              "apibigpond",
              `/deletesessionuploads/${userAuth.identityId}`
            ),
            API.post("apibigpond", `/clearmastersessiontable/${sessionId}`),
            API.post("apibigpond", `/updateuseruploadprocess/${currentUser.id}`),
          ]);
      
      setLoadingProgress(100);

      setExcelFiles([]);
      setPdfFiles([]);
      setCsvFiles([]);
      setCanGenerate(false);
      setGenerated(false);

      await updateClientBanks(currentUser, setCurrentUser, getClientBanks);

      setLoadingProgress(0);
      setLoadModal(false);
    } catch (err) {
      await errorLog(
        err,
        "pages -> workflowPage -> details.jsx",
        "handleClearWorkflow"
      );
    }
  };

  let uploadProgress = getUploadProcess(
    currentUser,
    excelFiles,
    pdfFiles,
    csvFiles
  );

  const explorerMsg = getExplorerMsg(
    currentUser,
    excelFiles,
    pdfFiles,
    csvFiles,
    loading,
    canGenerate,
    uploadProgress
  );  

  return (
    <div className="content-wrapper">
      <div className="main-body h-100">
        <Container
          fluid
          style={{
            background: "white",
            overflowY: "hidden",
            overflowX: "hidden",
            marginBottom: "20px",
            borderRadius: "10px",
            padding: "15px",
          }}
        >
          <div className="text-start" style={{ paddingLeft: "10px" }}>
            <h2>Xero Testing</h2>
          </div>
          <div className="divider-light"></div>
          {!loadingPage && clients.length === 0 ? (
            <h4>
              No clients found for Audit Firm {currentUser.company_name}. Please
              activate clients by requesting Xero access.
            </h4>
          ) : (
            <Row>
              <Col>
                <div id="workflow">
                  <Row>
                    <Col lg={8} md={8} sm={8}>
                      <h2>FILE UPLOADER</h2>
                      <Row>
                        <MainDropdowns
                          excelFiles={excelFiles}
                          pdfFiles={pdfFiles}
                          csvFiles={csvFiles}
                          setNewClient={setNewClient}
                          setNewWorkflow={setNewWorkflow}
                          setModal={setModal}
                          setLoadModal={setLoadModal}
                        />
                      </Row>
                      <WorkflowFileDownload />
                      <WorkFlowUplaods
                        setLoadModal={setLoadModal}
                        setLoadingProgress={setLoadingProgress}
                        refreshFiles={refreshFiles}
                        handleDeleteFile={handleDeleteFile}
                        excelFiles={excelFiles}
                        clientBanks={clientBanks}
                      />
                    </Col>
                    <Col lg={4} md={4} sm={4}>
                      <FileExplorer explorerMsg={explorerMsg} />
                      <FileExplorerButtons
                        loading={loading}
                        setLoading={setLoading}
                        canGenerate={canGenerate}
                        generated={generated}
                        setGenerated={setGenerated}
                        explorerMsg={explorerMsg}
                      />
                      <FileExplorerDropdowns
                        excelFiles={excelFiles}
                        setExcelFiles={setExcelFiles}
                        setPdfFiles={setPdfFiles}
                        setCsvFiles={setCsvFiles}
                        pdfFiles={pdfFiles}
                        csvFiles={csvFiles}
                      />
                    </Col>
                  </Row>
                </div>
              </Col>
            </Row>
          )}
          <MainModal
            type={"warning"}
            onHide={() => setModal(false)}
            show={modal}
            handleClearWorkflow={handleClearWorkflow}
          />
          <MainModal
            type={"loading"}
            onHide={() => setLoadModal(false)}
            show={loadModal}
            loadingProgress={loadingProgress}
          />
          <MainModal
            type={"excelfilerequired"}
            onHide={() => setExcelfilerequired(false)}
            show={excelfilerequired}
          />
        </Container>
      </div>
    </div>
  );
};

export default Details;
