"use client";
import type { RootState } from "@/core/redux/store";

import { setLocation, setProjectName, setProjectType, setUnitsOfMeasurement, UnitOption } from "@/core/redux/projectDetails";
import { useAppDispatch, useAppSelector } from "@/core/utils/hooks/useRedux";
import React, { useEffect, useMemo, useState } from "react";
import { useSelector } from "react-redux";

import AnimatedImages from "@/core/components/Icons/AnimatedImages";
import Filter from "@/core/components/Icons/Filter";
import Foundation from "@/core/components/Icons/Foundation";
import Info from "@/core/components/Icons/Info";
import ImgCard from "@/core/components/ImgCard";
import SelectDropdown from "@/core/components/SelectDropdown";
import Image from "next/image";

/* #region types and interfaces */
interface ProjectDetailsProps {
  isShown: boolean;
}

interface ImagesProps {
  uploadedImages: {
    url: string,
    date?: string,
  }[];
}

type Tab = {
  name: string,
  icon: (fill: string) => React.ReactNode,
};

type InputField = {
  label: string,
  value?: { label: string, value: string }[],
  type?: string,
};

type ImageField = {
  name: string,
};
/* #endregion */

/* #region dummy arrays */
const useAppData = () => {
  // Memoize tabs to avoid re-creating icon functions
  const tabs = useMemo(() => [
    { name: "Info", icon: (fill: string | undefined) => <Info fill={fill} /> },
    { name: "Images", icon: (fill: string | undefined) => <AnimatedImages fill={fill} /> },
    { name: "Materials", icon: (fill: string | undefined) => <Foundation fill={fill} /> },
  ], []);

  // Memoize infoFields to avoid re-creating the array on every render
  const infoFields = useMemo(() => [
    { label: "Project name" },
    { label: "Project type" },
    { label: "Location" },
    {
      label: "Units of measurement",
      value: [
        { value: "1", label: "U.S. - inch, foot, mile, pounds" },
        { value: "2", label: "EU - inch, foot, mile, pounds" },
      ],
      type: "dropdown",
    },
  ], []);

  // Memoize materials to avoid re-creating the array on every render
  const materials = useMemo(() => [
    {
      image: "https://picsum.photos/200/300?random=1",
      label: "Wood",
      data: "$630 - 1 pcs.",
    },
    {
      image: "https://picsum.photos/200/300?random=2",
      label: "Metal",
      data: "$630 - 1 pcs.",
    },
    {
      image: "https://picsum.photos/200/300?random=3",
      label: "Plastic",
      data: "$630 - 1 pcs.",
    },
    {
      image: "https://picsum.photos/200/300?random=4",
      label: "Glass",
      data: "$630 - 1 pcs.",
    },
  ], []);

  return { tabs, infoFields, materials };
};
/* #endregion */


const InfoTab = () => {
  const dispatch = useAppDispatch();

  const infoFields = useAppSelector(state => state.projectInfo.infoFields);

  const [isOpenedSelect, setIsOpenedSelect] = useState(false);

  const selectedMeasurement = (infoFields["Units of measurement"] as UnitOption[]).find(
    (unit) => unit.selected
  ) || { label: "", value: "" };

  const handleSelectMeasurement = (item: UnitOption) => {
    dispatch(setUnitsOfMeasurement(item.value));
  };

  const handleFieldChange = (label: string, value: string) => {
    switch (label) {
      case "Project name":
        dispatch(setProjectName(value));
        break;
      case "Project type":
        dispatch(setProjectType(value));
        break;
      case "Location":
        dispatch(setLocation(value));
        break;
      default:
        break;
    }
  };

  return (
    <div className="space-y-4">
      {Object.keys(infoFields).map((label) => (
        <div key={label}>
          <label className="block font-normal text-[12px] leading-[16.8px] text-gray-400 text-sm mb-1">
            {label}
          </label>
          {label === "Units of measurement" ? (
            <div
              className="w-full h-[40px] border select-none border-gray-300 rounded-lg bg-gray-50 cursor-pointer"
              onClick={() => setIsOpenedSelect(!isOpenedSelect)}
            >
              <div className="flex justify-between items-center px-[12px] h-[40px]">
                <SelectDropdown
                  position="bottom"
                  onSelect={handleSelectMeasurement}
                  list={infoFields["Units of measurement"] as UnitOption[]}
                  selected={selectedMeasurement}
                  isOpened={isOpenedSelect}
                  setIsOpened={setIsOpenedSelect}
                  textClasses="text-gray-900 font-normal leading-[16.8px]"
                  textSize="text-xs"
                />
                <Image
                  className={`origin-center transition-transform ${isOpenedSelect ? "rotate-180" : ""}`}
                  src={"/icons/expand_more_bottom.svg"}
                  alt={"expand_more_bottom"}
                  width={16}
                  height={16}
                />
              </div>
            </div>
          ) : (
            <input
              type="text"
              className="w-full h-[40px] p-3 border border-gray-300 rounded-lg bg-gray-50 text-gray-700"
              value={infoFields[label] as string}
              onChange={(e) => handleFieldChange(label, e.target.value)}
            />
          )}
        </div>
      ))}
    </div>
  );
};

