'use client'

import { FakeWindow, useWindowManager } from "@/hooks/window-manager";
import { Icon } from "@iconify/react";
import clsx from "clsx";
import React, { useState, useRef, useEffect, useReducer } from "react";

export const RestoreWindowsButton = ({ onClick, className, ...props}: React.ComponentProps<"button">) => {
  const windowManager = useWindowManager();

  const isWindowsDataDirty = !windowManager.windows.find(w =>
    w.closed == true
    || w.minimized == true
    || (w.offset.x != 0 && w.offset.y != 0)
  )

  return (
    <button
      className={clsx("bg-primary border border-[#FFA826]", className, isWindowsDataDirty && "hidden")}
      onClick={windowManager.resetAll}
      {...props}
    />
  )
}

export const FakeRelativeWindow = ({
  windowText,
  className,
  draggable,
  withAnim,
  children
}: {
  windowText: string,
  className?: string,
  draggable?: boolean,
  withAnim?: boolean,
  children: React.ReactNode
}) => {
  const windowManager = useWindowManager();
  const windowName = windowText.toLocaleLowerCase();
  const currentWindow = windowManager.get(windowName);

  const [animation, setAnimation] = useState({
    window: "animate-window-popup",
    content: "animate-[fade-in-half_1s]"
  });

  const offsetRef = useRef({ x: 0, y: 0 });
  const [isDragging, setDragging] = useState(false);

  const popupRef = useRef<HTMLDivElement>(null);
  const pos = useRef({
    dragging: false,
    mouseX: 0,
    mouseY: 0,
    x: 0,
    y: 0
  });

  const populateWindow = () => {
    windowManager.add({
      name: windowName,
      closed: false,
      minimized: false,
      offset: { x: 0, y: 0 }
    })
  }

  useEffect(() => {
    populateWindow();
    return () => {
      windowManager.remove(windowName);
    }
  }, []);

  useEffect(() => {
    if (!withAnim) return;
    const node = popupRef.current;
    if (!node) return;
    const observer = new window.IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          setAnimation({
            window: "animate-window-popup",
            content: "animate-[fade-in-half_1s]"
          });
        } else {
          setAnimation({
            window: "scale-x-0 scale-y-[0.03] animate-window-popdown",
            content: "animate-[fade-out-half_1s]"
          });
        }
      },
      { threshold: 0.3 }
    );
    observer.observe(node);
    return () => observer.disconnect();
  }, []);

  useEffect(() => {
    if (popupRef.current && currentWindow) {
      const initPos = {
        x: currentWindow.offset.x,
        y: currentWindow.offset.y
      }
      offsetRef.current.x = initPos.x;
      offsetRef.current.y = initPos.y;
      popupRef.current.style.transform = `translate(${initPos.x}px, ${initPos.y}px)`;
    }
  }, [popupRef.current, currentWindow]);

  const toggleMinimize = () => windowManager.toggleMinimize(windowName);
  const handleClose = () => windowManager.close(windowName);

  const onMouseDown = (e: React.MouseEvent) => {
    if (!draggable || !currentWindow) return;
    if (popupRef.current) {
      pos.current.dragging = true;
      pos.current.mouseX = e.clientX;
      pos.current.mouseY = e.clientY;
      pos.current.x = offsetRef.current.x;
      pos.current.y = offsetRef.current.y;
      document.body.style.userSelect = "none";
      setDragging(true);
    }
    window.addEventListener("mousemove", onMouseMove);
    window.addEventListener("mouseup", onMouseUp);
  };

  const onMouseUp = () => {
    windowManager.move(windowName, {
      x: offsetRef.current.x,
      y: offsetRef.current.y
    });

    pos.current.dragging = false;
    document.body.style.userSelect = "";
    window.removeEventListener("mousemove", onMouseMove);
    window.removeEventListener("mouseup", onMouseUp);
    setDragging(false);
  };

  const onMouseMove = (e: MouseEvent) => {
    if (!currentWindow) return;
    if (pos.current.dragging && popupRef.current) {
      const dx = e.clientX - pos.current.mouseX;
      const dy = e.clientY - pos.current.mouseY;
      const x = pos.current.x + dx;
      const y = pos.current.y + dy;
      offsetRef.current = { x, y }
      popupRef.current.style.transform = `translate(${x}px, ${y}px)`;
    }
  };

  if (!currentWindow || currentWindow?.closed) return

  return (
    <div className={clsx("absolute hidden lg:block", className)}>
      {/* Outline Window */}
      {draggable && (
        <div
          className={clsx("absolute border-primary w-full z-10", isDragging && "md:border")}
          ref={popupRef}
        >
          <div
            className={clsx("hidden md:flex p-2 gap-2 justify-end text-background windowbar", isDragging ? "opacity-0" : "opacity-100")}
            onMouseDown={onMouseDown}
          >
            <button
              className={clsx("bg-primary border border-[#FFA826] border-outset p-1")}
              onClick={toggleMinimize}
            >
              <Icon icon="lucide:minus"/>
            </button>
            <button
              className={clsx("bg-primary border border-[#FFA826] border-outset p-1")}
              onClick={handleClose}
            >
              <Icon icon="lucide:x"/>
            </button>
          </div>
          <div className={clsx("m-1", currentWindow?.minimized && "h-0")}>
            <div className={clsx("md:p-4 opacity-0")}>
              {children}
            </div>
          </div>
        </div>
      )}

      {/* Main window */}
      <div
        className={clsx("md:border bg-background bg-opacity-50 border-primary", withAnim && animation.window)}
        style={{
          transform: `translate(${currentWindow.offset.x}px, ${currentWindow.offset.y}px)`
        }}
      >
        <div className="hidden md:flex bg-primary p-2 justify-between text-background windowbar">
          <div className="ms-1 pointer-events-none">
            {currentWindow ? currentWindow.name : "Error!"}
          </div>
          <div className={clsx("flex gap-2", !isDragging ? "opacity-0" : "opacity-100")}>
            <button
              className="bg-primary border border-[#FFA826] border-outset p-1 pointer-events-none"
            >
              <Icon icon="lucide:minus"/>
            </button>
            <button
              className="bg-primary border border-[#FFA826] border-outset p-1 pointer-events-none"
            >
              <Icon icon="lucide:x"/>
            </button>
          </div>
        </div>
        <div className={clsx("m-1 border border-primary", currentWindow?.minimized ? "h-0 overflow-y-clip" : "h-fit")}>
          <div className={clsx("md:p-4", withAnim && animation.content)}>
            {children}
          </div>
        </div>
      </div>
    </div>
  )
}