// resources/js/composables/Core/useNavigate.js
import { getCurrentInstance, h } from 'vue'
import { encodeHash, encodePayload } from '../useUrlEncoder'
import { useUIStore } from '../../stores/ui'
import { useModal } from './useModal'

// Page module map — populated once from app.js for prefetching
let _pageModules = null;
export function setPageModules(modules) { _pageModules = modules; }

// Track which pages have already been prefetched to avoid duplicate calls
const _prefetchedPages = new Set();

export function useNavigate({ currentPage, currentProps, loading } = {}) {
  const instance = getCurrentInstance()
  const uiStore = useUIStore()
  const modal = useModal()
  // Try to get the global navigate helper first from window.$navigateHelper,
  // then fall back to instance?.proxy?.$navigate
  const globalNavigate = (window.$navigateHelper || instance?.proxy?.$navigate)

  /**
   * Prefetch a page component chunk by name.
   * Call on hover/focus to start loading the JS bundle before navigation.
   */
  const prefetch = (pageName) => {
    if (!pageName || !_pageModules || _prefetchedPages.has(pageName)) return;
    const loader = _pageModules[pageName];
    if (loader) {
      _prefetchedPages.add(pageName);
      loader().catch(() => { /* chunk may not exist, ignore */ });
    }
  }

  const navigate = async (arg1, arg2 = {}) => {
    // Universal navigate handler that accepts:
    // 1. navigate({ page: 'Home', props: {} })
    // 2. navigate('Home', { target: '...' })
    let page, props, delay, fromPopState;
    
    if (typeof arg1 === 'string') {
      page = arg1;
      props = arg2.props || arg2 || {};
      delay = arg2.delay || 0;
      fromPopState = arg2.fromPopState || false;
    } else {
      ({ page, props = {}, delay = 0, fromPopState = false } = arg1);
    }

    if (!page) {
      console.error('[useNavigate] Navigation failed: No page specified.', { arg1, arg2 });
      return;
    }

    // Global Page Disabled Check — fire-and-forget refresh if stale (don't block navigation)
    const cacheThreshold = 30 * 1000; // 30 seconds
    const isStale = !uiStore.lastSynced || (new Date() - new Date(uiStore.lastSynced) > cacheThreshold);
    
    if (isStale) {
      // Non-blocking: refresh in background, don't await
      uiStore.refreshSettings().catch(e => {
        console.error('[useNavigate] Failed to refresh settings during navigation:', e);
      });
    }

    const pageLower = page.toLowerCase();
    const isDisabled = uiStore.disabledPages && uiStore.disabledPages.some(p => p.toLowerCase() === pageLower);

    if (isDisabled) {
      console.warn(`[useNavigate] Page ${page} is globally disabled.`);
      
      modal.open({
        title: 'Access Restricted',
        body: h('div', { class: 'text-center p-4' }, [
          h('div', { class: 'icon-shape bg-soft-danger text-danger rounded-circle mx-auto mb-4 p-3 shadow-sm' }, [
            h('i', { class: 'fas fa-lock fa-3x' })
          ]),
          h('h4', { class: 'fw-black mb-3 text-dark' }, 'Page Offline'),
          h('p', { class: 'text-muted mb-4 px-3' }, `The requested page (${page}) has been temporarily disabled by the system administrator.`),
          h('button', { 
            class: 'btn btn-primary rounded-pill px-5 py-2 fw-bold shadow-primary-sm',
            onClick: () => {
              modal.close();
              if (pageLower !== 'home') navigate({ page: 'Home' });
            }
          }, 'Back to Dashboard')
        ]),
        footer: null
      });
      
      if (loading) loading.value = false;
      return;
    }

    // If local refs are provided (root app usage), update them directly
    if (currentPage || currentProps || loading) {
      if (loading) loading.value = true

      if (delay) await new Promise(r => setTimeout(r, delay))

      if (currentPage) currentPage.value = page
      if (currentProps) currentProps.value = props

      // Update browser URL (only if NOT coming from a popstate event)
      if (!fromPopState) {
        let url;
        if (page === 'Home') {
          url = '/';
        } else if (page === 'Auth.Login') {
          url = '/login';
        } else {
          // Check for special props that should be encoded into URL
          const hashkeyProp = props?.target || props?.target_user || props?.hashkey || props?.id;
          const payloadProp = props?.payload;

          let basePageUrl = `/${page
            .replace(/\./g, '/')
            .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
            .toLowerCase()}`;
          
          if (hashkeyProp) {
            // Encode the hashkey into URL as --h:ENCODED
            const encodedHash = encodeHash(hashkeyProp);
            url = `${basePageUrl}--${encodedHash}`;  
          } else if (payloadProp) {
            // Encode the payload into URL as --e:ENCODED_PAYLOAD
            const encodedPayload = encodePayload(payloadProp);
            url = `${basePageUrl}--${encodedPayload}`;  
          } else {
            url = basePageUrl;
          }
        }
        window.history.pushState({ page, props }, '', url);
      }

      if (loading) loading.value = false
      return
    }

    // In child components, fall back to the global $navigate helper
    if (globalNavigate) {
      globalNavigate({ page, props, delay, fromPopState })
    } else {
      console.warn('[useNavigate] No local refs and global navigate helper not found.')
    }
  }

  const reloadPage = () => {
    if (currentPage) {
      navigate({ page: currentPage.value, props: currentProps?.value, delay: 0 })
    } else if (globalNavigate) {
      // In children, we can't easily get 'currentPage' unless we pass it or use a store
      // but usually reloadPage is used in the context that knows the current state.
      console.warn('[useNavigate] reloadPage called in child without refs.')
    }
  }

  return { navigate, reloadPage, prefetch }
}

