import {
  createSignal,
  createMemo,
  onMount,
  Show,
  For,
  type Component,
} from "solid-js";
import { Dynamic } from "solid-js/web";
import type { WidgetConfig } from "../types/widget";
import { WidgetRenderer } from "./WidgetRenderer";
import { WidgetConfigurator } from "./WidgetConfigurator";
import { GridConfigurator } from "./GridConfigurator";
import { TabletPreview } from "./TabletPreview";
import { getGrid } from "../grids/registry";
import type { DashboardGridConfig } from "../types/grid";

export const Dashboard: Component = () => {
  const [widgets, setWidgets] = createSignal<WidgetConfig[]>([]);
  const [previewUrl, setPreviewUrl] = createSignal<string>("");
  const [shortLink, setShortLink] = createSignal<string>("");
  const [showUrlModal, setShowUrlModal] = createSignal(false);
  const [gridConfig, setGridConfig] = createSignal<DashboardGridConfig>({
    templateId: null,
    widgetPlacements: [],
  });
  const [hoveredCellId, setHoveredCellId] = createSignal<string | null>(null);
  const [isDraggingAny, setIsDraggingAny] = createSignal(false);

  const isSmallScreen = () =>
    typeof window !== "undefined" && window.matchMedia("(max-width: 968px)").matches;

  const previewScale = createMemo(() => {
    const grid = gridConfig().templateId
      ? getGrid(gridConfig().templateId!)
      : null;
    if (!grid) return 1;

    const gridWidth = grid.template.width || 800;
    const gridHeight = grid.template.height || 600;

    const containerWidth = isSmallScreen()
      ? window.innerWidth - 40
      : window.innerWidth - 450 - 140;
    const containerHeight = window.innerHeight * 0.85 - 80;

    const scaleX = containerWidth / gridWidth;
    const scaleY = containerHeight / gridHeight;

    return Math.min(scaleX, scaleY, 1) * 0.9;
  });

  const handleAddWidget = (config: WidgetConfig) => {
    if (!config.position) {
      config.position = { x: 10, y: 10 };
    }
    setWidgets((prev) => [...prev, config]);
    saveToLocalStorage([...widgets(), config]);
  };

  const handleRemoveWidget = (id: string) => {
    const updated = widgets().filter((w) => w.id !== id);
    setWidgets(updated);
    saveToLocalStorage(updated);
  };

  const handleWidgetPositionUpdate = (
    id: string,
    position: { x: number; y: number },
  ) => {
    const updated = widgets().map((w) =>
      w.id === id ? { ...w, position } : w,
    );
    setWidgets(updated);
    saveToLocalStorage(updated);
  };

  const handleWidgetSizeUpdate = (
    id: string,
    size: { width: number; height: number },
  ) => {
    const updated = widgets().map((w) => (w.id === id ? { ...w, size } : w));
    setWidgets(updated);
    saveToLocalStorage(updated);
  };

  const handleExport = () => {
    const exportData = {
      widgets: widgets(),
      grid: gridConfig(),
    };
    const data = JSON.stringify(exportData, null, 2);
    const blob = new Blob([data], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = "dashboard-config.json";
    a.click();
    URL.revokeObjectURL(url);
  };

  const handleImport = (e: Event) => {
    const input = e.target as HTMLInputElement;
    const file = input.files?.[0];
    if (file) {
      const reader = new FileReader();
      reader.onload = (event) => {
        try {
          const config = JSON.parse(event.target?.result as string);
          if (Array.isArray(config)) {
            // Old format
            setWidgets(config);
            saveToLocalStorage(config);
          } else {
            // New format
            if (config.widgets) {
              setWidgets(config.widgets);
              saveToLocalStorage(config.widgets);
            }
            if (config.grid) {
              setGridConfig(config.grid);
              saveGridToLocalStorage(config.grid);
            }
          }
        } catch (err) {
          alert("Error parsing config file");
        }
      };
      reader.readAsText(file);
    }
  };

  const handleGeneratePreviewUrl = async () => {
    const exportData = {
      widgets: widgets(),
      grid: gridConfig(),
    };
    const config = encodeURIComponent(JSON.stringify(exportData));
    const url = `${window.location.origin}/app/preview?config=${config}`;
    setPreviewUrl(url);

    // Generate short link
    try {
      const response = await fetch("/api/generate-link", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ url }),
      });
      const data = await response.json();
      if (data.shortLink) {
        setShortLink(data.shortLink);
      }
    } catch (error) {
      console.error("Error generating short link:", error);
      setShortLink("");
    }

    setShowUrlModal(true);
  };

  const copyToClipboard = () => {
    navigator.clipboard.writeText(previewUrl());
    alert("URL copied to clipboard!");
  };

  const copyShortLinkToClipboard = () => {
    navigator.clipboard.writeText(shortLink());
    alert("Short link copied to clipboard!");
  };

  const handleSelectGrid = (templateId: string | null) => {
    setGridConfig({
      templateId,
      widgetPlacements: [],
    });
    saveGridToLocalStorage({ templateId, widgetPlacements: [] });
  };

  const handleWidgetSnap = (widgetId: string, cellId: string | null) => {
    const updated = { ...gridConfig() };
    updated.widgetPlacements = updated.widgetPlacements.filter(
      (p) => p.widgetId !== widgetId,
    );
    if (cellId) {
      updated.widgetPlacements.push({ widgetId, cellId });
    }
    setGridConfig(updated);
    saveGridToLocalStorage(updated);
  };

  const handleCellHover = (cellId: string | null) => {
    setHoveredCellId(cellId);
  };

  const handleDragStateChange = (isDragging: boolean) => {
    setIsDraggingAny(isDragging);
    if (!isDragging) {
      setHoveredCellId(null);
    }
  };

  const saveToLocalStorage = (config: WidgetConfig[]) => {
    localStorage.setItem("dashboard-config", JSON.stringify(config));
  };

  const saveGridToLocalStorage = (config: DashboardGridConfig) => {
    localStorage.setItem("dashboard-grid-config", JSON.stringify(config));
  };

  onMount(() => {
    const saved = localStorage.getItem("dashboard-config");
    if (saved) {
      try {
        setWidgets(JSON.parse(saved));
      } catch (err) {
        console.error("Error loading saved config", err);
      }
    } else {
      // First run: start with a clock widget.
      const initial: WidgetConfig[] = [
        {
          id: "clock-1",
          type: "clock",
          position: { x: 10, y: 10 },
          size: { width: 200, height: 100 },
          settings: {},
        },
      ];
      setWidgets(initial);
      saveToLocalStorage(initial);
    }

    const savedGrid = localStorage.getItem("dashboard-grid-config");
    if (savedGrid) {
      try {
        setGridConfig(JSON.parse(savedGrid));
      } catch (err) {
        console.error("Error loading saved grid config", err);
      }
    }
  });

  return (
    <div>
      <style>{`
        @media (max-width: 968px) {
          .dashboard-panels {
            grid-template-columns: 1fr !important;
          }
        }
      `}</style>
      <header
        style={{
          "margin-bottom": "2rem",
          "border-bottom": "1px solid var(--border)",
          "padding-bottom": "1rem",
        }}
      >
        <h1 style={{ "margin-bottom": "0.5rem" }}>
          <i>
            <a style={{ color: "white" }} href="/">
              glance
            </a>
          </i>
        </h1>
        <div style={{ display: "flex", gap: "0.5rem" }}>
          <button onClick={handleExport}>Export Config</button>
          <label
            style={{
              border: "1px solid var(--border)",
              padding: "0.5rem 1rem",
              cursor: "pointer",
              display: "inline-block",
            }}
          >
            Import Config
            <input
              type="file"
              accept=".json"
              onChange={handleImport}
              style={{ display: "none" }}
            />
          </label>
          <button onClick={handleGeneratePreviewUrl}>
            Generate Fullscreen Link
          </button>
        </div>
      </header>

      <GridConfigurator
        onSelectGrid={handleSelectGrid}
        currentGridId={gridConfig().templateId}
      />

      <WidgetConfigurator onAddWidget={handleAddWidget} />

      <div style={{ "margin-top": "2rem" }}>
        <h2 style={{ "margin-bottom": "1rem" }}>
          Dashboard Preview ({widgets().length} widgets)
        </h2>
        <div
          style={{
            display: "grid",
            "grid-template-columns": "1fr 450px",
            gap: "1.5rem",
            "min-height": "85vh",
          }}
          class="dashboard-panels"
        >
          {/* Interactive Editor Panel */}
          <div
            style={{
              border: "1px solid var(--border)",
              padding: "20px",
              position: "relative",
              background: "var(--bg, #fff)",
              overflow: "hidden",
              display: "flex",
              "align-items": "center",
              "justify-content": "center",
              cursor: "pointer",
            }}
          >
            <div
              data-grid-container
              style={{
                position: "relative",
                width: gridConfig().templateId
                  ? `${getGrid(gridConfig().templateId!)?.template.width || 800}px`
                  : "100%",
                height: gridConfig().templateId
                  ? `${getGrid(gridConfig().templateId!)?.template.height || 600}px`
                  : "100%",
                transform: `scale(${previewScale()})`,
                "transform-origin": "center center",
                "flex-shrink": "0",
              }}
            >
              {/* Render grid template if selected */}
              <Show when={gridConfig().templateId}>
                {/* @ts-ignore */}
                {() => {
                  const grid = getGrid(gridConfig().templateId!);
                  return grid ? <Dynamic component={grid.Component} /> : null;
                }}
              </Show>

              {/* Grid cell highlights - Enhanced snap zones with visual feedback */}
              <Show when={isDraggingAny() && gridConfig().templateId}>
                {/* @ts-ignore */}
                {() => {
                  const grid = getGrid(gridConfig().templateId!);
                  return (
                    <For each={grid?.template.cells || []}>
                      {(cell) => {
                        const isHovered = hoveredCellId() === cell.id;
                        return (
                          <div
                            data-cell-highlight={cell.id}
                            style={{
                              position: "absolute",
                              left: `${cell.x}px`,
                              top: `${cell.y}px`,
                              width: `${cell.width}px`,
                              height: `${cell.height}px`,
                              "pointer-events": "none",
                              "z-index": "50",
                              "background-color": isHovered
                                ? "#ffffff"
                                : "transparent",
                              border: isHovered
                                ? "4px solid #000000"
                                : "2px dashed #ffffff",
                              "border-radius": "0",
                              transition: "none",
                              "box-shadow": "none",
                              transform: isHovered ? "scale(0.98)" : "scale(1)",
                            }}
                          >
                            {/* Snap indicator - shows when hovering */}
                            <Show when={isHovered}>
                              <div
                                style={{
                                  position: "absolute",
                                  top: "8px",
                                  right: "8px",
                                  background: "#000000",
                                  color: "#ffffff",
                                  padding: "4px 8px",
                                  "border-radius": "0",
                                  "font-size": "12px",
                                  "font-weight": "600",
                                  "box-shadow": "none",
                                  border: "2px solid #ffffff",
                                }}
                              >
                                Drop to snap
                              </div>
                            </Show>
                          </div>
                        );
                      }}
                    </For>
                  );
                }}
              </Show>

              {/* Render widgets */}
              <For each={widgets()}>
                {(widget) => {
                  const grid = gridConfig().templateId
                    ? getGrid(gridConfig().templateId || "")
                    : null;
                  return (
                    <WidgetRenderer
                      config={widget}
                      onPositionUpdate={handleWidgetPositionUpdate}
                      onSizeUpdate={handleWidgetSizeUpdate}
                      onRemove={handleRemoveWidget}
                      onSnapToCell={handleWidgetSnap}
                      onCellHover={handleCellHover}
                      onDragStateChange={handleDragStateChange}
                      gridCells={grid?.template.cells || []}
                    />
                  );
                }}
              </For>
            </div>
          </div>

          {/* 3D Tablet Preview Panel */}
          <div
            style={{
              border: "1px solid var(--border)",
              background: "#000",
              position: "relative",
              display: "flex",
              "align-items": "center",
              "justify-content": "center",
            }}
          >
            <TabletPreview dashboardElement={null} />
            <div
              style={{
                position: "absolute",
                bottom: "1rem",
                left: "50%",
                transform: "translateX(-50%)",
                color: "#666",
                "font-size": "0.85rem",
                "text-align": "center",
              }}
            >
              Live Preview
            </div>
          </div>
        </div>
      </div>

      <Show when={showUrlModal()}>
        <div
          style={{
            position: "fixed",
            top: "0",
            left: "0",
            right: "0",
            bottom: "0",
            background: "#ffffff",
            display: "flex",
            "align-items": "center",
            "justify-content": "center",
            "z-index": "1000",
          }}
          onClick={() => setShowUrlModal(false)}
        >
          <div
            style={{
              background: "#000000",
              padding: "2rem",
              "border-radius": "0",
              border: "3px solid #ffffff",
              "max-width": "600px",
              width: "90%",
            }}
            onClick={(e) => e.stopPropagation()}
          >
            <h3 style={{ "margin-bottom": "1rem" }}>Fullscreen Preview URL</h3>
            <p style={{ "margin-bottom": "1rem", color: "#ffffff" }}>
              Share this URL to display your dashboard in fullscreen mode with
              locked widgets:
            </p>
            <input
              type="text"
              value={previewUrl()}
              readOnly
              style={{
                width: "100%",
                padding: "0.5rem",
                "margin-bottom": "1rem",
                "font-size": "0.9rem",
              }}
            />
            <div
              style={{
                display: "flex",
                gap: "0.5rem",
                "margin-bottom": "1.5rem",
              }}
            >
              <button onClick={copyToClipboard}>Copy to Clipboard</button>
              <button onClick={() => window.open(previewUrl(), "_blank")}>
                Open Preview
              </button>
            </div>

            <Show when={shortLink()}>
              <div
                style={{
                  "border-top": "1px solid var(--border)",
                  "padding-top": "1.5rem",
                }}
              >
                <h3 style={{ "margin-bottom": "0.5rem", "font-size": "1rem" }}>
                  Short Link for E-Reader
                </h3>
                <p
                  style={{
                    "margin-bottom": "1rem",
                    color: "#ffffff",
                    "font-size": "0.9rem",
                  }}
                >
                  Easy to type on your e-reader keyboard:
                </p>
                <input
                  type="text"
                  value={shortLink()}
                  readOnly
                  style={{
                    width: "100%",
                    padding: "0.5rem",
                    "margin-bottom": "1rem",
                    "font-size": "1.1rem",
                    "font-weight": "600",
                    "font-family": "monospace",
                  }}
                />
                <button onClick={copyShortLinkToClipboard}>
                  Copy Short Link
                </button>
              </div>
            </Show>

            <div style={{ "margin-top": "1rem" }}>
              <button onClick={() => setShowUrlModal(false)}>Close</button>
            </div>
          </div>
        </div>
      </Show>
    </div>
  );
};
