"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 { WidgetPicker } from "@/components/widgets/WidgetPicker";
import { WidgetConfigDialog } from "@/components/widgets/WidgetConfigDialog";
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 [isPickerOpen, setIsPickerOpen] = useState(false);
  const [configWidgetId, setConfigWidgetId] = useState<string | null>(null);
  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]
  );

  const handleAddWidget = useCallback(
    (placement: WidgetPlacement) => {
      const updated = [...layout, placement];
      setLayout(updated);
      saveLayout(updated);
    },
    [layout, saveLayout]
  );

  const handleResetLayout = useCallback((): void => {
    setLayout(DEFAULT_LAYOUT);
    saveLayout(DEFAULT_LAYOUT);
  }, [saveLayout]);

  const handleEditWidget = useCallback((widgetId: string): void => {
    setConfigWidgetId(widgetId);
  }, []);

  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>
        <div className="flex items-center gap-2">
          {isEditing && (
            <>
              <button
                onClick={handleResetLayout}
                style={{
                  padding: "6px 14px",
                  borderRadius: "var(--r)",
                  border: "1px solid var(--border)",
                  background: "transparent",
                  color: "var(--muted)",
                  fontSize: "0.83rem",
                  fontWeight: 500,
                  cursor: "pointer",
                  transition: "all 0.15s ease",
                }}
              >
                Reset
              </button>
              <button
                onClick={(): void => {
                  setIsPickerOpen(true);
                }}
                style={{
                  padding: "6px 14px",
                  borderRadius: "var(--r)",
                  border: "1px solid var(--border)",
                  background: "transparent",
                  color: "var(--text-2)",
                  fontSize: "0.83rem",
                  fontWeight: 500,
                  cursor: "pointer",
                  transition: "all 0.15s ease",
                }}
              >
                + Add Widget
              </button>
            </>
          )}
          <button
            onClick={(): void => {
              setIsEditing((prev) => !prev);
              if (isEditing) setIsPickerOpen(false);
            }}
            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>
      </div>

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

      {/* Widget config dialog */}
      {configWidgetId && (
        <WidgetConfigDialog
          widgetId={configWidgetId}
          open
          onClose={(): void => {
            setConfigWidgetId(null);
          }}
        />
      )}

      {/* Widget picker drawer */}
      <WidgetPicker
        open={isPickerOpen}
        onClose={(): void => {
          setIsPickerOpen(false);
        }}
        onAddWidget={handleAddWidget}
        currentLayout={layout}
      />
    </div>
  );
}
