import VModal from './VModal.vue';
import VButton from './VButton.vue'; // For modal footer actions
import VInput from './VInput.vue'; // For form elements in modal
import VFormField from './VFormField.vue'; // For form layout in modal
import type { Meta, StoryObj } from '@storybook/vue3';
import { ref, watch } from 'vue';

const meta: Meta<typeof VModal> = {
  title: 'Valerie/VModal',
  component: VModal,
  tags: ['autodocs'],
  argTypes: {
    modelValue: { control: 'boolean', description: 'Controls modal visibility (v-model).' },
    title: { control: 'text' },
    hideCloseButton: { control: 'boolean' },
    persistent: { control: 'boolean' },
    size: { control: 'select', options: ['sm', 'md', 'lg'] },
    idBase: { control: 'text' },
    // Events
    'update:modelValue': { action: 'update:modelValue', table: { disable: true } },
    close: { action: 'close' },
    opened: { action: 'opened' },
    closed: { action: 'closed' },
    // Slots
    header: { table: { disable: true } },
    default: { table: { disable: true } }, // Body slot
    footer: { table: { disable: true } },
  },
  parameters: {
    docs: {
      description: {
        component: 'A modal dialog component that teleports to the body. Supports v-model for visibility, custom content via slots, and various interaction options.',
      },
    },
    // To better demonstrate modals, you might want a dark background for stories if not default
    // backgrounds: { default: 'dark' },
  },
};

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

// Template for managing modal visibility in stories
const ModalInteractionTemplate: Story = {
  render: (args) => ({
    components: { VModal, VButton, VInput, VFormField },
    setup() {
      // Use a local ref for modelValue to simulate v-model behavior within the story
      // This allows Storybook controls to set the initial 'modelValue' arg,
      // and then the component and story can interact with this local state.
      const isModalOpen = ref(args.modelValue);

      // Watch for changes from Storybook controls to update local state
      watch(() => args.modelValue, (newVal) => {
        isModalOpen.value = newVal;
      });

      // Function to update Storybook arg when local state changes (simulates emit)
      const onUpdateModelValue = (val: boolean) => {
        isModalOpen.value = val;
        // args.modelValue = val; // This would update the control, but can cause loops if not careful
                               // Storybook's action logger for 'update:modelValue' will show this.
      };

      return { ...args, isModalOpen, onUpdateModelValue }; // Spread args to pass all other props
    },
    // Base template structure, specific content will be overridden by each story
    template: `
      <div>
        <VButton @click="isModalOpen = true">Open Modal</VButton>
        <VModal
          :modelValue="isModalOpen"
          @update:modelValue="onUpdateModelValue"
          :title="title"
          :hideCloseButton="hideCloseButton"
          :persistent="persistent"
          :size="size"
          :idBase="idBase"
          @opened="() => $emit('opened')"
          @closed="() => $emit('closed')"
          @close="() => $emit('close')"
        >
          <template #header v-if="args.customHeaderSlot">
            <div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
              <h3 style="margin:0;"><em>Custom Header Slot!</em></h3>
              <VButton v-if="!hideCloseButton" @click="isModalOpen = false" size="sm" variant="neutral">Close from slot</VButton>
            </div>
          </template>

          <template #default>
            <p v-if="args.bodyContent">{{ args.bodyContent }}</p>
            <slot name="storyDefaultContent"></slot>
          </template>

          <template #footer v-if="args.showFooter !== false">
             <slot name="storyFooterContent">
                <VButton variant="neutral" @click="isModalOpen = false">Cancel</VButton>
                <VButton variant="primary" @click="isModalOpen = false">Submit</VButton>
            </slot>
          </template>
        </VModal>
      </div>
    `,
  }),
};

export const Basic: Story = {
  ...ModalInteractionTemplate,
  args: {
    modelValue: false, // Initial state for Storybook control
    title: 'Basic Modal Title',
    bodyContent: 'This is the main content of the modal. You can put any HTML or Vue components here.',
    size: 'md',
  },
};

export const WithCustomHeader: Story = {
  ...ModalInteractionTemplate,
  args: {
    ...Basic.args,
    title: 'This title is overridden by slot',
    customHeaderSlot: true, // Custom arg for story to toggle header slot template
  },
};

export const Persistent: Story = {
  ...ModalInteractionTemplate,
  args: {
    ...Basic.args,
    title: 'Persistent Modal',
    bodyContent: 'This modal will not close when clicking the backdrop. Use the "Close" button or Escape key.',
    persistent: true,
  },
};

