"use client";

import { useRef, useState, useEffect } from "react";
import { useUpdateEffect } from "react-use";
import classNames from "classnames";

import { cn } from "@/lib/utils";
import { GridPattern } from "@/components/magic-ui/grid-pattern";
import { useEditor } from "@/hooks/useEditor";
import { useAi } from "@/hooks/useAi";
import { htmlTagToText } from "@/lib/html-tag-to-text";
import { AnimatedBlobs } from "@/components/animated-blobs";
import { AiLoading } from "../ask-ai/loading";
import { defaultHTML } from "@/lib/consts";
import { Button } from "@/components/ui/button";
import { LivePreview } from "../live-preview";
import {
  MousePointerClick,
  History,
  AlertCircle,
  ChevronDown,
  ChevronUp,
} from "lucide-react";
import { api } from "@/lib/api";
import { toast } from "sonner";
import Loading from "@/components/loading";

export const Preview = ({ isNew }: { isNew: boolean }) => {
  const {
    project,
    device,
    isLoadingProject,
    currentTab,
    currentCommit,
    setCurrentCommit,
    currentPageData,
  } = useEditor();
  const {
    isEditableModeEnabled,
    setSelectedElement,
    isAiWorking,
    setIsEditableModeEnabled,
  } = useAi();

  const iframeSrc = project?.space_id
    ? `/api/proxy/?spaceId=${encodeURIComponent(project.space_id)}${
        currentCommit ? `&commitId=${currentCommit}` : ""
      }`
    : "";

  const iframeRef = useRef<HTMLIFrameElement>(null);
  const [hoveredElement, setHoveredElement] = useState<{
    tagName: string;
    rect: { top: number; left: number; width: number; height: number };
  } | null>(null);
  const [isHistoryNotificationCollapsed, setIsHistoryNotificationCollapsed] =
    useState(false);
  const [isPromotingVersion, setIsPromotingVersion] = useState(false);

  // Handle PostMessage communication with iframe
  useEffect(() => {
    const handleMessage = (event: MessageEvent) => {
      // Verify origin for security
      if (!event.origin.includes(window.location.origin)) {
        return;
      }

      const { type, data } = event.data;
      switch (type) {
        case "PROXY_SCRIPT_READY":
          if (iframeRef.current?.contentWindow) {
            iframeRef.current.contentWindow.postMessage(
              {
                type: isEditableModeEnabled
                  ? "ENABLE_EDIT_MODE"
                  : "DISABLE_EDIT_MODE",
              },
              "*"
            );
          }
          break;
        case "ELEMENT_HOVERED":
          if (isEditableModeEnabled) {
            setHoveredElement(data);
          }
          break;
        case "ELEMENT_MOUSE_OUT":
          if (isEditableModeEnabled) {
            setHoveredElement(null);
          }
          break;
        case "ELEMENT_CLICKED":
          if (isEditableModeEnabled) {
            const mockElement = {
              tagName: data.tagName,
              getBoundingClientRect: () => data.rect,
              outerHTML: data.element,
            };
            setSelectedElement(mockElement as any);
            setIsEditableModeEnabled(false);
          }
          break;
        case "NAVIGATE_TO_PROXY":
          // Handle navigation within the iframe while maintaining proxy context
          if (iframeRef.current && data.proxyUrl) {
            iframeRef.current.src = data.proxyUrl;
          }
          break;
      }
    };

    window.addEventListener("message", handleMessage);
    return () => window.removeEventListener("message", handleMessage);
  }, [setSelectedElement, isEditableModeEnabled]);

  // Send edit mode state to iframe and clear hover state when disabled
  useUpdateEffect(() => {
    if (iframeRef.current?.contentWindow) {
      iframeRef.current.contentWindow.postMessage(
        {
          type: isEditableModeEnabled
            ? "ENABLE_EDIT_MODE"
            : "DISABLE_EDIT_MODE",
        },
        "*"
      );
    }

    // Clear hover state when edit mode is disabled
    if (!isEditableModeEnabled) {
      setHoveredElement(null);
    }
  }, [isEditableModeEnabled, project?.space_id]);

  const promoteVersion = async () => {
    setIsPromotingVersion(true);
    await api
      .post(
        `/me/projects/${project?.space_id}/commits/${currentCommit}/promote`
      )
      .then((res) => {
        if (res.data.ok) {
          setCurrentCommit(null);
          toast.success("Version promoted successfully");
        }
      })
      .catch((err) => {
        toast.error(err.response.data.error);
      });
    setIsPromotingVersion(false);
  };

  return (
    <div
      className={classNames(
        "bg-neutral-900/30 w-full h-[calc(100dvh-57px)] flex flex-col items-center justify-center relative z-1 lg:border-l border-neutral-800",
        {
          "max-lg:h-0": currentTab === "chat",
          "max-lg:h-full": currentTab === "preview",
        }
      )}
    >
      <GridPattern
        x={-1}
        y={-1}
        strokeDasharray={"4 2"}
        className={cn(
          "[mask-image:radial-gradient(900px_circle_at_center,white,transparent)] opacity-40"
        )}
      />
      {!isAiWorking && hoveredElement && isEditableModeEnabled && (
        <div
          className="cursor-pointer absolute bg-sky-500/10 border-[2px] border-dashed border-sky-500 rounded-r-lg rounded-b-lg p-3 z-10 pointer-events-none"
          style={{
            top: hoveredElement.rect.top,
            left: hoveredElement.rect.left,
            width: hoveredElement.rect.width,
            height: hoveredElement.rect.height,
          }}
        >
          <span className="bg-sky-500 rounded-t-md text-sm text-neutral-100 px-2 py-0.5 -translate-y-7 absolute top-0 left-0">
            {htmlTagToText(hoveredElement.tagName.toLowerCase())}
          </span>
        </div>
      )}
      {isNew && !isAiWorking ? (
        <iframe
          className={classNames(
            "w-full select-none transition-all duration-200 bg-black h-full",
            {
              "lg:max-w-md lg:mx-auto lg:!rounded-[42px] lg:border-[8px] lg:border-neutral-700 lg:shadow-2xl lg:h-[80dvh] lg:max-h-[996px]":
                device === "mobile",
            }
          )}
          srcDoc={defaultHTML}
        />
      ) : iframeSrc === "" ||
        isLoadingProject ||
        (isAiWorking && iframeSrc == "") ? (
        <div className="w-full h-full flex items-center justify-center relative">
          <div className="py-10 w-full relative z-1 max-w-3xl mx-auto text-center">
            <AiLoading
              text={
                isAiWorking && iframeSrc === ""
                  ? undefined
                  : "Fetching your space..."
              }
              className="flex-col"
            />
            <AnimatedBlobs />
            <AnimatedBlobs />
          </div>
          <LivePreview
            currentPageData={currentPageData}
            isAiWorking={isAiWorking}
            defaultHTML={defaultHTML}
            className="bottom-4 left-4"
          />
        </div>
      ) : (
        <>
          <iframe
            id="preview-iframe"
            ref={iframeRef}
            className={classNames(
              "w-full select-none transition-all duration-200 bg-black h-full",
              {
                "lg:max-w-md lg:mx-auto lg:!rounded-[42px] lg:border-[8px] lg:border-neutral-700 lg:shadow-2xl lg:h-[80dvh] lg:max-h-[996px]":
                  device === "mobile",
              }
            )}
            src={iframeSrc}
            allow="accelerometer; ambient-light-sensor; autoplay; battery; camera; clipboard-read; clipboard-write; display-capture; document-domain; encrypted-media; fullscreen; geolocation; gyroscope; layout-animations; legacy-image-formats; magnetometer; microphone; midi; oversized-images; payment; picture-in-picture; publickey-credentials-get; serial; sync-xhr; usb; vr ; wake-lock; xr-spatial-tracking"
          />
          <div
            className={classNames(
              "absolute bottom-4 left-4 z-10 bg-white/95 backdrop-blur-sm border border-neutral-200 rounded-xl shadow-lg transition-all duration-300 ease-in-out",
              {
                hidden: !currentCommit,
              }
            )}
          >
            {isHistoryNotificationCollapsed ? (
              // Collapsed state
              <div className="flex items-center gap-2 p-3">
                <History className="size-4 text-neutral-600" />
                <span className="text-xs text-neutral-600 font-medium">
                  Historical Version
                </span>
                <Button
                  variant="outline"
                  size="iconXs"
                  className="!rounded-md !border-neutral-200"
                  onClick={() => setIsHistoryNotificationCollapsed(false)}
                >
                  <ChevronUp className="text-neutral-400 size-3" />
                </Button>
              </div>
            ) : (
              // Expanded state
              <div className="p-4 max-w-sm w-full">
                <div className="flex items-start gap-3">
                  <History className="size-4 text-neutral-600 translate-y-1.5" />
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center justify-between mb-1">
                      <div className="flex items-center gap-2">
                        <p className="font-semibold text-sm text-neutral-800">
                          Historical Version
                        </p>
                      </div>
                      <Button
                        variant="outline"
                        size="iconXs"
                        className="!rounded-md !border-neutral-200"
                        onClick={() => setIsHistoryNotificationCollapsed(true)}
                      >
                        <ChevronDown className="text-neutral-400 size-3" />
                      </Button>
                    </div>
                    <p className="text-xs text-neutral-600 leading-relaxed mb-3">
                      You're viewing a previous version of this project. Promote
                      this version to make it current and deploy it live.
                    </p>
                    <div className="flex items-center gap-2">
                      <Button
                        size="xs"
                        variant="black"
                        className="!pr-3"
                        onClick={() => promoteVersion()}
                        disabled={isPromotingVersion}
                      >
                        {isPromotingVersion ? (
                          <Loading overlay={false} />
                        ) : (
                          <MousePointerClick className="size-3" />
                        )}
                        Promote Version
                      </Button>
                      <Button
                        size="xs"
                        variant="outline"
                        className=" !text-neutral-600 !border-neutral-200"
                        disabled={isPromotingVersion}
                        onClick={() => setCurrentCommit(null)}
                      >
                        Go back to current
                      </Button>
                    </div>
                  </div>
                </div>
              </div>
            )}
          </div>
        </>
      )}
    </div>
  );
};