/**
 * Helper to derive component name from a URL path in a generic way.
 * Matches the logic in VueRouteMap.php.
 */
const getPageFromUrl = (path) => {
  let cleanPath = path.trim().replace(/^\/+|\/+$/g, '');
  if (!cleanPath) return 'Home';
  
  // Handle explicit common mappings
  if (cleanPath === 'login') return 'Auth.Login';
  if (cleanPath === 'app') return 'Home';

  // Strip hash/payload suffix (e.g., "view-store-market--h:ABC" -> "view-store-market")
  const slug = cleanPath.split('--h:')[0].split('--e:')[0];
  
  // Convert kebab-case/path to PascalCase/dots (e.g., "market/list-products" -> "Market.ListProducts")
  return slug.split('/').map(part => {
    return part.split('-').map(subPart => {
      if (!subPart) return '';
      return subPart.charAt(0).toUpperCase() + subPart.slice(1);
    }).join('');
  }).join('.');
}

// Global popstate listener to handle browser back button
if (typeof window !== 'undefined') {
  window.addEventListener('popstate', (event) => {
    if (event.state && event.state.page) {
      if (window.$navigateHelper) {
        window.$navigateHelper({
          page: event.state.page,
          props: event.state.props,
          fromPopState: true,
          delay: 0
        })
      } else {
        // Fallback if app not yet initialized
        window.location.reload()
      }
    } else {
      // If no state (initial load entry point), attempt to restore from initial DOM payload
      const el = document.getElementById('main-body');
      if (el && el.dataset.page) {
        try {
          const initialPage = JSON.parse(el.dataset.page);
          if (window.$navigateHelper) {
            window.$navigateHelper({
              page: initialPage.component,
              props: initialPage.props,
              fromPopState: true,
              delay: 0
            });
            return;
          }
        } catch (e) {
          console.error('[useNavigate] Failed to parse initial page from DOM:', e);
        }
      }
      
      // Ultimate Fallback: Derive the page from the URL (without props, as we can't reliably decode them here)
      const page = getPageFromUrl(window.location.pathname);
      if (window.$navigateHelper) {
        window.$navigateHelper({ page, fromPopState: true, delay: 0 })
      }
    }
  })
}
