import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';
import Toolbar from './Toolbar';
import { withReactFlow, withStore } from '../../.storybook/decorators';
import { Node, Edge } from '../store/store';

// ─── Event components for QuickAddEventButton ────────────────────────────────
// The store needs event/trigger components so the "New event" button renders.
const eventComponents = [
  { plugin: 'content_entity:insert', label: 'Content Insert', category: 'Events', componentType: 1 },
  { plugin: 'cron', label: 'Cron Run', category: 'Events', componentType: 1 },
  { plugin: 'user:login', label: 'User Login', category: 'Events', componentType: 1 },
  { plugin: 'trigger:manual', label: 'Manual Trigger', category: 'Triggers', componentType: 1 },
];

// Sample data for search functionality
const sampleNodes: Node[] = [
  { id: 'node_1', type: 'start', position: { x: 0, y: 0 }, data: { label: 'Content Created' } },
  { id: 'node_2', type: 'element', position: { x: 200, y: 0 }, data: { label: 'Send Email' } },
  { id: 'node_3', type: 'gateway', position: { x: 400, y: 0 }, data: { label: 'Check Role' } },
];

const sampleEdges: Edge[] = [
  { id: 'edge_1', source: 'node_1', target: 'node_2', type: 'default' },
  { id: 'edge_2', source: 'node_2', target: 'node_3', type: 'default' },
];

const meta: Meta<typeof Toolbar> = {
  title: 'Components/Toolbar',
  component: Toolbar,
  parameters: {
    layout: 'fullscreen',
  },
  decorators: [
    withReactFlow,
    withStore({ initialState: { components: eventComponents } }),
    (Story: React.ComponentType) => (
      <div style={{ width: '100%', background: '#fff' }}>
        <Story />
      </div>
    ),
  ],
  args: {
    onSave: fn(),
    onOpenMetadata: fn(),
    onToggleLock: fn(),
    onAutoLayout: fn(),
    onCopy: fn(),
    onPaste: fn(),
    onToggleSearch: fn(),
    onToggleAllAnnotations: fn(),
    onToggleMessages: fn(),
    onClearMessages: fn(),
    onToggleMinimap: fn(),
    onToggleEdgeOrders: fn(),
    onClose: fn(),
    onMinimize: fn(),
    onSearchHighlight: fn(),
    onSearchFocus: fn(),
    onAddEvent: fn(),
    onEventPopupOpenChange: fn(),
    isEventPopupOpen: false,
    isLocked: false,
    isSearchVisible: false,
    isMinimapVisible: true,
    hasSelection: false,
    canPaste: false,
    nodes: sampleNodes,
    edges: sampleEdges,
    allAnnotationsVisible: false,
    edgeOrdersVisible: false,
    hasMessages: false,
    messagesVisible: false,
    zoomLevel: 1,
    modelName: 'My Workflow',
    hasUnsavedChanges: false,
    settings: {},
  },
  argTypes: {
    isLocked: {
      control: 'boolean',
      description: 'Whether the canvas is locked',
    },
    isSearchVisible: {
      control: 'boolean',
      description: 'Whether the search bar is visible',
    },
    hasSelection: {
      control: 'boolean',
      description: 'Whether there is a selection (enables copy button)',
    },
    canPaste: {
      control: 'boolean',
      description: 'Whether paste is available',
    },
    hasUnsavedChanges: {
      control: 'boolean',
      description: 'Shows unsaved indicator in title and enables save button',
    },
    zoomLevel: {
      control: { type: 'range', min: 0.1, max: 4, step: 0.1 },
      description: 'Current zoom level',
    },
    modelName: {
      control: 'text',
      description: 'Name of the workflow model',
    },
  },
};

export default meta;
type Story = StoryObj<typeof Toolbar>;

/**
 * Default toolbar state
 */
export const Default: Story = {};

/**
 * Toolbar with unsaved changes indicator
 */
export const UnsavedChanges: Story = {
  args: {
    hasUnsavedChanges: true,
    modelName: 'Email Notification Workflow',
  },
};

/**
 * Toolbar with active selection (copy enabled)
 */
export const WithSelection: Story = {
  args: {
    hasSelection: true,
    canPaste: true,
  },
};

/**
 * Toolbar with locked canvas
 */
export const LockedCanvas: Story = {
  args: {
    isLocked: true,
  },
};

/**
 * Toolbar with search visible
 */
export const SearchVisible: Story = {
  args: {
    isSearchVisible: true,
  },
};

/**
 * Toolbar with all toggles active
 */
