import type { Meta, StoryObj } from '@storybook/vue3-vite';
import UiCodeBlock from './UiCodeBlock.vue';

/**
 * UiCodeBlock is a pre-formatted block for rendering code snippets with syntax highlighting and copy-to-clipboard support.
 * Use it in documentation, AI assistant responses, and knowledge-base content where readable, monospaced code matters.
 */
const meta: Meta<typeof UiCodeBlock> = {
  title: 'Components/UiCodeBlock',
  component: UiCodeBlock,
  tags: ['autodocs'],
  argTypes: {
    code: {
      control: false,
    },
    language: {
      control: 'select',
      options: [
        'text',
        'typescript',
        'javascript',
        'python',
        'json',
        'html',
        'css',
        'bash',
        'sql',
      ],
      description:
        'Programming language for syntax highlighting. Supports all Shiki languages (200+).',
    },
    filename: {
      control: 'text',
      description:
        'Shown in header instead of the language label. Use for file-specific context.',
    },
    showLineNumbers: {
      control: 'boolean',
    },
    showCopyButton: {
      control: 'boolean',
    },
    maxHeight: {
      control: 'text',
      description:
        'CSS height value. Code area scrolls when content exceeds this height.',
    },
  },
  args: {
    language: 'typescript',
    showLineNumbers: false,
    showCopyButton: true,
  },
};

export default meta;

type Story = StoryObj<typeof UiCodeBlock>;

const typescriptExample = `import { ref, computed } from 'vue';

interface User {
  id: number;
  name: string;
  email: string;
}

const users = ref<User[]>([]);

const activeUsers = computed(() =>
  users.value.filter(user => user.email.includes('@'))
);

function addUser(name: string, email: string) {
  users.value.push({
    id: users.value.length + 1,
    name,
    email,
  });
}`;

const defaultTemplateSource = `<script setup lang="ts">
import { UiCodeBlock } from '@aleph-alpha/ui-library'
</script>

<template>
  <UiCodeBlock
    :code="code"
    language="typescript"
  />
</template>`;

/**
 * Basic code block with syntax highlighting. Use this for displaying code
 * snippets in documentation, AI assistant responses, or knowledge bases.
 */
export const Default: Story = {
  render: (args) => ({
    components: { UiCodeBlock },
    setup() {
      return { args, code: typescriptExample };
    },
    template: `<UiCodeBlock :code="code" :language="args.language" :show-line-numbers="args.showLineNumbers" :show-copy-button="args.showCopyButton" :filename="args.filename" :max-height="args.maxHeight" />`,
  }),
  parameters: {
    docs: {
      source: {
        code: defaultTemplateSource,
      },
    },
  },
};

const pythonExample = `import pandas as pd
from sklearn.model_selection import train_test_split

def train_model(data_path: str, target_col: str):
    """Load data, split, and train a simple model."""
    df = pd.read_csv(data_path)
    X = df.drop(columns=[target_col])
    y = df[target_col]

    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=0.2, random_state=42
    )
    return X_train, X_test, y_train, y_test`;

const pythonWithFilenameTemplateSource = `<script setup lang="ts">
import { UiCodeBlock } from '@aleph-alpha/ui-library'
</script>

<template>
  <UiCodeBlock
    :code="code"
    language="python"
    filename="train.py"
  />
</template>`;

/**
 * Use the filename prop to give users context about which file the code
 * belongs to. The filename replaces the language label in the header.
 */
export const WithFilename: Story = {
  render: () => ({
    components: { UiCodeBlock },
    setup() {
      return { code: pythonExample };
    },
    template: `<UiCodeBlock :code="code" language="python" filename="train.py" />`,
  }),
  parameters: {
    docs: {
      source: {
        code: pythonWithFilenameTemplateSource,
      },
    },
  },
};

const jsonExample = `{
  "name": "@aleph-alpha/ui-library",
  "version": "1.14.0",
  "dependencies": {
    "vue": "^3.4.0",
    "shiki": "^3.0.0"
  },
  "scripts": {
    "build": "vite build",
    "test": "vitest --run"
  }
}`;

const withLineNumbersTemplateSource = `<script setup lang="ts">
import { UiCodeBlock } from '@aleph-alpha/ui-library'
</script>

<template>
  <UiCodeBlock
    :code="code"
    language="json"
    filename="package.json"
    show-line-numbers
  />
</template>`;

