// If you want to use Phoenix channels, run `mix help phx.gen.channel`
// to get started and then uncomment the line below.
// import "./user_socket.js"

// You can include dependencies in two ways.
//
// The simplest option is to put them in assets/vendor and
// import them using relative paths:
//
//     import "../vendor/some-package.js"
//
// Alternatively, you can `npm install some-package --prefix assets` and import
// them using a path starting with the package name:
//
//     import "some-package"
//

// Include phoenix_html to handle method=PUT/DELETE in forms and buttons.
import "phoenix_html"
// Establish Phoenix Socket and LiveView configuration.
import {Socket} from "phoenix"
import {LiveSocket} from "phoenix_live_view"
import topbar from "../vendor/topbar"

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")

// Hooks for LiveView components
let Hooks = {}

// CopyToClipboard hook: Copies text to clipboard when triggered by server event
Hooks.CopyToClipboard = {
  mounted() {
    this.handleEvent("copy_to_clipboard", ({text}) => {
      if (navigator.clipboard) {
        navigator.clipboard.writeText(text).catch(err => {
          console.error("Clipboard write failed:", err)
        })
      } else {
        // Fallback for older browsers
        const textArea = document.createElement("textarea")
        textArea.value = text
        textArea.style.position = "fixed"
        textArea.style.left = "-999999px"
        document.body.appendChild(textArea)
        textArea.select()
        try {
          document.execCommand("copy")
        } catch (err) {
          console.error("Fallback clipboard copy failed:", err)
        }
        document.body.removeChild(textArea)
      }
    })
  }
}

// ComboBox hook: Prevents form submission when Enter is pressed in dropdown
Hooks.ComboBox = {
  mounted() {
    this.handleKeyDown = (e) => {
      const isDropdownOpen = this.el.getAttribute("aria-expanded") === "true"
      
      if (e.key === "Enter" && isDropdownOpen) {
        e.preventDefault()
      }
    }
    
    this.el.addEventListener("keydown", this.handleKeyDown)
  },
  
  destroyed() {
    this.el.removeEventListener("keydown", this.handleKeyDown)
  }
}

// SidebarState hook: Manages sidebar expanded/collapsed state
Hooks.SidebarState = {
  mounted() {
    // Restore state from localStorage
    const expanded = localStorage.getItem('sidebar-expanded') !== 'false'
    this.setSidebarState(expanded)
    
    // Expose toggle function globally
    window.toggleSidebar = () => {
      const current = this.el.dataset.sidebarExpanded === 'true'
      this.setSidebarState(!current)
    }
  },
  
  setSidebarState(expanded) {
    // Convert boolean to string for consistency
    const expandedStr = expanded ? 'true' : 'false'
    
    // Update data-attribute (CSS reacts to this)
    this.el.dataset.sidebarExpanded = expandedStr
    
    // Persist to localStorage
    localStorage.setItem('sidebar-expanded', expandedStr)
    
    // Update ARIA for accessibility
    const toggleBtn = document.getElementById('sidebar-toggle')
    if (toggleBtn) {
      toggleBtn.setAttribute('aria-expanded', expandedStr)
    }
  },
  
  destroyed() {
    // Cleanup
    delete window.toggleSidebar
  }
}

let liveSocket = new LiveSocket("/live", Socket, {
  longPollFallbackMs: 2500,
  params: {_csrf_token: csrfToken},
  hooks: Hooks
})

// Listen for custom events from LiveView
window.addEventListener("phx:set-input-value", (e) => {
  const {id, value} = e.detail
  const input = document.getElementById(id)
  if (input) {
    input.value = value
  }
})

// Show progress bar on live navigation and form submits
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
window.addEventListener("phx:page-loading-start", _info => topbar.show(300))
window.addEventListener("phx:page-loading-stop", _info => topbar.hide())

// connect if there are any LiveViews on the page
liveSocket.connect()

// expose liveSocket on window for web console debug logs and latency simulation:
// >> liveSocket.enableDebug()
// >> liveSocket.enableLatencySim(1000)  // enabled for duration of browser session
// >> liveSocket.disableLatencySim()
window.liveSocket = liveSocket

