import type { Meta, StoryObj } from '@storybook/react';
import React, { useState } from 'react';
import { AppErrorBoundary, PageErrorBoundary, SectionErrorBoundary } from './error-boundary';

// ── Crash helper ─────────────────────────────────────────────────────────────
// A component that throws on the next render when `shouldCrash` is true.
// Used in every story to demonstrate real boundary behaviour.

function Crashable({ shouldCrash, label }: { shouldCrash: boolean; label: string }) {
  if (shouldCrash) throw new Error(`Simulated crash in: ${label}`);
  return (
    <div className="flex items-center justify-center p-8 rounded-[var(--radius-lg)] border border-border bg-card text-card-foreground">
      <p className="text-sm text-muted-foreground">
        ✅ <strong>{label}</strong> — rendering normally. Click the button to simulate a crash.
      </p>
    </div>
  );
}

// ── Wrapper that controls crash state ────────────────────────────────────────

function CrashController({
  Boundary,
  label,
}: {
  Boundary: React.ComponentType<{ children: React.ReactNode }>;
  label: string;
}) {
  const [crashed, setCrashed] = useState(false);

  return (
    <div className="space-y-4">
      <button
        onClick={() => setCrashed(true)}
        disabled={crashed}
        className="inline-flex items-center px-4 py-2 text-sm rounded-[var(--radius-button)] bg-destructive text-destructive-foreground hover:bg-destructive/90 disabled:opacity-40 disabled:cursor-not-allowed"
      >
        Simulate crash
      </button>

      <Boundary>
        <Crashable shouldCrash={crashed} label={label} />
      </Boundary>
    </div>
  );
}

// ── Meta ──────────────────────────────────────────────────────────────────────

const meta: Meta = {
  title: 'Shared/ErrorBoundary',
  parameters: {
    layout: 'padded',
    docs: {
      description: {
        component:
          'Three pre-configured ErrorBoundary variants for root, page, and section-level error isolation. Click "Simulate crash" to see each fallback UI.',
      },
    },
  },
};

export default meta;

// ── Stories ───────────────────────────────────────────────────────────────────

export const App: StoryObj = {
  name: 'AppErrorBoundary (root fallback)',
  render: () => <CrashController Boundary={AppErrorBoundary} label="App-level component" />,
  parameters: {
    docs: {
      description: {
        story:
          '`AppErrorBoundary` renders a full-screen fallback using only inline styles — no Tailwind dependency — so it works even if the design system itself fails to load.',
      },
    },
  },
};

export const Page: StoryObj = {
  name: 'PageErrorBoundary (route fallback)',
  render: () => <CrashController Boundary={PageErrorBoundary} label="Page component" />,
  parameters: {
    docs: {
      description: {
        story:
          '`PageErrorBoundary` shows a half-height Tailwind-styled fallback. The sidebar, header, and other chrome remain visible — only the page content area is replaced.',
      },
    },
  },
};

export const Section: StoryObj = {
  name: 'SectionErrorBoundary (inline fallback)',
  render: () => (
    <div className="space-y-6 max-w-2xl">
      <p className="text-sm text-muted-foreground">
        Each card below is independently wrapped. Crashing one does not affect the others.
      </p>

      {(['Team table', 'Chart', 'Assistant panel'] as const).map(label => (
        <CrashController key={label} Boundary={SectionErrorBoundary} label={label} />
      ))}
    </div>
  ),
  parameters: {
    docs: {
      description: {
        story:
          '`SectionErrorBoundary` renders a compact inline fallback. Multiple independent sections on the same page can each fail in isolation.',
      },
    },
  },
};
