import React, {
  Suspense,
  lazy,
  useEffect,
  useMemo,
  useRef,
  useState,
} from "react";
import { useReactToPrint } from "react-to-print";
import profile from "../../assets/images/icons/family.svg";
import localImgLoad from "../../lib/localImgLoad";
import usersService from "../../services/UsersService";
import LoadingSpinner from "../Spinners/LoadingSpinner";
import AssignTaskPopout from "./FamilyPopout/AssignTaskPopout";
import FamilyWallet from "./Tabs/FamilyWallet";
import { apiConst } from "../../lib/apiConst";
import { useSelector } from "react-redux";

// Lazy Imports for components
const FamilyWaitlist = lazy(() => import("./Tabs/FamilyWaitlist"));
const FamilyAccount = lazy(() => import("./Tabs/FamilyAccount"));
const FamilyProfile = lazy(() => import("./Tabs/FamilyProfile"));
const FamilyTasks = lazy(() => import("./Tabs/FamilyTasks"));
const ProfileInfo = lazy(() => import("./Tabs/ProfileInfo"));
const FamilyPending = lazy(() => import("./Tabs/FamilyPending"));

export default function FamilyManageTabs({
  className,
  accountDetails,
  listReload,
  loader,
}) {

  const { jobListTable, pendingListTable, parentFamilyTaskList } = useSelector((state) => state.tableReload); // TABLE RELOAD TRIGGERS

  // Initial state for family details
  const initialDetailState = {
    loading: false,
    data: [],
  };

  // State for family details, tasks, waitlist, and pending
  let [familyDetails, setFamilyDetails] = useState({loading: false, data: {}})
  let [familyTasks, setFamilyTasks] = useState({...initialDetailState})
  let [familyWaitList, setFamilyWaitList] = useState({...initialDetailState})
  let [familyPending, setFamilyPending] = useState({...initialDetailState})


  const [updatePage, setUpdatePage] = useState(false) // State to determine when to update the page

  // State for list of created jobs by FULL USER
  const [jobList, setJobList] = useState({ loading: false, data: [] });

  // State for active/selected job
  const [activeTask, setActiveTask] = useState({ id: 0, data: {} });

  // State for family task popout
  const [assignTaskPopout, setAssignTaskPopout] = useState(false);

  let [uploadStatus, setUploadStatus] = useState({loading: false, status: false, message:''}) // HOLDS STATE FOR UPLOAD PROFILE PICTURE STATUS

  // State for profile image
  const [profileImg, setProfileImg] = useState(accountDetails.image ? accountDetails.image : profile);

  // Ref for profile image input
  const profileImgInput = useRef(null);

  // Create an instance of the usersService class
  const apiCall = useMemo(() => new usersService(), []);

  // Function to handle toggling the family task popout
  const familyAssignPopUpHandler = () => {
    setAssignTaskPopout((prev) => !prev);
  };

  // Function to trigger a click on the hidden profile image input
  const browseProfileImg = () => {
    profileImgInput.current.click();
  };

  /**
   * Handles the change event of the profile image input field.
   * Checks if the selected file exceeds the maximum file size limit and displays an alert if it does.
   * If the file is within the size limit, it reads the file using the FileReader API and sets the profile image state with the result.
   */

  const profileImgChangeHandler = (e) => {
    setUploadStatus({loading: false, status: false, message:''})
    let acceptedFormat = ["jpeg", "jpg", "png", "bmp", "gif"] // ARRAY OF SUPPORTED FORMATS
    let uploadedFile = e.target.files[0] //UPLOADED FILE

    const fileFormat = uploadedFile?.type?.split("/")[1]?.toLowerCase();
    if(!acceptedFormat.includes(fileFormat)){ //CHECKING FOR CORRECT UPLOAD FORMAT
      const msg = `Please select ${acceptedFormat.slice(0, -1).join(', ')} or ${acceptedFormat.slice(-1)}`;
      setUploadStatus({loading: false, status: false, message:msg})
      return setTimeout(()=>{
        profileImgInput.current.value = '' // clear the input
        setUploadStatus({loading: false, status: false, message:''})
      },5000)
    }

    if(uploadedFile.size > 5*1048576){ // CHECKING FOR CORRECT FILE SIZE
      setUploadStatus({loading: false, status: false, message:'File must not exceed 5MB'})
      return setTimeout(()=>{
        profileImgInput.current.value = '' // clear the input
        setUploadStatus({loading: false, status: false, message:''})
      },5000)
    }

    if (e.target.value !== "") {
      const imgReader = new FileReader();
      imgReader.onload = (event) => {
        let base64Img = imgReader.result.split(",")[1];
        let reqData = { // PAYLOAD FOR API CALL
          family_uid: accountDetails?.family_uid,
          file_name: uploadedFile?.name,
          file_size: uploadedFile?.size,
          file_type: uploadedFile?.type?.split("/")[0]?.toLowerCase(),
          file_data: base64Img,
          msg_type: 'FILE',
          action: apiConst.WRENCHBOARD_PICTURE_FAMMEMBER
        }
        setUploadStatus({loading: true, status: false, message:'Loading...'})
        apiCall.sendFiles(reqData).then(res=>{
          if(res.status != 200 || res.data.internal_return < 0){
            return setUploadStatus({loading: false, status: false, message: 'Something went wrong, try again'})
          }
          setUploadStatus({loading: false, status: true, message: 'Uploaded successfully'})
          setProfileImg(event.target.result);
        }).catch(error=>{
          setUploadStatus({loading: false, status: false, message: 'Network error, try again'})
        }).finally(()=>{
          setTimeout(()=>{
            setUploadStatus({loading: false, status: false, message: ''})
          },5000)
        })
      };
      imgReader.readAsDataURL(e.target.files[0]);
    }
  };

  // Ref for the account section
  const accountRef = useRef();

  // React-to-Print hook for handling printing
  const useHandlePrint = useReactToPrint({
    content: () => accountRef.current,
  });

  // Array of tab names
  const tabs = [
    { id: 1, name: "Tasks" },
    { id: 2, name: "Waiting" },
    { id: 3, name: "Pending" },
  ];

  // State for the currently selected tab
  const [tab, setTab] = useState(tabs[0].name);

  // Function to handle tab changes
  const tabHandler = (value) => {
    setTab(value);
  };

  // Object that maps tab names to their corresponding components
  const tabComponents = {
    Tasks: (
      <FamilyTasks
        className={className}
        familyData={familyTasks}
        accountDetails={accountDetails}
      />
    ),
    Waiting: (
      <FamilyWaitlist
        familyData={familyWaitList}
        accountDetails={accountDetails}
        setUpdatePage={setUpdatePage}
        jobList={jobList}
        setActiveTask={setActiveTask}
        activeTask={activeTask}
      />
    ),
    Pending: (
      <FamilyPending
        familyData={familyPending}
        accountDetails={accountDetails}
        setUpdatePage={setUpdatePage}
      />
    ),
    Account: (
      <FamilyAccount
        familyData={familyDetails}
        myRef={accountRef}
        handlePrint={useHandlePrint}
      />
    ),
    Profile: <FamilyProfile familyData={familyDetails.data} />,
    wallet: <FamilyWallet familyData={familyDetails.data} />,
  };

  // Default tab component
  const defaultTabComponent = (
    <FamilyTasks
      className={className}
      familyData={familyTasks}
      accountDetails={accountDetails}
    />
  );

  // Selected tab component based on the current 'tab'
  const selectedTabComponent = tabComponents[tab] || defaultTabComponent;

  // Effect to manage family details
  useEffect(() => {
    const manageFamily = async () => {
      setFamilyDetails({loading:true, data: {}})
      try {
        const { family_uid } = accountDetails;
        const reqData = { family_uid };

        const response = await apiCall.ManageFamily(reqData)
        if(response.status != 200 || !response?.data){
          return setFamilyDetails({loading:false, data: {}})
        }
        setFamilyDetails({loading:false, data: response?.data})
      } catch (error) {
        throw new Error(error);
        setFamilyDetails({loading:false, data: {}})
      }
    };
    // Invoke the manageFamily function when the component mounts
    manageFamily();
  }, []);

    // Effect to manage active family task details
    useEffect(() => {
      const manageTasks = async () => {
        setFamilyTasks({loading:true, data: []})
        try {
          const { family_uid } = accountDetails;
          const reqData = { family_uid };
  
          const response = await apiCall.ManageTasks(reqData)
          if(response.status != 200 || !response?.data){
            return setFamilyTasks({loading:false, data: []})
          }
          setFamilyTasks({loading:false, data: response?.data})
        } catch (error) {
          throw new Error(error);
          setFamilyTasks({loading:false, data: []})
        }
      };
      // Invoke the manageFamily function when the component mounts
      manageTasks();
    }, [updatePage, parentFamilyTaskList]);

  // Effect to manage family wait task details
  useEffect(() => {
    const manageFamilyWaitlist = async () => {
      setFamilyWaitList({loading:true, data: []})
      try {
        const response = await apiCall.ManageFamilyWaitlist()
        if(response.status != 200 || !response?.data){
          return setFamilyWaitList({loading:false, data: []})
        }
        setFamilyWaitList({loading:false, data: response?.data})
      } catch (error) {
        throw new Error(error);
        setFamilyWaitList({loading:false, data: []})
      }
    };
    // Invoke the manageFamily function when the component mounts
    manageFamilyWaitlist();
  }, [updatePage]);

    // Effect to manage family pending task details
    useEffect(() => {
      const manageFamilyPending = async () => {
        setFamilyPending({loading:true, data: []})
        try {
          const response = await apiCall.ManageFamilyPending()
          if(response.status != 200 || !response?.data){
            return setFamilyPending({loading:false, data: []})
          }
          setFamilyPending({loading:false, data: response?.data})
        } catch (error) {
          throw new Error(error);
          setFamilyPending({loading:false, data: []})
        }
      };
      // Invoke the manageFamily function when the component mounts
      manageFamilyPending();
    }, [updatePage, pendingListTable]);

  // Effect to get all parent job list
  useEffect(() => {
    const reqData = {
      limit: 30,
      offset: 0,
      job_type: "FAMILY",
      action: apiConst.WRENCHBOARD_PICTURE_FAMMEMBER,
    };

      setJobList({ loading: true });
      apiCall
        .getMyJobList(reqData)
        .then((res) => {
          setJobList({ loading: false, data: res?.data?.result_list });
          if (res?.data?.result_list?.length) {
            setActiveTask((prev) => ({
              ...prev,
              data: res?.data?.result_list[0],
            }));
          }
        })
        .catch((err) => {
          setJobList({ loading: false, data: [] });
          console.log("Error", err);
        });
  }, []);

  return (
    <div
      className={`w-full bg-white dark:bg-dark-white overflow-y-auto rounded-2xl section-shadow h-full ${
        className || ""
      }`}
    >
      <div className="relative w-full sm:rounded-lg overflow-x-auto">
        <Suspense
          fallback={
            <div className="h-full min-h-[609px] w-full overflow-hidden flex justify-center items-center">
              <LoadingSpinner size="16" color="sky-blue" />
            </div>
          }
        >
          <div className="w-full h-full text-sm text-left text-gray-500 dark:text-gray-400 relative grid grid-cols-4 min-h-[575px]">
            <div className="border-r border-[#E3E4FE] dark:border-[#a7a9b533] p-6 h-full flex flex-col justify-between">
              <ProfileInfo
                profileImg={profileImg}
                profileImgInput={profileImgInput}
                profileImgChangeHandler={profileImgChangeHandler}
                browseProfileImg={browseProfileImg}
                accountDetails={accountDetails}
                uploadStatus={uploadStatus}
              />
              <div className="mt-4 flex flex-col justify-center items-center gap-2 lg:flex-row lg:justify-center lg:items-center xl:flex-col xl:justify-center xl:items-center 2xl:flex-row 2xl:justify-center 2xl:items-center 2xl:gap-[2px]">
                <button
                  onClick={() => tabHandler("Account")}
                  className="family-icon p-2 border-2 border-sky-blue rounded-2xl flex flex-col justify-between items-center max-w-[65px] w-full"
                >
                  <img
                    src={localImgLoad("images/icons/account.svg")}
                    className="max-w-[30px]"
                    alt="Settings-Icon"
                  />
                  <p className="text-[16px] text-sky-blue">Acc.</p>
                </button>
                <button
                  onClick={() => tabHandler("Profile")}
                  className="family-icon p-2 border-2 border-sky-blue rounded-2xl flex flex-col justify-between items-center max-w-[65px] w-full"
                >
                  <img
                    src={localImgLoad("images/icons/profile.svg")}
                    className="max-w-[30px]"
                    alt="Settings-Icon"
                  />
                  <p className="text-[16px] text-sky-blue">Profile</p>
                </button>
                <button
                  onClick={() => tabHandler("wallet")}
                  className="family-icon p-2 border-2 border-sky-blue rounded-2xl flex flex-col justify-between items-center max-w-[65px] w-full"
                >
                  <img
                    src={localImgLoad("images/icons/wallet.svg")}
                    className="max-w-[30px]"
                    alt="Settings-Icon"
                  />
                  <p className="text-[16px] text-sky-blue">Wallet</p>
                </button>
              </div>
            </div>
            <div className="col-span-3 h-full w-full">
              <div className="flex flex-col w-full">
                <div className="w-full pr-8 flex items-center gap-1 border-b border-b-[#FAFAF]">
                  <ul className="flex gap-2 items-center w-full">
                    {tabs.map(({ name, id }) => (
                      <li
                        onClick={() => tabHandler(name)}
                        className={`p-4 flex hover:text-purple transition-all ease-in-out items-center cursor-pointer overflow-hidden text-xl relative top-[2px] ${
                          tab === name
                            ? "text-purple border-r"
                            : "text-thin-light-gray"
                        }`}
                        key={id}
                      >
                        <h1>{name}</h1>
                      </li>
                    ))}
                  </ul>
                  <button
                    type="button"
                    onClick={familyAssignPopUpHandler}
                    className="p-1 my-1 w-[100px] flex justify-center items-center btn-gradient text-base rounded-full text-white"
                  >
                    Add task
                  </button>
                </div>

                <div className="flex-[0.9] h-full">
                  <div className="h-full relative overflow-y-auto">
                    <Suspense
                      fallback={<LoadingSpinner size="16" color="sky-blue" />}
                    >
                      {selectedTabComponent}
                    </Suspense>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </Suspense>
      </div>

      {assignTaskPopout && (
        <AssignTaskPopout
          action={familyAssignPopUpHandler}
          situation={assignTaskPopout}
          jobList={jobList}
          setActiveTask={setActiveTask}
          activeTask={activeTask}
          familyDetailsData={familyDetails.data}
          setUpdatePage={setUpdatePage}
        />
      )}
    </div>
  );
}
