import { PktElementWithSlot } from '@/base-elements/element-with-slot'
import { slotContent } from '@/directives/slot-content'
import { html, nothing, PropertyValues } from 'lit'
import { customElement, property } from 'lit/decorators.js'
import { ifDefined } from 'lit/directives/if-defined.js'
import {
  User,
  Representing,
  UserMenuItem,
  THeaderMenu,
  TLogOutButtonPlacement,
  THeaderPosition,
  THeaderScrollBehavior,
  TSlotMenuVariant,
  IPktHeader,
  Booleanish,
  booleanishConverter,
} from './types'

import './header-service'

/**
 * PktHeader - Main header component for Oslo kommune services
 *
 * This component provides a complete header solution with:
 * - Logo and service name
 * - User menu with login/logout functionality
 * - Search functionality
 * - Responsive mobile menu
 * - Fixed positioning with scroll-to-hide
 *
 * TODO: Add `type` prop to switch between `service` and `global` header types
 */
export class PktHeader extends PktElementWithSlot<IPktHeader> implements IPktHeader {
  @property({ type: String, attribute: 'service-name' }) serviceName?: string
  @property({ type: String, attribute: 'service-link' }) serviceLink?: string
  @property({ type: String, attribute: 'logo-link' }) logoLink?: string
  @property({ type: String, attribute: 'search-placeholder' }) searchPlaceholder = 'Søk'
  @property({ type: String, attribute: 'search-value' }) searchValue = ''
  @property({ type: Number, attribute: 'mobile-breakpoint' }) mobileBreakpoint: number = 768
  @property({ type: Number, attribute: 'tablet-breakpoint' }) tabletBreakpoint: number = 1280
  @property({ type: String, attribute: 'opened-menu' }) openedMenu: THeaderMenu = 'none'
  @property({ type: String, attribute: 'log-out-button-placement' })
  logOutButtonPlacement: TLogOutButtonPlacement = 'none'
  @property({ type: String }) position: THeaderPosition = 'fixed'
  @property({ type: String, attribute: 'scroll-behavior' }) scrollBehavior: THeaderScrollBehavior =
    'hide'
  @property({ type: String, attribute: 'slot-menu-variant' })
  slotMenuVariant: TSlotMenuVariant = 'icon-only'
  @property({ type: String, attribute: 'slot-menu-text' }) slotMenuText = 'Meny'

  @property({ type: Boolean, attribute: 'hide-logo', converter: booleanishConverter })
  hideLogo: Booleanish = false
  @property({ type: Boolean, converter: booleanishConverter }) compact: Booleanish = false
  @property({ type: Boolean, attribute: 'show-search', converter: booleanishConverter })
  showSearch: Booleanish = false
  @property({
    type: Boolean,
    attribute: 'can-change-representation',
    converter: booleanishConverter,
  })
  canChangeRepresentation: Booleanish = false
  @property({ type: Boolean, attribute: 'has-log-out', converter: booleanishConverter })
  hasLogOut: Booleanish = false

  @property({ type: Object }) user?: User
  @property({ type: Array, attribute: 'user-menu' }) userMenu?: UserMenuItem[]
  @property({ type: Object }) representing?: Representing

  // Deprecated props - emit warnings
  @property({ type: Array, attribute: 'user-menu-footer' }) userMenuFooter?: UserMenuItem[]
  @property({ type: Array, attribute: 'user-options' }) userOptions?: UserMenuItem[]

  firstUpdated(changedProperties: PropertyValues) {
    super.firstUpdated(changedProperties)
    this.emitDeprecationWarnings()
  }

  private emitDeprecationWarnings() {
    if (this.userMenuFooter !== undefined) {
      // eslint-disable-next-line no-console -- Deprecation warnings are intentional for library consumers
      console.warn('[PktHeader] userMenuFooter is deprecated. Use userMenu instead.')
    }
    if (this.userOptions !== undefined) {
      // eslint-disable-next-line no-console -- Deprecation warnings are intentional for library consumers
      console.warn('[PktHeader] userOptions is deprecated. Use userMenu instead.')
    }
  }

  /**
   * Convert deprecated props to new props
   */
  private get effectiveUserMenu(): UserMenuItem[] | undefined {
    const menu = this.userMenu || []
    const footer = this.userMenuFooter || []
    const options = this.userOptions || []

    if (footer.length || options.length) {
      return [...menu, ...options, ...footer]
    }
    return this.userMenu
  }

  render() {
    return html`
      <pkt-header-service
        service-name=${ifDefined(this.serviceName)}
        service-link=${ifDefined(this.serviceLink)}
        logo-link=${ifDefined(this.logoLink)}
        search-placeholder=${this.searchPlaceholder}
        search-value=${this.searchValue}
        mobile-breakpoint=${this.mobileBreakpoint}
        tablet-breakpoint=${this.tabletBreakpoint}
        opened-menu=${this.openedMenu}
        log-out-button-placement=${this.logOutButtonPlacement}
        position=${this.position}
        scroll-behavior=${this.scrollBehavior}
        slot-menu-variant=${this.slotMenuVariant}
        slot-menu-text=${this.slotMenuText}
        .hideLogo=${this.hideLogo}
        .compact=${this.compact}
        .showSearch=${this.showSearch}
        .canChangeRepresentation=${this.canChangeRepresentation}
        .hasLogOut=${this.hasLogOut}
        .user=${this.user}
        .userMenu=${this.effectiveUserMenu}
        .representing=${this.representing}
      >
        ${this.hasSlotContent()
          ? html`<div class="pkt-contents">${slotContent(this)}</div>`
          : nothing}
      </pkt-header-service>
    `
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'pkt-header': PktHeader
  }
}

try {
  customElement('pkt-header')(PktHeader)
} catch (e) {
  console.warn('Forsøker å definere <pkt-header>, men den er allerede definert')
}