/**
 * Enable line numbers for code that needs to be referenced by line,
 * such as config files, code reviews, or error stack traces.
 */
export const WithLineNumbers: Story = {
  render: () => ({
    components: { UiCodeBlock },
    setup() {
      return { code: jsonExample };
    },
    template: `<UiCodeBlock :code="code" language="json" filename="package.json" show-line-numbers />`,
  }),
  parameters: {
    docs: {
      source: {
        code: withLineNumbersTemplateSource,
      },
    },
  },
};

const longCode = Array.from(
  { length: 30 },
  (_, i) => `console.log('Line ${i + 1}: Processing item ${i + 1}');`,
).join('\n');

const withMaxHeightTemplateSource = `<script setup lang="ts">
import { UiCodeBlock } from '@aleph-alpha/ui-library'
</script>

<template>
  <UiCodeBlock
    :code="code"
    language="javascript"
    max-height="200px"
    show-line-numbers
  />
</template>`;

/**
 * Use maxHeight to constrain long code blocks and prevent them from
 * dominating the page layout. The code area becomes scrollable.
 */
export const WithMaxHeight: Story = {
  render: () => ({
    components: { UiCodeBlock },
    setup() {
      return { code: longCode };
    },
    template: `<UiCodeBlock :code="code" language="javascript" max-height="200px" show-line-numbers />`,
  }),
  parameters: {
    docs: {
      source: {
        code: withMaxHeightTemplateSource,
      },
    },
  },
};

const bashExample = `#!/bin/bash
set -euo pipefail

echo "Deploying application..."
docker build -t my-app:latest .
docker push my-app:latest
kubectl apply -f k8s/deployment.yaml
echo "Deployment complete!"`;

const withoutCopyButtonTemplateSource = `<script setup lang="ts">
import { UiCodeBlock } from '@aleph-alpha/ui-library'
</script>

<template>
  <UiCodeBlock
    :code="code"
    language="bash"
    :show-copy-button="false"
  />
</template>`;

/**
 * Hide the copy button when the code is for display only and copying
 * is not expected, such as terminal output or read-only logs.
 */
export const WithoutCopyButton: Story = {
  render: () => ({
    components: { UiCodeBlock },
    setup() {
      return { code: bashExample };
    },
    template: `<UiCodeBlock :code="code" language="bash" :show-copy-button="false" />`,
  }),
  parameters: {
    docs: {
      source: {
        code: withoutCopyButtonTemplateSource,
      },
    },
  },
};

const plainTextExample = `This is plain text output from a command.
No syntax highlighting is applied.
Useful for terminal output or log files.`;

const plainTextTemplateSource = `<script setup lang="ts">
import { UiCodeBlock } from '@aleph-alpha/ui-library'
</script>

<template>
  <UiCodeBlock :code="code" />
</template>`;

/**
 * Omit the language prop (defaults to 'text') for plain output that
 * doesn't need syntax highlighting, such as CLI output or raw logs.
 */
export const PlainText: Story = {
  render: () => ({
    components: { UiCodeBlock },
    setup() {
      return { code: plainTextExample };
    },
    template: `<UiCodeBlock :code="code" />`,
  }),
  parameters: {
    docs: {
      source: {
        code: plainTextTemplateSource,
      },
    },
  },
};

const htmlExample = `<template>
  <div class="card">
    <header class="card__header">
      <h2>{{ title }}</h2>
    </header>
    <main class="card__body">
      <slot />
    </main>
    <footer class="card__footer">
      <button @click="$emit('confirm')">Confirm</button>
    </footer>
  </div>
</template>`;

const htmlWithLineNumbersTemplateSource = `<script setup lang="ts">
import { UiCodeBlock } from '@aleph-alpha/ui-library'
</script>

<template>
  <UiCodeBlock
    :code="code"
    language="html"
    filename="Card.vue"
    show-line-numbers
  />
</template>`;

/**
 * Combine filename and line numbers for code review or documentation
 * contexts where both the file origin and line references matter.
 */
export const HtmlWithLineNumbers: Story = {
  render: () => ({
    components: { UiCodeBlock },
    setup() {
      return { code: htmlExample };
    },
    template: `<UiCodeBlock :code="code" language="html" filename="Card.vue" show-line-numbers />`,
  }),
  parameters: {
    docs: {
      source: {
        code: htmlWithLineNumbersTemplateSource,
      },
    },
  },
};
