import type { Type } from '@angular/core';

/**
 * Local shim of the CSF3 story types.
 *
 * This file exists because the Aurora catalog convention (see
 * `frontend/.claude/skills/catalyst-component-catalog/`) authors `*.stories.ts`
 * files using the Storybook CSF3 shape (`Meta<T>` + named `StoryObj<T>` exports)
 * WITHOUT installing Storybook as a runtime. Stories are consumed as structured
 * documentation by humans and by Claude (`Glob` + `Read`) — not rendered by a
 * Storybook dev server.
 *
 * When Storybook is reintroduced:
 *   1. Install `@storybook/angular` and `storybook/test`.
 *   2. Delete this file.
 *   3. Replace `import { Meta, StoryObj } from '@aurora/story.types'` with
 *      `import type { Meta, StoryObj } from '@storybook/angular'` across every
 *      `*.stories.ts` under `frontend/src/@aurora/components/**`.
 *
 * The shapes below are intentionally a strict subset of the real Storybook
 * types — enough for TypeScript to validate our stories, not enough to mislead
 * readers into thinking this runs as Storybook.
 */

export interface AuroraStoryMetadata {
  /** Coarse component family — e.g. `'data-table'`, `'navigation'`, `'form'`. */
  category: string;
  /** One-sentence description of the primary use case. */
  when: string;
  /** One-sentence description of when a different component fits better, naming that alternative. */
  whenNot: string;
}

export interface StoryParameters {
  docs?: {
    description?: {
      story?: string;
      component?: string;
    };
  };
  aurora?: AuroraStoryMetadata;
  [key: string]: unknown;
}

export interface StoryArgType {
  /**
   * Storybook control spec. `false` disables the control UI (useful for
   * complex inputs like functions that cannot be edited through form widgets).
   */
  control?: string | { type: string; [key: string]: unknown } | false;
  description?: string;
  /** Shortcut for declaring an output as an action; preserved for Storybook parity. */
  action?: string;
  [key: string]: unknown;
}

export type StoryArgTypes<TComponent> = {
  [K in keyof TComponent]?: StoryArgType;
} & {
  [key: string]: StoryArgType;
};

/**
 * Unwrap Angular v17+ signal-like wrappers to their value type.
 * - `input<T>()` returns `InputSignal<T>` (callable, `() => T`).
 * - `output<T>()` returns `OutputEmitterRef<T>` (has `.emit`, not callable as `() => T`).
 * Non-signal members pass through untouched.
 */
type UnwrapSignal<T> = T extends { (): infer V } ? V : T;

type UnwrapSignals<T> = { [K in keyof T]: UnwrapSignal<T[K]> };

export type StoryArgs<TComponent> = Partial<UnwrapSignals<TComponent>> & Record<string, unknown>;

export interface Meta<TComponent> {
  title: string;
  component: Type<TComponent>;
  tags?: string[];
  argTypes?: StoryArgTypes<TComponent>;
  args?: StoryArgs<TComponent>;
  parameters?: StoryParameters;
}

export interface StoryObj<TComponent> {
  name?: string;
  args?: StoryArgs<TComponent>;
  parameters?: StoryParameters;
}
