"use client";

import { useRef, useLayoutEffect } from "react";
import { createRoot, type Root } from "react-dom/client";
import { Maximize2 } from "lucide-react";
import { GridStack } from "gridstack";
import type { WidgetItem, DashboardAllocation } from "@/types/dashboard";
import { AllocationStateView } from "./AllocationStateView";

const WIDGET_CARD_CHART_HEIGHT = 280;
const WIDGET_CARD_PLACEHOLDER_HEIGHT = 192;

export interface WidgetCardContentProps {
  widget: WidgetItem;
  allocation: DashboardAllocation;
  currency?: string;
  piePalette: string[];
  onOpenModal?: (widget: WidgetItem) => void;
}

export function WidgetCardContent({
  widget,
  allocation,
  currency,
  piePalette,
  onOpenModal,
}: WidgetCardContentProps) {
  const isAssetAllocation = widget.file_path === "asset_allocation";
  const displayTitle = isAssetAllocation ? "Asset Allocation" : widget.name || "Widget";

  return (
    <div className="group relative flex h-full flex-col overflow-hidden rounded-2xl border border-slate-100 bg-white px-4 py-3.5 shadow-sm transition-all duration-200 hover:shadow-md hover:border-slate-200">
      {/* Decorative blobs */}
      <div className="pointer-events-none absolute -right-10 -top-14 h-36 w-36 rounded-full bg-indigo-200/30 blur-3xl transition-all duration-500 group-hover:scale-110" />
      <div className="pointer-events-none absolute -left-12 bottom-0 h-32 w-32 rounded-full bg-fuchsia-200/25 blur-3xl transition-all duration-500 group-hover:scale-110" />

      {/* Header */}
      <div className="relative flex items-center justify-between gap-2">
        <p className="text-sm font-bold tracking-tight text-slate-800">{displayTitle}</p>
        {onOpenModal && (
          <button
            type="button"
            onClick={() => onOpenModal(widget)}
            aria-label="Expand widget"
            className="flex h-6 w-6 items-center justify-center rounded-lg border border-slate-200 bg-white text-slate-400 shadow-sm opacity-0 transition-all duration-200 group-hover:opacity-100 hover:border-slate-300 hover:text-slate-600 hover:scale-110"
          >
            <Maximize2 className="h-3 w-3" />
          </button>
        )}
      </div>

      {/* Content */}
      <div
        className="relative mt-2 flex-1 min-h-0 cursor-pointer"
        onClick={() => onOpenModal?.(widget)}
        role="button"
        tabIndex={0}
        onKeyDown={(e) => {
          if (e.key === "Enter" || e.key === " ") {
            e.preventDefault();
            onOpenModal?.(widget);
          }
        }}
      >
        {isAssetAllocation ? (
          <AllocationStateView
            allocation={allocation}
            currency={currency}
            piePalette={piePalette}
            height={WIDGET_CARD_CHART_HEIGHT}
            widget={widget}
            placeholderMinHeight={WIDGET_CARD_PLACEHOLDER_HEIGHT}
          />
        ) : (
          <div className="flex h-full min-h-[192px] flex-col items-center justify-center rounded-xl bg-slate-50/80 px-4 text-center border border-slate-100">
            <p className="text-sm font-semibold text-slate-700">{widget.name}</p>
            <p className="mt-1 text-xs text-slate-400">
              {widget.short_description || "Active widget"}
            </p>
            <p className="mt-3 text-[10px] font-semibold uppercase tracking-widest text-slate-400">
              Click to expand
            </p>
          </div>
        )}
      </div>
    </div>
  );
}

export interface GridWidgetItemProps {
  widget: WidgetItem;
  allocation: DashboardAllocation;
  currency?: string;
  piePalette: string[];
  layout: { x: number; y: number; w: number; h: number };
  grid: GridStack | null;
  onOpenModal?: (widget: WidgetItem) => void;
}

export function GridWidgetItem({
  widget,
  allocation,
  currency,
  piePalette,
  layout,
  grid,
  onOpenModal,
}: GridWidgetItemProps) {
  const elRef = useRef<HTMLDivElement>(null);
  const contentRef = useRef<HTMLElement | null>(null);
  const rootRef = useRef<Root | null>(null);

  useLayoutEffect(() => {
    const el = elRef.current;
    if (!el || !grid) return;

    grid.makeWidget(el, { id: widget.widget_id });

    const contentEl = el.querySelector(".grid-stack-item-content") as HTMLElement | null;
    if (contentEl) {
      contentRef.current = contentEl;
      if (!rootRef.current) {
        rootRef.current = createRoot(contentEl);
      }
    }

    return () => {
      const root = rootRef.current;
      const content = contentRef.current;
      rootRef.current = null;
      contentRef.current = null;

      try {
        grid.removeWidget(el, false);
      } catch {
        // ignore
      }

      if (root && content) {
        queueMicrotask(() => {
          try {
            root.unmount();
          } catch {
            // ignore
          }
        });
      }
    };
  }, [grid, widget.widget_id]);

  useLayoutEffect(() => {
    if (!rootRef.current) return;
    rootRef.current.render(
      <WidgetCardContent
        widget={widget}
        allocation={allocation}
        currency={currency}
        piePalette={piePalette}
        onOpenModal={onOpenModal}
      />
    );
  }, [widget, allocation, currency, piePalette, onOpenModal]);

  return (
    <div
      ref={elRef}
      className="grid-stack-item"
      data-widget-id={widget.widget_id}
      gs-id={widget.widget_id}
      gs-w={layout.w}
      gs-h={layout.h}
      gs-x={layout.x}
      gs-y={layout.y}
    >
      <div className="grid-stack-item-content" />
    </div>
  );
}
