/**
 * @fileoverview React component for PlaygroundEditor.jsx
 * 
 * @module pages.Playground.components.PlaygroundEditor
 */

import React, {
  useEffect,
  useRef,
  useCallback,
  useMemo,
  useState,
} from "react";
import * as Blockly from "blockly/core";
import {
  Download,
  Upload,
  Play,
  Loader,
  CircleAlert,
  BookOpen,
  HelpCircle,
} from "lucide-react";
import { playgroundToolbox } from "../config/playgroundToolbox";
import { defaultWorkspace } from "../config/defaultWorkspace";
import {
  loadWorkspace,
  createDebouncedSave,
} from "../services/playgroundStorage";
import { useIsMobile } from "../../../hooks/useIsMobile";
import ExamplesModal from "./ExamplesModal";
import "./PlaygroundEditor.css";

// Tema claro personalizado
const lightTheme = Blockly.Theme.defineTheme("light", {
  base: Blockly.Themes.Classic,
  componentStyles: {
    workspaceBackgroundColour: "#f9fafb",
    toolboxBackgroundColour: "#e5e7eb",
    toolboxForegroundColour: "#374151",
    flyoutBackgroundColour: "#f3f4f6",
    flyoutForegroundColour: "#111827",
    flyoutOpacity: 0.95,
    scrollbarColour: "#9ca3af",
    scrollbarOpacity: 0.5,
  },
});

// Tema escuro personalizado
const darkTheme = Blockly.Theme.defineTheme("dark", {
  base: Blockly.Themes.Classic,
  componentStyles: {
    workspaceBackgroundColour: "#1e1e1e",
    toolboxBackgroundColour: "#252526",
    toolboxForegroundColour: "#cccccc",
    flyoutBackgroundColour: "#2d2d30",
    flyoutForegroundColour: "#ffffff",
    flyoutOpacity: 0.95,
    scrollbarColour: "#6b7280",
    scrollbarOpacity: 0.5,
  },
});