const Images: React.FC<ImagesProps> = ({ uploadedImages }) => {

  const [activeImageType, setActiveImageType] = useState<string>("Screenshots");

  return (
    <div>
      {uploadedImages.length > 0 ? (
        <>
          <div className="flex justify-between mb-4">
            {["Screenshots", "Realistic", "360°"].map((option) => (
              <div
                key={option}
                className={`w-[90px] h-[30px] px-[10px] py-[5px] flex justify-center items-center rounded-[5px]
            text-[12px] leading-[14.52px] font-medium cursor-pointer
            ${
              activeImageType === option
                ? "bg-[#FF94241A] text-[#131313]"
                : "border-[1px] border-[#FF94241A] text-[#13131399]"
              }`}
                onClick={() => setActiveImageType(option)}
              >
                {option}
              </div>
            ))}
          </div>
          <div className="space-y-4">
            {uploadedImages.map((image) => {
              return (
              <ImgCard
                key={image.url}
                image={image.url}
                date={image.date ?? ""}
              />)
            })
            }
          </div>
        </>
      ) : (
        <div className="text-center text-[20px] font-semibold">
          No images yet🥲
        </div>
      )}
    </div>
  );
};

const Materials = () => {
  const currentRoom = useAppSelector((state) => state.model.currentRoom);
  const materials = useAppData().materials;

  return (
    <div>
      {materials.length > 0 ? (
        <>
          <div className="flex justify-between mb-4 text-[#131313] font-normal text-[12px] leading-[16.8px]">
            <div className="flex gap-[14px] justify-center items-center font-medium">
              <Image
                src={"/icons/room.svg"}
                alt={"room"}
                width={18}
                height={20}
              />
              {currentRoom?.floor + "/" + currentRoom?.name}
            </div>
            <div className="flex gap-[10px] justify-center items-center">
              <Filter />
              Sort/filter
            </div>
          </div>
          <div className="space-y-4">
            {materials.map((material) => (
              <div
                key={material.label}
                className="h-[60px] flex justify-between items-center pr-[20px] rounded-[5px] bg-[#FF94241A] overflow-hidden"
              >
                <div className="flex items-center gap-[24px]">
                  <div className="relative h-[60px] w-[60px] rounded-[5px] flex justify-center items-center overflow-hidden cursor-pointer">
                    <img src={material.image} alt={material.image} />
                  </div>
                  <div className="m-0 p-0 flex flex-col">
                    <p
                      className="text-[12px] font-normal leading-[16.8px]"
                      style={{ color: "#131313" }}
                    >
                      {material.label}
                    </p>
                    <p
                      className="text-[10px] font-normal leading-[12.1px]"
                      style={{ color: "#13131366" }}
                    >
                      {material.data}
                    </p>
                  </div>
                </div>
                <div
                  style={{
                    width: "5px",
                    height: "10px",
                    backgroundImage: `url('data:image/svg+xml,<svg width="5" height="10" viewBox="0 0 5 10" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M0 10L5 5L0 0V10Z" fill="%23FF9424"/></svg>')`,
                    backgroundRepeat: "no-repeat",
                    backgroundSize: "contain",
                  }}
                />
              </div>
            ))}
          </div>
        </>
      ) : (
        <div className="text-center text-[20px] font-semibold">
          No materials yet🥲
        </div>
      )}
    </div>
  );
};

const ProjectDetails: React.FC<ProjectDetailsProps> = (props) => {
  const [activeTab, setActiveTab] = useState<string>("Info");
  const [isVisible, setIsVisible] = useState(props.isShown);
  const tabs = useAppData().tabs;

  const uploadedImages = useSelector(
    (state: RootState) => state.imageUpload.uploadedImages
  );

  const renderTabContent = (
    uploadedImages: { url: string, date?: string }[]
  ) => {
    switch (activeTab) {
      case "Info":
        return <InfoTab />;
      case "Images":
        return <Images uploadedImages={uploadedImages} />;
      case "Materials":
        return <Materials />;
      default:
        return null;
    }
  };

  useEffect(() => {
    let timeoutId: NodeJS.Timeout;
    if (props.isShown) {
      setIsVisible(true);
    } else {
      timeoutId = setTimeout(() => {
        setIsVisible(false);
      }, 200);
    }
    return () => {
      clearTimeout(timeoutId);
    };
  }, [props.isShown]); //timeout for animation

  return (
    <div
      className="absolute top-[100%] py-[20px] px-[22px] left-0 mt-[10px] w-[376px] p-6 bg-white rounded-xl shadow-lg max-w-md mx-auto"
      style={{
        visibility: isVisible ? "visible" : "hidden",
        transformOrigin: "bottom center",
        opacity: props.isShown ? "1" : "0",
        transition: "opacity 0.15s ease-in-out",
      }}
    >
      <div className="flex justify-between mb-4 bg-orange-100 rounded-lg px-[8px]">
        {tabs.map((tab) => (
          <div
            className={`relative w-[60px] h-[60px] flex flex-col items-center justify-center py-3 rounded-[10px] cursor-pointer`}
            onClick={() => setActiveTab(tab.name)}
            key={tab.name}
          >
            <div
              className={
                "flex flex-col items-center justify-center gap-1 w-full h-full z-[5]"
              }
            >
              <div className="text-lg mb-1">
                {tab.icon(activeTab === tab.name ? "#FFFFFF" : "#131313")}
              </div>
              <p
                className={`text-[12px] leading-[14.52px] font-medium text-${
                  activeTab === tab.name ? "white" : "-[#131313]"
                }`}
              >
                {tab.name}
              </p>
              <div
                className={`absolute inset-0 flex items-center justify-center`}
              >
                <div
                  className={`before:absolute before:-z-[1] before:top-0 before:left-0 before:w-full before:h-full
                  before:transition-transform before:bg-primary-500 before:rounded-[8px]
                  ${activeTab === tab.name
            ? "before:scale-100 before:opacity-100"
            : "before:scale-0"}
                  `}
                />
              </div>
            </div>
          </div>
        ))}
      </div>

      {renderTabContent(uploadedImages)}
      <button className="w-full py-3 mt-6 bg-[#0A1135CC] text-white rounded-lg">
        Save
      </button>
    </div>
  );
};

export default ProjectDetails;