export const AllTogglesActive: Story = {
  args: {
    isLocked: true,
    isSearchVisible: true,
    isMinimapVisible: true,
    allAnnotationsVisible: true,
    edgeOrdersVisible: true,
    hasSelection: true,
    canPaste: true,
  },
};

/**
 * Toolbar with messages toggle visible (messages hidden, ready to show)
 */
export const WithMessagesToggleActive: Story = {
  args: {
    hasMessages: true,
    messagesVisible: false,
  },
};

/**
 * Toolbar with messages toggle visible (messages shown, can hide)
 */
export const WithMessagesToggleInactive: Story = {
  args: {
    hasMessages: true,
    messagesVisible: true,
  },
};

/**
 * Toolbar with minimize button (stayInContextOnClose)
 */
export const WithMinimizeButton: Story = {
  args: {
    settings: {
      modeler: {
        stayInContextOnClose: true,
      },
    },
  },
};

/**
 * Toolbar with context selector dropdown (no context selected)
 */
export const WithContextSelector: Story = {
  args: {
    contexts: [
      { id: 'ctx_1', topic: 'Content Publishing', model_owner: 'example_owner', components: {} },
      { id: 'ctx_2', topic: 'User Registration', model_owner: 'example_owner', components: {} },
      { id: 'ctx_3', topic: 'Commerce Orders', model_owner: 'example_owner', components: {} },
    ],
    selectedContextId: null,
    onContextChange: fn(),
  },
};

/**
 * Toolbar with context selector and a context pre-selected
 */
export const WithContextSelected: Story = {
  args: {
    contexts: [
      { id: 'ctx_1', topic: 'Content Publishing', model_owner: 'example_owner', components: {} },
      { id: 'ctx_2', topic: 'User Registration', model_owner: 'example_owner', components: {} },
      { id: 'ctx_3', topic: 'Commerce Orders', model_owner: 'example_owner', components: {} },
    ],
    selectedContextId: 'ctx_2',
    onContextChange: fn(),
  },
};

// ─── New Event Button stories ────────────────────────────────────────────────

/**
 * Toolbar with the "New event" button visible in the toolbar-left section.
 * The button appears as the first element when `onAddEvent` is provided and
 * the canvas is not locked.
 */
export const WithNewEventButton: Story = {
  args: {
    onAddEvent: fn(),
    isEventPopupOpen: false,
  },
};

/**
 * Toolbar with the "New event" popup open (controlled mode).
 */
export const WithNewEventPopupOpen: Story = {
  args: {
    onAddEvent: fn(),
    isEventPopupOpen: true,
    onEventPopupOpenChange: fn(),
  },
};

/**
 * Toolbar with locked canvas hides the "New event" button.
 * Compare with WithNewEventButton to see the difference.
 */
export const LockedHidesNewEvent: Story = {
  args: {
    isLocked: true,
    onAddEvent: fn(),
  },
};

// ─── Start Flow Filter stories ───────────────────────────────────────────────

// Nodes with multiple start nodes so the StartFlowFilter renders
const multiStartNodes: Node[] = [
  { id: 'start_1', type: 'start', position: { x: 0, y: 0 }, data: { label: 'Content Created', plugin: 'content:entity_insert' } },
  { id: 'start_2', type: 'start', position: { x: 0, y: 300 }, data: { label: 'User Registered', plugin: 'user:user_insert' } },
  { id: 'start_3', type: 'start', position: { x: 0, y: 600 }, data: { label: 'Order Completed', plugin: 'commerce:order_complete' } },
  { id: 'action_1', type: 'element', position: { x: 200, y: 0 }, data: { label: 'Send Email', plugin: 'mail:send_mail' } },
  { id: 'gateway_1', type: 'gateway', position: { x: 400, y: 0 }, data: { label: 'Check Role' } },
];

const multiStartEdges: Edge[] = [
  { id: 'edge_1', source: 'start_1', target: 'action_1', type: 'default' },
  { id: 'edge_2', source: 'action_1', target: 'gateway_1', type: 'default' },
];

/**
 * Toolbar with Start Flow Filter visible (all flows selected).
 * The filter appears because there are multiple start nodes.
 */
export const WithFlowFilter: Story = {
  args: {
    nodes: multiStartNodes,
    edges: multiStartEdges,
  },
  decorators: [
    withStore({ initialState: { visibleStartNodeIds: null } }),
  ],
};

/**
 * Toolbar with Start Flow Filter showing a single selected flow.
 * The button label displays the selected start node's name.
 */
