"use client";

import * as React from "react";
import Link from "next/link";
import { ExternalLink, RefreshCw, Settings2 } from "lucide-react";

import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
import { cn } from "@/lib/utils";

type DashboardWidgetShellProps = {
  title: string;
  subtitle?: React.ReactNode;
  reportHref?: string;
  reportLabel?: string;
  settingsHref?: string;
  /** Opens configure in place (preferred over navigating to Dashboard Settings). */
  onSettingsClick?: () => void;
  loading?: boolean;
  refreshing?: boolean;
  error?: string | null;
  onRefresh?: () => void;
  headerActions?: React.ReactNode;
  toolbar?: React.ReactNode;
  loadingContent?: React.ReactNode;
  emptyContent?: React.ReactNode;
  children?: React.ReactNode;
  className?: string;
};

export function DashboardWidgetShell({
  title,
  subtitle,
  reportHref,
  reportLabel = "Full report",
  settingsHref,
  onSettingsClick,
  loading = false,
  refreshing = false,
  error = null,
  onRefresh,
  headerActions,
  toolbar,
  loadingContent,
  emptyContent,
  children,
  className,
}: DashboardWidgetShellProps) {
  const settingsControl = onSettingsClick ? (
    <Button
      type="button"
      variant="outline"
      size="icon"
      className="size-8"
      title="Configure widget"
      onClick={onSettingsClick}
    >
      <Settings2 className="size-4" />
      <span className="sr-only">Configure</span>
    </Button>
  ) : settingsHref ? (
    <Button asChild variant="outline" size="icon" className="size-8">
      <Link href={settingsHref} title="Configure widget">
        <Settings2 className="size-4" />
        <span className="sr-only">Configure</span>
      </Link>
    </Button>
  ) : null;

  return (
    <Card className={cn("flex h-full flex-col gap-0 overflow-hidden py-0 shadow-sm", className)}>
      <CardHeader className="flex flex-row items-start justify-between gap-3 space-y-0 border-b py-3">
        <div className="min-w-0 flex-1">
          <CardTitle className="text-base text-primary">{title}</CardTitle>
          {subtitle ? <div className="text-[10px] text-muted-foreground">{subtitle}</div> : null}
        </div>
        <div className="flex shrink-0 flex-wrap items-center justify-end gap-1">
          {headerActions}
          {settingsControl}
          {onRefresh ? (
            <Button
              type="button"
              variant="outline"
              size="icon"
              className="size-8"
              onClick={() => void onRefresh()}
              disabled={refreshing}
              aria-label="Refresh"
            >
              <RefreshCw className={cn("size-4", refreshing && "animate-spin")} />
            </Button>
          ) : null}
          {reportHref ? (
            <Button asChild variant="outline" size="sm" className="h-8 gap-1.5 px-2.5 text-xs">
              <Link href={reportHref}>
                {reportLabel}
                <ExternalLink className="size-3.5" />
              </Link>
            </Button>
          ) : null}
        </div>
      </CardHeader>

      {toolbar ? <div className="border-b border-border/60">{toolbar}</div> : null}

      <CardContent className="flex flex-1 flex-col overflow-hidden p-0">
        {loading && !children ? (
          loadingContent ?? (
            <div className="space-y-2 p-4">
              <Skeleton className="h-10 w-full" />
              <Skeleton className="h-32 w-full" />
            </div>
          )
        ) : error ? (
          <div className="flex min-h-[200px] flex-1 flex-col items-center justify-center gap-2 p-4 text-center">
            <p className="text-sm text-destructive">{error}</p>
            {onRefresh ? (
              <Button type="button" variant="outline" size="sm" onClick={() => void onRefresh()}>
                Try again
              </Button>
            ) : null}
          </div>
        ) : children ? (
          <div className="relative flex min-h-0 flex-1 flex-col overflow-hidden">
            {children}
            {refreshing ? (
              <div
                className="pointer-events-none absolute inset-0 z-10 flex items-center justify-center bg-background/60 backdrop-blur-[1px]"
                aria-busy="true"
                aria-live="polite"
              >
                <RefreshCw className="size-6 animate-spin text-muted-foreground" />
              </div>
            ) : null}
          </div>
        ) : (
          emptyContent ?? (
            <div className="flex min-h-[200px] flex-1 items-center justify-center p-4 text-center text-sm text-muted-foreground">
              No data available.
            </div>
          )
        )}
      </CardContent>
    </Card>
  );
}