const PlaygroundEditor = ({
  onWorkspaceChange,
  onDownloadWorkspace,
  onUploadWorkspace,
  onRunCode,
  onHelp,
  isRunning,
  blockCount = 0,
  theme = "light",
}) => {
  const blocklyDiv = useRef(null);
  const workspaceRef = useRef(null);
  const isInitializedRef = useRef(false);
  const isMobile = useIsMobile();
  const debouncedSave = useMemo(() => createDebouncedSave(1000), []);
  const [showExamples, setShowExamples] = useState(false);
  const [isVisible, setIsVisible] = useState(true);

  // Monitorar visibilidade da página
  useEffect(() => {
    const handleVisibilityChange = () => {
      const visible = !document.hidden;
      setIsVisible(visible);

      if (visible && workspaceRef.current) {
        // Forçar resize quando a página voltar a ficar visível
        requestAnimationFrame(() => {
          if (workspaceRef.current) {
            Blockly.svgResize(workspaceRef.current);
          }
        });
      }
    };

    document.addEventListener("visibilitychange", handleVisibilityChange);
    return () =>
      document.removeEventListener("visibilitychange", handleVisibilityChange);
  }, []);

  // Forçar resize quando isVisible mudar
  useEffect(() => {
    if (isVisible && workspaceRef.current) {
      const timer = setTimeout(() => {
        if (workspaceRef.current) {
          Blockly.svgResize(workspaceRef.current);
        }
      }, 100);
      return () => clearTimeout(timer);
    }
  }, [isVisible]);

  /**
   * Debounced save e notificação externa quando a workspace muda.
   * Persiste a workspace localmente e chama `onWorkspaceChange` se fornecido.
   *
   * @function handleWorkspaceChange
   * @returns {void}
   */
  const handleWorkspaceChange = useCallback(() => {
    if (!workspaceRef.current) return;

    debouncedSave(workspaceRef.current);

    if (onWorkspaceChange) {
      onWorkspaceChange(workspaceRef.current);
    }
  }, [onWorkspaceChange, debouncedSave]);

  useEffect(() => {
    if (isInitializedRef.current || !blocklyDiv.current) return;

    isInitializedRef.current = true;

    const toolboxWithIcons = {
      ...playgroundToolbox,
      contents: playgroundToolbox.contents.map((cat) => ({
        ...cat,
        "css-icon": cat.cssIcon || "fa fa-cube",
      })),
    };

    workspaceRef.current = Blockly.inject(blocklyDiv.current, {
      toolbox: toolboxWithIcons,
      theme: theme === "light" ? lightTheme : darkTheme,
      grid: {
        spacing: 25,
        length: 3,
        colour: theme === "light" ? "#ccc" : "#3a3a3a",
        snap: true,
      },
      zoom: {
        controls: false,
        wheel: true,
        startScale: 1.0,
        maxScale: 3,
        minScale: 0.3,
        scaleSpeed: 1.2,
      },
      trashcan: true,
      scrollbars: true,
      renderer: "zelos",
    });

    const savedData = loadWorkspace();
    const workspaceToLoad = savedData || defaultWorkspace;

    try {
      Blockly.serialization.workspaces.load(
        workspaceToLoad,
        workspaceRef.current,
      );
    } catch (error) {
      console.error("Erro ao carregar workspace:", error);
      // Se falhar, tenta carregar o workspace padrão
      try {
        Blockly.serialization.workspaces.load(
          defaultWorkspace,
          workspaceRef.current,
        );
      } catch (fallbackError) {
        console.error("Erro ao carregar workspace padrão:", fallbackError);
      }
    }

    handleWorkspaceChange();

    const listener = (event) => {
      if (event.isUiEvent) return;
      handleWorkspaceChange();
    };

    workspaceRef.current.addChangeListener(listener);

    // Fazer zoom para ajustar todos os blocos na tela (especialmente útil em mobile)
    setTimeout(() => {
      if (workspaceRef.current && isMobile) {
        const metrics = workspaceRef.current.getMetrics();
        if (metrics) {
          // Calcular escala para caber todos os blocos
          workspaceRef.current.zoomToFit();
        }
      }
    }, 200);

    // Adicionar ResizeObserver para garantir que o workspace se redimensione corretamente
    const resizeObserver = new ResizeObserver(() => {
      if (workspaceRef.current) {
        Blockly.svgResize(workspaceRef.current);
      }
    });

    if (blocklyDiv.current) {
      resizeObserver.observe(blocklyDiv.current);
    }

    // Listener para quando a página voltar a ficar visível (alt+tab, mudança de aba)
    const handleVisibilityChange = () => {
      if (!document.hidden && workspaceRef.current) {
        // Pequeno delay para garantir que o layout está estável
        setTimeout(() => {
          if (workspaceRef.current) {
            Blockly.svgResize(workspaceRef.current);
          }
        }, 50);
      }
    };

    // Listener para quando a janela receber foco novamente
    const handleWindowFocus = () => {
      if (workspaceRef.current) {
        setTimeout(() => {
          if (workspaceRef.current) {
            Blockly.svgResize(workspaceRef.current);
          }
        }, 50);
      }
    };

    // Listener para resize da janela
    const handleWindowResize = () => {
      if (workspaceRef.current) {
        Blockly.svgResize(workspaceRef.current);
      }
    };

    document.addEventListener("visibilitychange", handleVisibilityChange);
    window.addEventListener("focus", handleWindowFocus);
    window.addEventListener("resize", handleWindowResize);

    // Forçar um resize inicial após um pequeno delay
    setTimeout(() => {
      if (workspaceRef.current) {
        Blockly.svgResize(workspaceRef.current);
      }
    }, 100);

    return () => {
      resizeObserver.disconnect();
      document.removeEventListener("visibilitychange", handleVisibilityChange);
      window.removeEventListener("focus", handleWindowFocus);
      window.removeEventListener("resize", handleWindowResize);
      if (workspaceRef.current) {
        workspaceRef.current.dispose();
        workspaceRef.current = null;
      }
    };
  }, [handleWorkspaceChange]);

  // Efeito para trocar o tema do Blockly dinamicamente
  useEffect(() => {
    if (!workspaceRef.current) return;

    const newTheme = theme === "light" ? lightTheme : darkTheme;
    workspaceRef.current.setTheme(newTheme);

    // Atualizar a cor do grid
    const gridColour = theme === "light" ? "#ccc" : "#3a3a3a";
    workspaceRef.current.getTheme().componentStyles.gridColour = gridColour;

    // Forçar atualização visual
    workspaceRef.current.refreshTheme();
  }, [theme]);

  const naoTemBlocos = blockCount === 0;

  /**
   * Carrega um exemplo de workspace no editor.
   * Substitui o workspace atual pelo exemplo fornecido e ajusta o zoom.
   *
   * @function handleLoadExample
   * @param {Object} exampleData - Dados serializados do exemplo (workspace)
   * @returns {void}
   */
  const handleLoadExample = useCallback(
    (exampleData) => {
      if (!workspaceRef.current) return;

      try {
        // Limpar workspace atual
        workspaceRef.current.clear();

        // Carregar o exemplo
        Blockly.serialization.workspaces.load(
          exampleData,
          workspaceRef.current,
        );

        // Fazer zoom para ajustar todos os blocos na tela (especialmente útil em mobile)
        setTimeout(() => {
          if (workspaceRef.current && isMobile) {
            workspaceRef.current.zoomToFit();
          }
        }, 150);

        // Notificar mudança
        handleWorkspaceChange();
      } catch (error) {
        console.error("Erro ao carregar exemplo:", error);
        alert("Erro ao carregar exemplo. Tente novamente.");
      }
    },
    [handleWorkspaceChange, isMobile],
  );

  /**
   * Retorna as classes CSS para o botão de executar dependendo do estado.
   * Usa `isMobile`, `isRunning` e `blockCount` para decidir estilos/estado.
   *
   * @function getRunButtonClasses
   * @returns {string} Classes CSS para aplicação ao botão
   */
  const getRunButtonClasses = () => {
    const baseClasses = `flex items-center gap-2 ${isMobile ? "px-3 py-3" : "px-6 py-3"} rounded-full text-sm font-medium transition-all duration-200 shadow-md hover:shadow-lg`;

    if (naoTemBlocos) {
      return `${baseClasses} bg-gray-300 text-black cursor-not-allowed`;
    }

    if (isRunning) {
      return `${baseClasses} bg-[var(--action-green)] hover:bg-[rgb(235_119_63/1)] text-white`;
    }

    return `${baseClasses} bg-green-100 hover:bg-green-200 text-black`;
  };

  return (
    <div className="playground-editor-container" data-tour="blockly-editor">
      <div
        className={`flex gap-3 p-3 border-b-2 border-transparent border-highlight ${
          theme === "light"
            ? "bg-gradient-to-br from-gray-50 to-gray-200"
            : "bg-gradient-to-br from-[#252526] to-[#1e1e1e]"
        }`}
        data-tour="toolbar"
      >
        <button
          onClick={onRunCode}
          className={getRunButtonClasses()}
          disabled={naoTemBlocos && !isRunning}
          data-tour="run-button"
          title={
            isRunning
              ? "Executando..."
              : naoTemBlocos
                ? "Adicione blocos para executar"
                : "Executar"
          }
        >
          {isRunning ? (
            <>
              <Loader className="w-4 h-4 animate-spin" />
              {!isMobile && <span>Executando...</span>}
            </>
          ) : naoTemBlocos ? (
            <>
              <CircleAlert className="w-4 h-4" />
              {!isMobile && <span>Adicione blocos para executar</span>}
            </>
          ) : (
            <>
              <Play className="w-4 h-4" />
              {!isMobile && <span>Executar</span>}
            </>
          )}
        </button>

        <button
          onClick={onDownloadWorkspace}
          className={`flex items-center gap-2 ${isMobile ? "px-3 py-3" : "px-6 py-3"} bg-green-100 text-black rounded-full text-sm font-medium transition-all duration-200 shadow-md hover:bg-green-200`}
          title="Salvar blocos do workspace"
          data-tour="download-button"
        >
          <Download className="w-4 h-4" />
          {!isMobile && <span>Salvar Blocos</span>}
        </button>

        <button
          onClick={onUploadWorkspace}
          className={`flex items-center gap-2 ${isMobile ? "px-3 py-3" : "px-6 py-3"} bg-green-100 text-black rounded-full text-sm font-medium transition-all duration-200 shadow-md hover:bg-green-200`}
          title="Carregar blocos salvos"
          data-tour="upload-button"
        >
          <Upload className="w-4 h-4" />
          {!isMobile && <span>Carregar Blocos</span>}
        </button>

        <button
          onClick={() => setShowExamples(true)}
          className={`flex items-center gap-2 ${isMobile ? "px-3 py-3" : "px-6 py-3"} bg-green-100 text-black rounded-full text-sm font-medium transition-all duration-200 shadow-md hover:bg-green-200`}
          data-tour="examples-button"
          title="Ver exemplos de código"
        >
          <BookOpen className="w-4 h-4" />
          {!isMobile && <span>Exemplos</span>}
        </button>

        {isMobile && onHelp && (
          <button
            onClick={onHelp}
            className={`flex items-center justify-center px-3 py-3 rounded-full text-sm font-medium transition-all duration-200 shadow-md hover:shadow-lg hover:-translate-y-0.5 active:translate-y-0 ${
              theme === "light"
                ? "bg-gray-200 hover:bg-gray-300 text-gray-800"
                : "bg-gray-700 hover:bg-gray-600 text-white"
            }`}
            data-tour="help-button"
            title="Ajuda - Tour guiado"
          >
            <HelpCircle className="w-4 h-4" />
          </button>
        )}
      </div>
      <div ref={blocklyDiv} className="playground-editor" />

      <ExamplesModal
        isOpen={showExamples}
        onClose={() => setShowExamples(false)}
        onSelectExample={handleLoadExample}
      />
    </div>
  );
};

export default PlaygroundEditor;
