"use client";

import { useState, useEffect, useCallback, useRef } from "react";
import type { ReactElement } from "react";
import type { WidgetPlacement } from "@mosaic/shared";
import { WidgetGrid } from "@/components/widgets/WidgetGrid";
import { DEFAULT_LAYOUT } from "@/components/widgets/defaultLayout";
import { fetchDefaultLayout, createLayout, updateLayout } from "@/lib/api/layouts";
import { useWorkspaceId } from "@/lib/hooks";

export default function DashboardPage(): ReactElement {
  const workspaceId = useWorkspaceId();
  const [layout, setLayout] = useState<WidgetPlacement[]>(DEFAULT_LAYOUT);
  const [layoutId, setLayoutId] = useState<string | null>(null);
  const [isEditing, setIsEditing] = useState(false);
  const [isLoading, setIsLoading] = useState(true);

  // Debounce timer for auto-saving layout changes
  const saveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  // Load the user's default layout (or create one)
  useEffect(() => {
    if (!workspaceId) {
      setIsLoading(false);
      return;
    }

    const wsId = workspaceId;
    const ac = new AbortController();

    async function loadLayout(): Promise<void> {
      try {
        const existing = await fetchDefaultLayout(wsId);
        if (ac.signal.aborted) return;

        if (existing) {
          setLayout(existing.layout);
          setLayoutId(existing.id);
        } else {
          const created = await createLayout(wsId, {
            name: "Default",
            isDefault: true,
            layout: DEFAULT_LAYOUT,
          });
          // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- aborted can change during await
          if (ac.signal.aborted) return;
          setLayout(created.layout);
          setLayoutId(created.id);
        }
      } catch (err: unknown) {
        console.error("[Dashboard] Failed to load layout:", err);
      }
      setIsLoading(false);
    }

    void loadLayout();

    return (): void => {
      ac.abort();
    };
  }, [workspaceId]);

  // Save layout changes with debounce
  const saveLayout = useCallback(
    (newLayout: WidgetPlacement[]) => {
      if (!workspaceId || !layoutId) return;

      if (saveTimerRef.current) {
        clearTimeout(saveTimerRef.current);
      }

      saveTimerRef.current = setTimeout(() => {
        void updateLayout(workspaceId, layoutId, { layout: newLayout }).catch((err: unknown) => {
          console.error("[Dashboard] Failed to save layout:", err);
        });
      }, 800);
    },
    [workspaceId, layoutId]
  );

  const handleLayoutChange = useCallback(
    (newLayout: WidgetPlacement[]) => {
      setLayout(newLayout);
      saveLayout(newLayout);
    },
    [saveLayout]
  );

  const handleRemoveWidget = useCallback(
    (widgetId: string) => {
      const updated = layout.filter((item) => item.i !== widgetId);
      setLayout(updated);
      saveLayout(updated);
    },
    [layout, saveLayout]
  );

  if (isLoading) {
    return (
      <div className="flex items-center justify-center" style={{ minHeight: 400 }}>
        <div className="flex flex-col items-center gap-2">
          <div
            className="w-8 h-8 border-2 border-t-transparent rounded-full animate-spin"
            style={{ borderColor: "var(--primary)", borderTopColor: "transparent" }}
          />
          <span className="text-sm" style={{ color: "var(--muted)" }}>
            Loading dashboard...
          </span>
        </div>
      </div>
    );
  }

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
      {/* Dashboard header with edit toggle */}
      <div className="flex items-center justify-between">
        <h1
          style={{
            fontSize: "1.5rem",
            fontWeight: 700,
            color: "var(--text)",
            margin: 0,
          }}
        >
          Dashboard
        </h1>
        <button
          onClick={() => {
            setIsEditing((prev) => !prev);
          }}
          style={{
            padding: "6px 14px",
            borderRadius: "var(--r)",
            border: isEditing ? "1px solid var(--primary)" : "1px solid var(--border)",
            background: isEditing ? "var(--primary)" : "transparent",
            color: isEditing ? "#fff" : "var(--text-2)",
            fontSize: "0.83rem",
            fontWeight: 500,
            cursor: "pointer",
            transition: "all 0.15s ease",
          }}
        >
          {isEditing ? "Done" : "Edit Layout"}
        </button>
      </div>

      {/* Widget grid */}
      <WidgetGrid
        layout={layout}
        onLayoutChange={handleLayoutChange}
        {...(isEditing && { onRemoveWidget: handleRemoveWidget })}
        isEditing={isEditing}
      />
    </div>
  );
}
