<script setup>
import { computed, watch, onMounted, onUnmounted } from 'vue';
import { useDesignSystem } from '~/composables/useDesignSystem';

const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  title: {
    type: String,
    default: ''
  },
  size: {
    type: String,
    default: 'md',
    validator: (value) => ['sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl', '5xl', '6xl', 'full'].includes(value)
  },
  persistent: {
    type: Boolean,
    default: false
  },
  loading: {
    type: Boolean,
    default: false
  },
  scrollable: {
    type: Boolean,
    default: true
  },
  centered: {
    type: Boolean,
    default: false
  },
  hideHeader: {
    type: Boolean,
    default: false
  },
  hideFooter: {
    type: Boolean,
    default: false
  },
  maxHeight: {
    type: String,
    default: '80vh'
  }
});

const emit = defineEmits(['close', 'confirm', 'cancel']);

// Design system
const { tokens, utils, animations } = useDesignSystem();

// Modal state
const isVisible = ref(false);
const modalRef = ref(null);
const focusableElements = ref([]);

// Computed classes
const modalClasses = computed(() => {
  return utils.composeClasses(
    'fixed inset-0 z-50 flex items-center justify-center p-4',
    centered.value ? 'items-center' : 'items-start pt-16',
    'backdrop-blur-sm bg-black/50'
  );
});

const dialogClasses = computed(() => {
  return utils.composeClasses(
    'relative w-full max-h-full',
    utils.getSizeClasses('modal', props.size),
    'bg-white dark:bg-gray-800',
    'rounded-lg shadow-xl',
    'transform transition-all duration-300',
    'border border-gray-200 dark:border-gray-600'
  );
});

const contentClasses = computed(() => {
  return utils.composeClasses(
    'flex flex-col max-h-full',
    props.scrollable ? 'overflow-hidden' : ''
  );
});

// Focus management
const getFocusableElements = () => {
  if (!modalRef.value) return [];
  
  const selectors = [
    'button:not([disabled])',
    'input:not([disabled])',
    'textarea:not([disabled])',
    'select:not([disabled])',
    'a[href]',
    '[tabindex]:not([tabindex="-1"])'
  ];
  
  return Array.from(modalRef.value.querySelectorAll(selectors.join(', ')));
};

const trapFocus = (event) => {
  if (!isVisible.value) return;
  
  const focusableEls = getFocusableElements();
  const firstFocusable = focusableEls[0];
  const lastFocusable = focusableEls[focusableEls.length - 1];
  
  if (event.key === 'Tab') {
    if (event.shiftKey) {
      if (document.activeElement === firstFocusable) {
        event.preventDefault();
        lastFocusable?.focus();
      }
    } else {
      if (document.activeElement === lastFocusable) {
        event.preventDefault();
        firstFocusable?.focus();
      }
    }
  }
};

const handleEscape = (event) => {
  if (event.key === 'Escape' && isVisible.value && !props.persistent) {
    closeModal();
  }
};

// Modal actions
const closeModal = () => {
  if (props.loading) return;
  emit('close');
};

const handleBackdropClick = (event) => {
  if (event.target === event.currentTarget && !props.persistent) {
    closeModal();
  }
};

const confirmAction = () => {
  emit('confirm');
};

const cancelAction = () => {
  emit('cancel');
};

// Watchers
watch(() => props.visible, (newValue) => {
  isVisible.value = newValue;
  
  if (newValue) {
    document.body.style.overflow = 'hidden';
    nextTick(() => {
      const focusableEls = getFocusableElements();
      focusableEls[0]?.focus();
    });
  } else {
    document.body.style.overflow = '';
  }
});

// Lifecycle
onMounted(() => {
  document.addEventListener('keydown', handleEscape);
  document.addEventListener('keydown', trapFocus);
});

onUnmounted(() => {
  document.removeEventListener('keydown', handleEscape);
  document.removeEventListener('keydown', trapFocus);
  document.body.style.overflow = '';
});
</script>

