import BmsInputCode from '@/components/form/BmsInputCode.vue';
import { htmlSyntaxLinter, lintGutter } from './bms-input-code.linters';
import { ref } from 'vue';

import template from '@/documentation/template_field_dependency.mdx';

export default {
  title: 'Composants/form/InputCode',
  component: BmsInputCode,
  parameters: {
    docs: {
      page: template,
    },
  },
};

const Template = (args) => ({
  setup() {
    return { args };
  },
  components: {
    BmsInputCode,
  },
  template: `
    <BmsInputCode v-bind="args"/>
    <br/>
    <BmsInputCode v-bind="{...args, small:true}"/>
  `,
});

export const Default = Template.bind({});
Default.args = {
  captions: ['There is more information'],
  label: 'Label',
  type: 'html',
  modelValue: '',
};

export const WithValue = Template.bind({});
WithValue.args = {
  label: 'Label',
  type: 'html',
  modelValue: `
  <div></div>
  <div></div>`,
};
export const Disabled = Template.bind({});
Disabled.args = {
  label: 'Label',
  type: 'html',
  disabled: true,
  modelValue: `
  <div></div>
  <div></div>`,
};

// Simple template for documentation
const SimpleTemplate = (args) => ({
  setup() {
    const modelValue = ref(args.modelValue || '');
    return { args, modelValue };
  },
  components: {
    BmsInputCode,
  },
  template: `
  <BmsInputCode v-bind="args" v-model="modelValue" />
  `,
});

// Playground with default values for documentation
export const PlaygroundInputCode = SimpleTemplate.bind({});
PlaygroundInputCode.parameters = { chromatic: { disable: true } };
PlaygroundInputCode.args = {
  label: 'Code editor',
  type: 'json',
  modelValue: '{\n  "key": "value"\n}',
};

// Do: Input code with clear label
export const DoWithClearLabel = SimpleTemplate.bind({});
DoWithClearLabel.parameters = { chromatic: { disable: true } };
DoWithClearLabel.args = {
  label: 'JSON Configuration',
  type: 'json',
  modelValue: '{\n  "name": "example"\n}',
};

// Do: Input code with HTML type
export const DoWithHtmlType = SimpleTemplate.bind({});
DoWithHtmlType.parameters = { chromatic: { disable: true } };
DoWithHtmlType.args = {
  label: 'HTML Template',
  type: 'html',
  modelValue: '<div class="container">\n  <p>Content</p>\n</div>',
};

// Do: Input code with JSON type and validation
export const DoWithJsonType = SimpleTemplate.bind({});
DoWithJsonType.parameters = { chromatic: { disable: true } };
DoWithJsonType.args = {
  label: 'Configuration JSON',
  type: 'json',
  modelValue: '{\n  "setting": true,\n  "value": 42\n}',
  captions: ['JSON syntax is automatically validated'],
};

// Do: Input code with caption
export const DoWithCaption = SimpleTemplate.bind({});
DoWithCaption.parameters = { chromatic: { disable: true } };
DoWithCaption.args = {
  label: 'Code snippet',
  type: 'html',
  modelValue: '<div>Example</div>',
  captions: ['Enter valid HTML code'],
};

// Do: Disabled state
export const DoDisabled = SimpleTemplate.bind({});
DoDisabled.parameters = { chromatic: { disable: true } };
DoDisabled.args = {
  label: 'Read-only code',
  type: 'json',
  modelValue: '{\n  "readonly": true\n}',
  disabled: true,
};

// Do: Input code with error feedback
export const DoWithErrorFeedback = SimpleTemplate.bind({});
DoWithErrorFeedback.parameters = { chromatic: { disable: true } };
DoWithErrorFeedback.args = {
  label: 'JSON Configuration',
  type: 'json',
  modelValue: '{\n  "invalid": json\n}',
  errors: ['Invalid JSON syntax'],
};

// Don't: Missing labels
export const DontNoLabel = SimpleTemplate.bind({});
DontNoLabel.parameters = { chromatic: { disable: true } };
DontNoLabel.args = {
  type: 'json',
  modelValue: '{\n  "key": "value"\n}',
};

export const DoWithLabel = SimpleTemplate.bind({});
DoWithLabel.parameters = { chromatic: { disable: true } };
DoWithLabel.args = {
  label: 'Code editor',
  type: 'json',
  modelValue: '{\n  "key": "value"\n}',
};

// Don't: No error feedback
export const DontNoErrorFeedback = SimpleTemplate.bind({});
DontNoErrorFeedback.parameters = { chromatic: { disable: true } };
DontNoErrorFeedback.args = {
  label: 'JSON Configuration',
  type: 'json',
  modelValue: '{\n  "invalid": syntax\n}',
};

// Extra extensions: les objets CodeMirror ne peuvent pas être passés via args
// (références circulaires non sérialisables par Storybook) — on les instancie dans setup.
const makeExtraExtensionsTemplate = (extensions) => (args) => ({
  setup() {
    const modelValue = ref(args.modelValue || '');
    return { args, modelValue, extensions };
  },
  components: { BmsInputCode },
  template: `<BmsInputCode v-bind="args" v-model="modelValue" :extra-extensions="extensions" />`,
});

export const WithExtraExtensions = makeExtraExtensionsTemplate([
  lintGutter(),
  htmlSyntaxLinter(),
]).bind({});
WithExtraExtensions.parameters = { chromatic: { disable: true } };
WithExtraExtensions.args = {
  label: 'HTML avec linter syntaxique',
  type: 'html',
  modelValue: '<div><p>Hello</p></div>',
};

export const WithExtraExtensionsError = makeExtraExtensionsTemplate([
  lintGutter(),
  htmlSyntaxLinter(),
]).bind({});
WithExtraExtensionsError.parameters = { chromatic: { disable: true } };
WithExtraExtensionsError.args = {
  label: 'HTML avec linter syntaxique (erreur)',
  type: 'html',
  modelValue: '<div><p>Balise non fermée</div>',
};

// Click JSON path event
const JsonPathTemplate = (args) => ({
  setup() {
    const modelValue = ref(args.modelValue || '');
    const lastPath = ref(null);
    return { args, modelValue, lastPath };
  },
  components: { BmsInputCode },
  template: `
    <BmsInputCode
      v-bind="args"
      v-model="modelValue"
      @click-json-path="lastPath = $event"
    />
    <div v-if="lastPath !== null" style="margin-top: 12px; font-family: monospace; font-size: 13px;">
      JSON path: <strong>{{ lastPath }}</strong>
    </div>
  `,
});

export const JsonPathClick = JsonPathTemplate.bind({});
JsonPathClick.parameters = { chromatic: { disable: true } };
JsonPathClick.args = {
  label: 'JSON Configuration',
  type: 'json',
  modelValue: JSON.stringify(
    {
      user: {
        name: 'Alice',
        address: { city: 'Paris', zip: '75001' },
      },
      tags: ['admin', 'editor'],
    },
    null,
    2,
  ),
};