export const WithFlowFilterSingleSelected: Story = {
  args: {
    nodes: multiStartNodes,
    edges: multiStartEdges,
  },
  decorators: [
    withStore({ initialState: { visibleStartNodeIds: ['start_2'] } }),
  ],
};

/**
 * Toolbar with Start Flow Filter and context selector together.
 * Demonstrates both toolbar-left controls rendering side by side.
 */
export const WithFlowFilterAndContext: Story = {
  args: {
    nodes: multiStartNodes,
    edges: multiStartEdges,
    contexts: [
      { id: 'ctx_1', topic: 'Content Publishing', model_owner: 'example_owner', components: {} },
      { id: 'ctx_2', topic: 'User Registration', model_owner: 'example_owner', components: {} },
    ],
    selectedContextId: 'ctx_1',
    onContextChange: fn(),
  },
  decorators: [
    withStore({ initialState: { visibleStartNodeIds: null } }),
  ],
};

// ─── Overflow Menu stories ───────────────────────────────────────────────────

/**
 * Toolbar at a narrow width (800px).
 * The lowest-priority buttons (minimap, dark mode, zoom, etc.)
 * collapse into the overflow ("...") menu.
 */
export const NarrowWidth: Story = {
  decorators: [
    withReactFlow,
    withStore({ initialState: { components: eventComponents } }),
    (Story: React.ComponentType) => (
      <div style={{ width: '800px', background: '#fff' }}>
        <Story />
      </div>
    ),
  ],
  args: {
    isSearchVisible: true,
  },
};

/**
 * Toolbar at a very narrow width (500px).
 * Most buttons collapse into the overflow menu; only Save, Close,
 * and a few high-priority items remain inline.
 */
export const VeryNarrowWidth: Story = {
  decorators: [
    withReactFlow,
    withStore({ initialState: { components: eventComponents } }),
    (Story: React.ComponentType) => (
      <div style={{ width: '500px', background: '#fff' }}>
        <Story />
      </div>
    ),
  ],
};

/**
 * Toolbar with all features active at a narrow width.
 * Demonstrates how the overflow menu handles many active/toggled items.
 */
export const AllFeaturesNarrow: Story = {
  decorators: [
    withReactFlow,
    withStore({ initialState: { components: eventComponents } }),
    (Story: React.ComponentType) => (
      <div style={{ width: '700px', background: '#fff' }}>
        <Story />
      </div>
    ),
  ],
  args: {
    isLocked: true,
    isSearchVisible: true,
    isMinimapVisible: true,
    allAnnotationsVisible: true,
    edgeOrdersVisible: true,
    hasSelection: true,
    canPaste: true,
    hasUnsavedChanges: true,
    hasMessages: true,
    messagesVisible: false,
  },
};

/**
 * Toolbar with a very long model name demonstrating title truncation
 * in the center region.
 */
export const LongModelName: Story = {
  args: {
    modelName: 'My Very Long Workflow Model Name That Should Get Truncated With Ellipsis When It Exceeds Available Space',
    hasUnsavedChanges: true,
  },
};

// ─── Compact Mode stories ────────────────────────────────────────────────────

/**
 * Toolbar in compact mode (below 660px threshold).
 * Two-row layout: center+right on row 1, left on row 2.
 * All right-region buttons collapse into the overflow menu,
 * leaving only Save, Close, and the overflow trigger visible.
 */
export const CompactMode: Story = {
  decorators: [
    withReactFlow,
    withStore({ initialState: { components: eventComponents } }),
    (Story: React.ComponentType) => (
      <div style={{ width: '400px', background: '#fff' }}>
        <Story />
      </div>
    ),
  ],
  args: {
    hasUnsavedChanges: true,
    modelName: 'Compact Workflow',
  },
};

/**
 * Compact mode with all features active.
 * Demonstrates the two-row layout with messages indicator,
 * flow filter, and new event button in the second row.
 */
export const CompactModeAllFeatures: Story = {
  decorators: [
    withReactFlow,
    withStore({ initialState: { components: eventComponents, visibleStartNodeIds: null } }),
    (Story: React.ComponentType) => (
      <div style={{ width: '500px', background: '#fff' }}>
        <Story />
      </div>
    ),
  ],
  args: {
    nodes: multiStartNodes,
    edges: multiStartEdges,
    isLocked: false,
    isSearchVisible: false,
    hasUnsavedChanges: true,
    hasMessages: true,
    messagesVisible: false,
    modelName: 'Email Notification Workflow',
    onAddEvent: fn(),
    isEventPopupOpen: false,
    onEventPopupOpenChange: fn(),
    settings: {
      modeler: {
        stayInContextOnClose: true,
      },
    },
  },
};