<template>
  <Teleport to="body">
    <Transition
      :enter-active-class="animations.transitions.fadeIn.enter"
      :enter-from-class="animations.transitions.fadeIn.enterFrom"
      :enter-to-class="animations.transitions.fadeIn.enterTo"
      :leave-active-class="animations.transitions.fadeIn.leave"
      :leave-from-class="animations.transitions.fadeIn.leaveFrom"
      :leave-to-class="animations.transitions.fadeIn.leaveTo"
    >
      <div
        v-if="isVisible"
        :class="modalClasses"
        @click="handleBackdropClick"
        role="dialog"
        aria-modal="true"
        :aria-labelledby="title ? 'modal-title' : undefined"
      >
        <Transition
          :enter-active-class="animations.transitions.scaleIn.enter"
          :enter-from-class="animations.transitions.scaleIn.enterFrom"
          :enter-to-class="animations.transitions.scaleIn.enterTo"
          :leave-active-class="animations.transitions.scaleIn.leave"
          :leave-from-class="animations.transitions.scaleIn.leaveFrom"
          :leave-to-class="animations.transitions.scaleIn.leaveTo"
        >
          <div
            v-if="isVisible"
            ref="modalRef"
            :class="dialogClasses"
            @click.stop
          >
            <!-- Loading Overlay -->
            <div
              v-if="loading"
              class="absolute inset-0 bg-white/80 dark:bg-gray-800/80 rounded-lg flex items-center justify-center z-10"
            >
              <div class="flex flex-col items-center space-y-3">
                <div class="w-8 h-8 border-2 border-primary border-t-transparent rounded-full animate-spin"></div>
                <p class="text-sm text-gray-600 dark:text-gray-400">Loading...</p>
              </div>
            </div>

            <div :class="contentClasses" :style="{ maxHeight: maxHeight }">
              <!-- Header -->
              <header
                v-if="!hideHeader && (title || $slots.header)"
                class="flex items-center justify-between p-6 border-b border-gray-200 dark:border-gray-600"
              >
                <div class="flex-1">
                  <slot name="header">
                    <h2
                      v-if="title"
                      id="modal-title"
                      class="text-lg font-semibold text-gray-900 dark:text-gray-100"
                    >
                      {{ title }}
                    </h2>
                  </slot>
                </div>
                
                <button
                  v-if="!persistent"
                  @click="closeModal"
                  :disabled="loading"
                  class="ml-4 p-1 rounded-md text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors duration-200 disabled:opacity-50"
                  aria-label="Close modal"
                >
                  <Icon name="mdi:close" class="w-5 h-5" />
                </button>
              </header>

              <!-- Body -->
              <main
                :class="[
                  'flex-1',
                  scrollable ? 'overflow-y-auto' : '',
                  $slots.footer || !hideFooter ? 'p-6' : 'p-6 pb-6'
                ]"
              >
                <slot name="body">
                  <slot />
                </slot>
              </main>

              <!-- Footer -->
              <footer
                v-if="!hideFooter && ($slots.footer || $slots.actions)"
                class="flex items-center justify-end space-x-3 p-6 border-t border-gray-200 dark:border-gray-600 bg-gray-50 dark:bg-gray-700/50"
              >
                <slot name="footer">
                  <slot name="actions">
                    <rs-button
                      variant="secondary-outline"
                      @click="cancelAction"
                      :disabled="loading"
                    >
                      Cancel
                    </rs-button>
                    <rs-button
                      variant="primary"
                      @click="confirmAction"
                      :disabled="loading"
                    >
                      Confirm
                    </rs-button>
                  </slot>
                </slot>
              </footer>
            </div>
          </div>
        </Transition>
      </div>
    </Transition>
  </Teleport>
</template>

<style scoped>
/* Enhanced scrollbar for modal content */
main::-webkit-scrollbar {
  width: 6px;
}

main::-webkit-scrollbar-track {
  background: transparent;
}

main::-webkit-scrollbar-thumb {
  background-color: rgba(156, 163, 175, 0.5);
  border-radius: 3px;
}

main::-webkit-scrollbar-thumb:hover {
  background-color: rgba(156, 163, 175, 0.7);
}

/* Dark mode scrollbar */
.dark main::-webkit-scrollbar-thumb {
  background-color: rgba(75, 85, 99, 0.5);
}

.dark main::-webkit-scrollbar-thumb:hover {
  background-color: rgba(75, 85, 99, 0.7);
}
</style> 