// Sidebar accessibility improvements
document.addEventListener("DOMContentLoaded", () => {
  const drawerToggle = document.getElementById("mobile-drawer")
  const sidebarToggle = document.getElementById("sidebar-toggle")
  const sidebar = document.getElementById("main-sidebar")
  
  if (!drawerToggle || !sidebarToggle || !sidebar) return
  
  // Manage tabindex for sidebar elements based on open/closed state
  const updateSidebarTabIndex = (isOpen) => {
    // Find all potentially focusable elements (including those with tabindex="-1")
    const allFocusableElements = sidebar.querySelectorAll(
      'a[href], button, select, input:not([type="hidden"]), [tabindex]'
    )
    
    allFocusableElements.forEach(el => {
      // Skip the overlay button
      if (el.closest('.drawer-overlay')) return
      
      if (isOpen) {
        // Remove tabindex="-1" to make focusable when open
        if (el.hasAttribute('tabindex') && el.getAttribute('tabindex') === '-1') {
          el.removeAttribute('tabindex')
        }
      } else {
        // Set tabindex="-1" to remove from tab order when closed
        if (!el.hasAttribute('tabindex')) {
          el.setAttribute('tabindex', '-1')
        } else if (el.getAttribute('tabindex') !== '-1') {
          // Store original tabindex in data attribute before setting to -1
          if (!el.hasAttribute('data-original-tabindex')) {
            el.setAttribute('data-original-tabindex', el.getAttribute('tabindex'))
          }
          el.setAttribute('tabindex', '-1')
        }
      }
    })
  }
  
  // Find first focusable element in sidebar
  // Priority: first navigation link (menuitem) > other links > other focusable elements
  const getFirstFocusableElement = () => {
    // First, try to find the first navigation link (menuitem)
    const firstNavLink = sidebar.querySelector('a[href][role="menuitem"]:not([tabindex="-1"])')
    if (firstNavLink && !firstNavLink.closest('.drawer-overlay')) {
      return firstNavLink
    }
    
    // Fallback: any navigation link
    const firstLink = sidebar.querySelector('a[href]:not([tabindex="-1"])')
    if (firstLink && !firstLink.closest('.drawer-overlay')) {
      return firstLink
    }
    
    // Last resort: any other focusable element
    const focusableSelectors = [
      'button:not([tabindex="-1"]):not([disabled])',
      'select:not([tabindex="-1"]):not([disabled])',
      'input:not([tabindex="-1"]):not([disabled]):not([type="hidden"])',
      '[tabindex]:not([tabindex="-1"])'
    ]
    
    for (const selector of focusableSelectors) {
      const element = sidebar.querySelector(selector)
      if (element && !element.closest('.drawer-overlay')) {
        return element
      }
    }
    return null
  }
  
  // Update aria-expanded when drawer state changes
  const updateAriaExpanded = () => {
    const isOpen = drawerToggle.checked
    sidebarToggle.setAttribute("aria-expanded", isOpen.toString())
    
    // Update dropdown aria-expanded if present
    const userMenuButton = sidebar.querySelector('button[aria-haspopup="true"]')
    if (userMenuButton) {
      const dropdown = userMenuButton.closest('.dropdown')
      const isDropdownOpen = dropdown?.classList.contains('dropdown-open')
      if (userMenuButton) {
        userMenuButton.setAttribute("aria-expanded", (isDropdownOpen || false).toString())
      }
    }
  }
  
  // Listen for changes to the drawer checkbox
  drawerToggle.addEventListener("change", () => {
    const isOpen = drawerToggle.checked
    updateAriaExpanded()
    updateSidebarTabIndex(isOpen)
    if (!isOpen) {
      // When closing, return focus to toggle button
      sidebarToggle.focus()
    }
  })
  
  // Update on initial load
  updateAriaExpanded()
  updateSidebarTabIndex(drawerToggle.checked)
  
  // Close sidebar with ESC key
  document.addEventListener("keydown", (e) => {
    if (e.key === "Escape" && drawerToggle.checked) {
      drawerToggle.checked = false
      updateAriaExpanded()
      updateSidebarTabIndex(false)
      // Return focus to toggle button
      sidebarToggle.focus()
    }
  })
  
  // Improve keyboard navigation for sidebar toggle
  sidebarToggle.addEventListener("keydown", (e) => {
    if (e.key === "Enter" || e.key === " ") {
      e.preventDefault()
      const wasOpen = drawerToggle.checked
      drawerToggle.checked = !drawerToggle.checked
      updateAriaExpanded()
      
      // If opening, move focus to first element in sidebar
      if (!wasOpen && drawerToggle.checked) {
        updateSidebarTabIndex(true)
        // Use setTimeout to ensure DOM is updated
        setTimeout(() => {
          const firstElement = getFirstFocusableElement()
          if (firstElement) {
            firstElement.focus()
          }
        }, 50)
      } else if (wasOpen && !drawerToggle.checked) {
        updateSidebarTabIndex(false)
      }
    }
  })
  
  // Also handle click events to update tabindex and focus
  sidebarToggle.addEventListener("click", () => {
    setTimeout(() => {
      const isOpen = drawerToggle.checked
      updateSidebarTabIndex(isOpen)
      if (isOpen) {
        const firstElement = getFirstFocusableElement()
        if (firstElement) {
          firstElement.focus()
        }
      }
    }, 50)
  })
  
  // Handle dropdown keyboard navigation
  const userMenuButton = sidebar?.querySelector('button[aria-haspopup="true"]')
  if (userMenuButton) {
    userMenuButton.addEventListener("click", () => {
      setTimeout(updateAriaExpanded, 0)
    })
    
    userMenuButton.addEventListener("keydown", (e) => {
      if (e.key === "Enter" || e.key === " ") {
        e.preventDefault()
        userMenuButton.click()
      }
    })
  }
})

