<script lang="ts">
  import { onMount, onDestroy, createEventDispatcher } from 'svelte';
  import { fade, scale } from 'svelte/transition';
  
  const dispatch = createEventDispatcher();
  
  // Props
  export let title = '';
  export let closable = true;
  export let component = null;
  export let componentProps = {};
  
  // State
  let isOpen = false;
  let modalContent;
  let componentInstance = null;
  
  // Event callbacks
  let onSubmitCallback = null;
  let onCancelCallback = null;
  
  // Handle component dispatch events
  function handleComponentEvent(event) {
    if (event.type === 'save') {
      if (onSubmitCallback) {
        onSubmitCallback(event.detail);
      }
      close();
    } else if (event.type === 'cancel') {
      if (onCancelCallback) {
        onCancelCallback();
      }
      close();
    }
  }
  
  // Open the modal
  export function open() {
    console.log('Opening modal');
    isOpen = true;
  }
  
  // Close the modal
  export function close() {
    console.log('Closing modal');
    isOpen = false;
    
    // Schedule component cleanup
    setTimeout(() => {
      if (!isOpen) {
        cleanupComponent();
      }
    }, 300); // Wait for transitions to complete
  }
  
  // Set properties and callbacks
  export function setProps(props) {
    if (props.title !== undefined) title = props.title;
    if (props.closable !== undefined) closable = props.closable;
    if (props.component !== undefined) component = props.component;
    if (props.componentProps !== undefined) componentProps = props.componentProps;
    if (props.onSubmit) onSubmitCallback = props.onSubmit;
    if (props.onCancel) onCancelCallback = props.onCancel;
  }
  
  // Clean up any previous component instance
  function cleanupComponent() {
    if (componentInstance) {
      try {
        componentInstance.$destroy();
      } catch (error) {
        console.error('Error destroying component instance:', error);
      }
      componentInstance = null;
    }
  }

  // Only create component when modal is open and modalContent is available
  $: if (isOpen && component && modalContent) {
    console.log('Creating component in modal:', component.name || 'Unknown component');
    
    // Clean up previous component first to prevent conflicts
    cleanupComponent();
    
    try {
      // Create the component instance
      componentInstance = new component({
        target: modalContent,
        props: componentProps
      });
      
      console.log('Component created successfully');
      
      // Listen for events from the component
      for (const event of ['save', 'cancel']) {
        componentInstance.$on(event, (e) => handleComponentEvent({ type: event, detail: e.detail }));
      }
    } catch (error) {
      console.error('Error creating component in modal:', error);
    }
  }
  
  // Close on ESC key
  function handleKeydown(event) {
    if (event.key === 'Escape' && closable && isOpen) {
      close();
      if (onCancelCallback) onCancelCallback();
    }
  }
  
  // Cleanup on destroy
  onDestroy(() => {
    cleanupComponent();
    window.removeEventListener('keydown', handleKeydown);
  });
  
  // Listen for ESC key
  onMount(() => {
    window.addEventListener('keydown', handleKeydown);
    return () => {
      window.removeEventListener('keydown', handleKeydown);
    };
  });
  
  // Prevent clicks inside the modal from bubbling up
  function handleModalClick(event) {
    event.stopPropagation();
  }
  
  // Handle backdrop click
  function handleBackdropClick() {
    if (closable) {
      close();
      if (onCancelCallback) onCancelCallback();
    }
  }
</script>

<svelte:window on:keydown={handleKeydown} />

{#if isOpen}
  <div class="modal-backdrop" on:click={handleBackdropClick} transition:fade={{ duration: 150 }}>
    <div class="modal-content" on:click={handleModalClick} transition:scale={{ start: 0.95, duration: 200 }}>
      <div class="modal-header">
        <h2 class="modal-title">{title}</h2>
        {#if closable}
          <button type="button" class="modal-close-button" on:click={close} aria-label="Close modal">
            &times;
          </button>
        {/if}
      </div>
      
      <div class="modal-body" bind:this={modalContent}></div>
    </div>
  </div>
{/if}

<style>
  .modal-backdrop {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 1000;
  }
  
  .modal-content {
    background-color: #fff;
    border-radius: 8px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
    width: 90%;
    max-width: 600px;
    max-height: 90vh;
    overflow-y: auto;
    position: relative;
  }
  
  .modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 16px 20px;
    border-bottom: 1px solid #eee;
  }
  
  .modal-title {
    margin: 0;
    font-size: 1.25rem;
    color: #333;
  }
  
  .modal-close-button {
    background: none;
    border: none;
    font-size: 24px;
    cursor: pointer;
    color: #999;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
  }
  
  .modal-close-button:hover {
    color: #333;
    background-color: #f0f0f0;
  }
  
  .modal-body {
    max-height: calc(90vh - 70px);
    overflow-y: auto;
  }
  
  /* Dark mode support */
  :global(body.dark) .modal-content {
    background-color: #2d3748;
    color: #f8f9fa;
  }
  
  :global(body.dark) .modal-header {
    border-bottom-color: #4a5568;
  }
  
  :global(body.dark) .modal-title {
    color: #f8f9fa;
  }
  
  :global(body.dark) .modal-close-button {
    color: #cbd5e0;
  }
  
  :global(body.dark) .modal-close-button:hover {
    color: #f8f9fa;
    background-color: #4a5568;
  }
</style>