import React, { useState, useEffect } from "react";
import "./ProjectInfra.css";
import BuildingModel from "./Infrastructure/BuildingModel";
import FloorModel from "./Infrastructure/FloorModel";
import showToast from "../../services/toastService";
import WorkAreaModel from "./Infrastructure/WorkAreaModel";
import TaskModel from "./Infrastructure/TaskModel";
import ProjectRepository, {
  TasksRepository,
} from "../../repositories/ProjectRepository";
import ProjectModal from "./ProjectModal";
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import { MANAGE_PROJECT_INFRA } from "../../utils/constants";
import InfraTable from "./Infrastructure/InfraTable";
import { cacheData, clearCacheKey, getCachedData } from "../../slices/apiDataManager";
import { useProjectDetails } from "../../hooks/useProjects";

const ProjectInfra = ({
  data,
  onDataChange,
  eachSiteEngineer,
}) => {
  const [expandedBuildings, setExpandedBuildings] = useState([]);
  const { projects_Details,refetch, loading } = useProjectDetails(data.id);
  const [project, setProject] = useState(projects_Details);
  const [modalConfig, setModalConfig] = useState({ type: null, data: null });
  const [isModalOpen, setIsModalOpen] = useState(false);
  const ManageInfra = useHasUserPermission(MANAGE_PROJECT_INFRA);

  const [isBuildingModalOpen, setIsBuildingModalOpen] = useState(false);
  const [isFloorModalOpen, setIsFloorModalOpen] = useState(false);
  const [isWorkAreaModelOpen, setIsWorkAreaModalOpen] = useState(false);
  const [isTaskModelOpen, setIsTaskModalOpen] = useState(false);
  const [isAssignRoleModal, setIsAssingRoleModal] = useState(false);
  const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
  const [clearFormTrigger, setClearFormTrigger] = useState(false);
  const [CurrentBuilding, setCurrentBuilding] = useState("");
  const [showModal, setShowModal] = useState(false);

  useEffect(() => {
    setProject(projects_Details);
  }, [data, projects_Details]);

  const openFloorModel = (projectData) => {
    setIsFloorModalOpen(true);
  };
  const closeFloorModel = () => {
    setIsFloorModalOpen(false);
  };

  const openAssignModel = (assignData) => {
    setCurrentBuilding(assignData);
    setIsAssingRoleModal(true);
  };
  const openBuildingModel = (projectData) => {
    setIsBuildingModalOpen(true);
  };

  const closeBuildingModel = () => {
    setIsBuildingModalOpen(false);
  };

  const handleBuildingModelFormSubmit = (buildingmodel) => {
    if (buildingmodel.id == "" || buildingmodel.id == 0)
      delete buildingmodel.id;
    let data = [
      {
        building: buildingmodel,
        floor: null,
        workArea: null,
      },
    ];
    submitData(data);
  };
  const handleFloorModelFormSubmit = (updatedFloor) => {
    if (updatedFloor.id == "") delete updatedFloor.id;
    submitData([
      {
        building: null,
        floor: updatedFloor,
        workArea: null,
      },
    ]);
  };

  const openWorkAreaModel = (projectData) => {
    setIsWorkAreaModalOpen(true);
  };

  const closeWorkAreaModel = () => {
    setIsWorkAreaModalOpen(false);
  };
  const handleWorkAreaModelFormSubmit = (updatedModel) => {
    if (updatedModel.id == "") delete updatedModel.id;
    submitData([
      {
        building: null,
        floor: null,
        workArea: updatedModel,
      },
    ]);
  };

  const openTaskModel = (projectData) => {
    setIsTaskModalOpen(true);
  };

  const closeTaskModel = () => {
    setIsTaskModalOpen(false);
  };

  const handleTaskModelFormSubmit = (updatedModel) => {
    if (updatedModel.id == "") updatedModel.id = null;
    const updatedProject = { ...project };

    ProjectRepository.manageProjectTasks([updatedModel])
      .then((response) => {
        onDataChange("task-change");
        showToast("Details updated successfully.", "success");
        // setClearFormTrigger( true );
        if (response?.data[0]) {
          const { workItemId, workItem } = response.data[0];

          const updatedBuildings = updatedProject.buildings.map((building) =>
            building.id == updatedModel.buildingID
              ? {
                  ...building,
                  floors: building.floors.map((floor) =>
                    floor.id == updatedModel.floorId
                      ? {
                          ...floor,
                          workAreas: floor.workAreas.map((workArea) =>
                            workArea.id === workItem?.workAreaId
                              ? {
                                  ...workArea,
                                  workItems: workArea.workItems.some(
                                    (existingItem) =>
                                      existingItem.workItemId ===
                                      workItem.workItemId
                                  )
                                  ? [...workArea.workItems] // Create a new array to trigger re-render
                                  : [...workArea.workItems, workItem],
                                }
                              : workArea
                          ),
                        }
                      : floor
                  ),
                }
              : building
          );
          updatedProject.buildings = updatedBuildings;
          // workItem update, but having local state issue there for needed to calling api
          clearCacheKey( "projectInfo" )
          refetch()

          cacheData("projectInfo", {
            projectId: updatedProject.id,
            data: updatedProject,
          });
     
          setProject( updatedProject );
          // closeTaskModel()
        }
      })
      .catch((error) => {
        showToast(error.message, "error");
      });
  };


  const submitData = async (infraObject) => {
    try
    {
      
      let response = await ProjectRepository.manageProjectInfra(infraObject);
      const entity = response.data;

      const updatedProject = { ...project };
      // Handle the building data
      if (entity.building) {
        const { id, name, description } = entity.building;
        const updatedBuildings = updatedProject?.buildings?.map((building) =>
          building.id === id ? { ...building, name, description } : building
        );

        // Add building if it doesn't exist
        if (!updatedProject.buildings.some((building) => building.id === id)) {
          updatedBuildings.push({
            id: id,
            name,
            description,
            floors: [],
          });
        }

        updatedProject.buildings = updatedBuildings;

        // Update the cache for buildings
        cacheData("projectInfo", {
          projectId: updatedProject.id,
          data: updatedProject,
        });
        setProject((prevProject) => ({
          ...prevProject,
          buildings: updatedBuildings,
        } ) );
        // closeBuildingModel()
        
      }
      // Handle the floor data
      else if (entity.floor) {
        const { buildingId, id, floorName } = entity.floor;
        const updatedBuildings = updatedProject?.buildings?.map((building) =>
          building.id == buildingId
            ? {
                ...building,
                floors: building.floors
                  .map((floor) =>
                    floor.id === id
                      ? {
                          ...floor,
                          floorName, // Update the floor name only
                          // Keep other properties as they are (including workArea)
                        }
                      : floor
                  )
                  // Add the new floor if it doesn't already exist
                  .concat(
                    !building.floors.some((floor) => floor.id === id)
                      ? [{ id: id, floorName, workAreas: [] }] // New floor added with workArea set to null
                      : []
                  ),
              }
            : building
        );

        updatedProject.buildings = updatedBuildings;

        // Cache the updated project
        cacheData("projectInfo", {
          projectId: updatedProject.id,
          data: updatedProject,
        });
        setProject( updatedProject );
        // closeFloorModel()
      }
      // Handle the work area data
      else if ( entity.workArea )
      {
        let buildingId = infraObject[0].workArea.buildingId;

        const { floorId, areaName, id } = entity.workArea;
        // Check if the workArea exists, otherwise create a new one
        const updatedBuildings = updatedProject.buildings.map((building) =>
          building.id == buildingId
            ? {
                ...building,
                floors: building.floors.map((floor) =>
                  floor.id == floorId
                    ? {
                        ...floor,
                        workAreas: floor.workAreas.some(
                          (workArea) => workArea.id === id
                        )
                          ? floor.workAreas.map((workArea) =>
                              workArea.id === id
                                ? { ...workArea, areaName }
                                : workArea
                            )
                          : [
                              ...floor.workAreas,
                              { id, areaName, workItems: [] },
                            ],
                      }
                    : floor
                ),
              }
            : building
        );

        updatedProject.buildings = updatedBuildings;

        // Update the cache for work areas
        cacheData("projectInfo", {
          projectId: updatedProject.id,
          data: updatedProject,
        });
        setProject( updatedProject );
        // closeWorkAreaModel()
      }
      // Handle the task (workItem) data
      else {
        console.error("Unsupported data type for submitData", entity);
      }
    } catch (Err) {
      showToast("Somthing wrong", "error");
    }
  };

 
  const toggleBuilding = (id) => {
    setExpandedBuildings((prev) =>
      prev.includes(id) ? prev.filter((bid) => bid !== id) : [...prev, id]
    );
  };

  const handleModalData = (type, modaldata) => {
    setModalConfig({ type: type, data: modaldata });
  };
  const openModal = () => {
    const modalElement = document.getElementById("building-model");
    const modal = new Modal(modalElement, {
      backdrop: false,
      keyboard: true,
      focus: true,
    });
    modal.show();
  };
  const closeModal = () => {
    setIsModalOpen(false);
    setModalConfig(null);

    const modalElement = document.getElementById("building-model");
    if (modalElement) {
      modalElement.classList.remove("show"); // Remove modal visibility class
      modalElement.style.display = "none"; // Hide the modal element
    }

    document.body.classList.remove("modal-open"); // Remove modal-open class from body

    // Remove the modal backdrop
    const backdropElement = document.querySelector(".modal-backdrop");
    if (backdropElement) {
      backdropElement.classList.remove("modal-backdrop"); // Remove backdrop class
      backdropElement.style.display = "none"; // Hide the backdrop element
    }
    document.body.style.overflow = "auto";
  };

  const handleShow = () => setShowModal(true);
  const handleClose = () => setShowModal(false);

  return (
    <>
      <div
        className={`modal fade ${showModal ? "show" : ""}`}
        tabIndex="-1"
        role="dialog"
        style={{ display: showModal ? "block" : "none" }}
        aria-hidden={!showModal}
      >
        <BuildingModel
          project={project}
          onClose={handleClose}
          onSubmit={handleBuildingModelFormSubmit}
          clearTrigger={clearFormTrigger}
          onClearComplete={() => setClearFormTrigger(false)}
        ></BuildingModel>
      </div>
      {isFloorModalOpen && (
        <div
          className="modal fade show"
          id="floor-model"
          tabIndex="-1"
          role="dialog"
          style={{ display: "block" }}
          aria-hidden="false"
        >
          <FloorModel
            project={project}
            onClose={closeFloorModel}
            onSubmit={handleFloorModelFormSubmit}
            clearTrigger={clearFormTrigger}
            onClearComplete={() => setClearFormTrigger(false)}
          />
        </div>
      )}

      {isWorkAreaModelOpen && (
        <div
          className="modal fade show"
          id="work-area-model"
          tabIndex="-1"
          role="dialog"
          style={{ display: "block" }}
          aria-hidden="false"
        >
          <WorkAreaModel
            project={project}
            onClose={closeWorkAreaModel}
            onSubmit={handleWorkAreaModelFormSubmit}
            clearTrigger={clearFormTrigger}
            onClearComplete={() => setClearFormTrigger(false)}
          />
        </div>
      )}

      {isTaskModelOpen && (
        <div
          className="modal fade show"
          id="task-model"
          tabIndex="-1"
          role="dialog"
          style={{ display: "block" }}
          aria-hidden="false"
        >
          <TaskModel
            project={project}

            onClose={closeTaskModel}
            onSubmit={handleTaskModelFormSubmit}
            clearTrigger={clearFormTrigger}
            onClearComplete={() => setClearFormTrigger(false)}
          />
        </div>
      )}

      {isModalOpen && (
        <ProjectModal modalConfig={modalConfig} closeModal={closeModal} />
      )}

      <div className="col-md-12 col-lg-12 col-xl-12 order-0 mb-4">
        <div className="card">
          <div className="card-body" style={{ padding: "0.5rem" }}>
            <div className="align-items-center">
              <div className="row ">
                <div
                  className={`col-12 text-end mb-1 ${
                    !ManageInfra && "d-none"
                  } `}
                >
                  <button
                    type="button"
                    className="link-button link-button-sm m-1 "
                    onClick={handleShow}
                  >
                    <i className="bx bx-plus-circle me-2"></i>
                    Manage Building
                  </button>
                  <button
                    type="button"
                    className="link-button m-1"
                    onClick={() => openFloorModel()}
                  >
                    <i className="bx bx-plus-circle me-2"></i>
                    Manage Floors
                  </button>
                  <button
                    type="button"
                    className="link-button m-1"
                    onClick={() => openWorkAreaModel()}
                  >
                    <i className="bx bx-plus-circle me-2"></i>
                    Manage Work Areas
                  </button>
                  <button
                    type="button"
                    className="link-button m-1"
                    onClick={() => openTaskModel()}
                  >
                    <i className="bx bx-plus-circle me-2"></i>
                    Create Tasks
                  </button>
                </div>
              </div>
              <div className="row ">
                {loading && <p>Loading....</p>}
                {project && project.buildings?.length > 0 && (
                  <InfraTable
                    buildings={project?.buildings}
                    project={project}
                    handleFloor={submitData}
                  />
                )}
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

export default ProjectInfra;