export const NoCloseButton: Story = {
  ...ModalInteractionTemplate,
  args: {
    ...Basic.args,
    title: 'No "X" Button',
    bodyContent: 'The default header close button (X) is hidden. You must provide other means to close it (e.g., footer buttons, Esc key).',
    hideCloseButton: true,
  },
};

export const SmallSize: Story = {
  ...ModalInteractionTemplate,
  args: {
    ...Basic.args,
    title: 'Small Modal (sm)',
    size: 'sm',
    bodyContent: 'This modal uses the "sm" size preset for a smaller width.',
  },
};

export const LargeSize: Story = {
  ...ModalInteractionTemplate,
  args: {
    ...Basic.args,
    title: 'Large Modal (lg)',
    size: 'lg',
    bodyContent: 'This modal uses the "lg" size preset for a larger width. Useful for forms or more content.',
  },
};

export const WithFormContent: Story = {
  ...ModalInteractionTemplate,
  render: (args) => ({ // Override render for specific slot content
    components: { VModal, VButton, VInput, VFormField },
    setup() {
      const isModalOpen = ref(args.modelValue);
      watch(() => args.modelValue, (newVal) => { isModalOpen.value = newVal; });
      const onUpdateModelValue = (val: boolean) => { isModalOpen.value = val; };
      const username = ref('');
      const password = ref('');
      return { ...args, isModalOpen, onUpdateModelValue, username, password };
    },
    template: `
      <div>
        <VButton @click="isModalOpen = true">Open Form Modal</VButton>
        <VModal
          :modelValue="isModalOpen"
          @update:modelValue="onUpdateModelValue"
          :title="title"
          :size="size"
        >
          <VFormField label="Username" forId="modalUser">
            <VInput id="modalUser" v-model="username" placeholder="Enter username" />
          </VFormField>
          <VFormField label="Password" forId="modalPass">
            <VInput id="modalPass" type="password" v-model="password" placeholder="Enter password" />
          </VFormField>

          <template #footer>
            <VButton variant="neutral" @click="isModalOpen = false">Cancel</VButton>
            <VButton variant="primary" @click="() => { alert('Submitted: ' + username + ' / ' + password); isModalOpen = false; }">Log In</VButton>
          </template>
        </VModal>
      </div>
    `,
  }),
  args: {
    ...Basic.args,
    title: 'Login Form',
    showFooter: true, // Ensure default footer with submit/cancel is shown by template logic
  },
};


export const ConfirmOnClose: Story = {
  render: (args) => ({
    components: { VModal, VButton, VInput },
    setup() {
      const isModalOpen = ref(args.modelValue);
      const textInput = ref("Some unsaved data...");
      const hasUnsavedChanges = computed(() => textInput.value !== "");

      watch(() => args.modelValue, (newVal) => { isModalOpen.value = newVal; });

      const requestClose = () => {
        if (hasUnsavedChanges.value) {
          if (confirm("You have unsaved changes. Are you sure you want to close?")) {
            isModalOpen.value = false;
             // args.modelValue = false; // Update arg
          }
        } else {
          isModalOpen.value = false;
          // args.modelValue = false; // Update arg
        }
      };

      // This simulates the @update:modelValue from VModal,
      // but intercepts it for confirmation logic.
      const handleModalUpdate = (value: boolean) => {
        if (value === false) { // Modal is trying to close
          requestClose();
        } else {
          isModalOpen.value = true;
          // args.modelValue = true;
        }
      };

      return { ...args, isModalOpen, textInput, handleModalUpdate, requestClose };
    },
    template: `
      <div>
        <VButton @click="isModalOpen = true">Open Modal with Confirmation</VButton>
        <VModal
          :modelValue="isModalOpen"
          @update:modelValue="handleModalUpdate"
          :title="title"
          :persistent="true"
          :hideCloseButton="false"
        >
          <p>Try to close this modal with text in the input field.</p>
          <VInput v-model="textInput" placeholder="Type something here" />
          <p v-if="textInput === ''" style="color: green;">No unsaved changes. Modal will close normally.</p>
          <p v-else style="color: orange;">Unsaved changes detected!</p>

          <template #footer>
            <VButton variant="neutral" @click="requestClose">Attempt Close</VButton>
            <VButton variant="primary" @click="() => { textInput = ''; alert('Changes saved (simulated)'); }">Save Changes</VButton>
          </template>
        </VModal>
      </div>
    `,
  }),
  args: {
    ...Basic.args,
    title: 'Confirm Close Modal',
    bodyContent: '', // Content is in the template for this story
    // persistent: true, // Good for confirm on close so backdrop click doesn't bypass confirm
    // hideCloseButton: true, // Also good for confirm on close
  },
};
