import { useState, useEffect, useRef } from "react";
import { useWidgetStore } from "../../../../../store/useWidgetStore";
import ChartComponent from "../../../sidebarLeft/visualization/widgets/ChartComponent";
import RegularDropDown from "../../../../ui/inputs/RegularDropDown";
import { WalletIcon } from "../../../../icons/3dChartIcons";
import SimpleCard from "../../../../ui/realTimeVis/floating/SimpleCard";

interface Widget {
  id: string;
  type?: string;
  panel: "top" | "bottom" | "left" | "right";
  title?: string;
  header?: string;
  fontFamily?: string;
  fontSize?: string;
  fontWeight?: string;
  className?: string;
  data?: {
    labels: string[];
    datasets: {
      data: number[];
      backgroundColor: string;
      borderColor: string;
      borderWidth: number;
    }[];
  };
  value?: string;
  per?: string;
}

interface ChartElement {
  tagName: string;
  className: string;
  textContent: string;
  selector: string;
}

const Design = () => {
  const [selectedFont, setSelectedFont] = useState("drop down");
  const [selectedSize, setSelectedSize] = useState("drop down");
  const [selectedWeight, setSelectedWeight] = useState("drop down");
  const [elementColor, setElementColor] = useState("#6f42c1");
  const [showColorPicker, setShowColorPicker] = useState(false);
  const [chartElements, setChartElements] = useState<ChartElement[]>([]);
  const [selectedElementToStyle, setSelectedElementToStyle] = useState<
    string | null
  >(null);
  const [nameInput, setNameInput] = useState("");
  const chartRef = useRef<HTMLDivElement>(null);

  const { selectedChartId, setSelectedChartId, widgets, setWidgets } =
    useWidgetStore();

  // Initialize name input and extract elements when selectedChartId changes
  useEffect(() => {
    setNameInput(selectedChartId?.header || selectedChartId?.title || "");

    if (!chartRef.current) return;

    const timer = setTimeout(() => {
      const chartContainer = chartRef.current;
      if (!chartContainer) return;

      const elements = Array.from(chartContainer.querySelectorAll("*"))
        .filter((el) => {
          const tagName = el.tagName.toLowerCase();
          return !["script", "style", "meta", "link", "head"].includes(tagName);
        })
        .map((el, index) => {
          const tagName = el.tagName.toLowerCase();
          const className =
            typeof el.className === "string" ? el.className : "";
          const textContent = el.textContent?.trim() || "";

          let selector = tagName;

          if (className && typeof className === "string") {
            const classList = className
              .split(/\s+/)
              .filter((c) => c.length > 0);
            if (classList.length > 0) {
              selector += "." + classList.join(".");
            }
          }

          if (!className || className.trim() === "") {
            const parent = el.parentElement;
            if (parent) {
              const siblings = Array.from(parent.children).filter(
                (child) => child.tagName.toLowerCase() === tagName
              );
              const position = siblings.indexOf(el) + 1;
              selector += `:nth-of-type(${position})`;
            }
          }

          return {
            tagName,
            className,
            textContent,
            selector,
          };
        });

      setChartElements(elements);
    }, 300);

    return () => clearTimeout(timer);
  }, [selectedChartId]);

  const applyStyles = () => {
    if (!selectedElementToStyle || !chartRef.current) return;

    const element = chartRef.current.querySelector(selectedElementToStyle);
    if (!element) return;

    const elementToStyle = element as HTMLElement;

    if (selectedFont !== "drop down") {
      elementToStyle.style.fontFamily = selectedFont;
    }
    if (selectedSize !== "drop down") {
      elementToStyle.style.fontSize = selectedSize;
    }
    if (selectedWeight !== "drop down") {
      elementToStyle.style.fontWeight = selectedWeight.toLowerCase();
    }
    if (elementColor) {
      elementToStyle.style.color = elementColor;
    }
  };

  useEffect(() => {
    applyStyles();
  }, [
    selectedFont,
    selectedSize,
    selectedWeight,
    elementColor,
    selectedElementToStyle,
  ]);

  const handleUpdateWidget = (updatedProperties: Partial<Widget>) => {
    if (!selectedChartId) return;

    const updatedChartId = {
      ...selectedChartId,
      ...updatedProperties,
    };
    setSelectedChartId(updatedChartId);

    const updatedWidgets = widgets.map((widget) =>
      widget.id === selectedChartId.id
        ? { ...widget, ...updatedProperties }
        : widget
    );
    setWidgets(updatedWidgets);
  };

  const handleNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const newName = e.target.value;
    setNameInput(newName);

    if (selectedChartId?.title) {
      handleUpdateWidget({ title: newName });
    } else if (selectedChartId?.header) {
      handleUpdateWidget({ header: newName });
    }
  };

  const defaultChartData = {
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [
      {
        data: [65, 59, 80, 81, 56, 55, 40],
        backgroundColor: "#6f42c1",
        borderColor: "#b392f0",
        borderWidth: 1,
      },
    ],
  };

  const elementOptions = chartElements.map((el) => {
    let displayName = el.tagName;
    if (el.className) displayName += `.${el.className}`;
    if (el.textContent)
      displayName += ` (${el.textContent.substring(0, 20)}${
        el.textContent.length > 20 ? "..." : ""
      })`;
    return {
      display: displayName,
      value: el.selector,
    };
  });

  return (
    <div className="design">
      <div className="selectedWidget">
        {selectedChartId?.title || selectedChartId?.header || "Widget 1"}
      </div>

      <div className="reviewChart" ref={chartRef}>
        {selectedChartId?.title ? (
          <ChartComponent
            type={selectedChartId.type || "bar"}
            title={selectedChartId.title}
            data={selectedChartId.data || defaultChartData}
          />
        ) : (
          <SimpleCard
            header={selectedChartId?.header || ""}
            icon={WalletIcon}
            value={selectedChartId?.value || ""}
            per={selectedChartId?.per || ""}
          />
        )}
      </div>

      <div className="optionsContainer">
        <div className="option">
          <span>Element to Style</span>
          <RegularDropDown
            header={selectedElementToStyle || "Select Element"}
            options={
              elementOptions.length > 0
                ? elementOptions.map((opt) => opt.display)
                : ["No elements found"]
            }
            onSelect={(value) => {
              const selected = elementOptions.find(
                (opt) => opt.display === value
              );
              setSelectedElementToStyle(selected?.value || null);
            }}
          />
        </div>

        <div className="option">
          <span>Name</span>
          <input
            type="text"
            value={nameInput}
            onChange={handleNameChange}
            placeholder="Enter name"
          />
        </div>

        {selectedChartId?.title && (
          <div className="option">
            <span>Chart Type</span>
            <RegularDropDown
              header={selectedChartId?.type || "Select Type"}
              options={["bar", "line", "pie", "doughnut", "radar", "polarArea"]}
              onSelect={(value) => {
                handleUpdateWidget({ type: value });
              }}
            />
          </div>
        )}

        <div className="option">
          <span>Font Family</span>
          <RegularDropDown
            header={selectedChartId?.fontFamily || "Select Font"}
            options={["Arial", "Roboto", "Sans-serif"]}
            onSelect={(value) => setSelectedFont(value)}
          />
        </div>

        <div className="option">
          <span>Size</span>
          <RegularDropDown
            header={selectedChartId?.fontSize || "Select Size"}
            options={["12px", "14px", "16px", "18px"]}
            onSelect={(value) => setSelectedSize(value)}
          />
        </div>

        <div className="option">
          <span>Weight</span>
          <RegularDropDown
            header={selectedChartId?.fontWeight || "Select Weight"}
            options={["Light", "Regular", "Bold"]}
            onSelect={(value) => setSelectedWeight(value)}
          />
        </div>

        <div className="option">
          <div
            className="header"
            onClick={() => setShowColorPicker((prev) => !prev)}
          >
            <span>Element Color</span>
            <div className="icon">▾</div>
          </div>

          {showColorPicker && (
            <div className="colorDisplayer">
              <input
                type="color"
                value={elementColor}
                onChange={(e) => {
                  setElementColor(e.target.value);
                  if (selectedChartId?.data) {
                    handleUpdateWidget({
                      data: {
                        ...selectedChartId.data,
                        datasets: [
                          {
                            ...selectedChartId.data.datasets[0],
                            backgroundColor: e.target.value,
                          },
                        ],
                      },
                    });
                  }
                }}
              />
              <span style={{ marginLeft: "10px" }}>{elementColor}</span>
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

export default Design;
