'use client'

import Link from 'next/link'
import { usePathname } from 'next/navigation'
import type { ReactNode } from 'react'
import { useEffect, useLayoutEffect, useState } from 'react'
import {
  LayoutDashboard,
  Car,
  Calendar,
  Globe,
  Users,
  Tag,
  UserPlus,
  BarChart2,
  CreditCard,
  Bell,
  Settings,
  LogOut,
  FileText,
  ChevronLeft,
  ChevronRight,
  Star,
  AlertTriangle,
} from 'lucide-react'
import { DashboardLanguageSwitcher, DashboardThemeSwitcher, useDashboardI18n } from '@/components/I18nProvider'
import { carplaceUrl } from '@/lib/urls'
import { EMPLOYEE_PROFILE_KEY, apiFetch } from '@/lib/api'
import { toDashboardAppPath } from '@/lib/dashboardPaths'
import { SHARED_LANGUAGE_KEY, readCurrentUserScopedPreference } from '@/lib/preferences'

interface BrandSettings {
  displayName: string
  logoUrl: string | null
}

interface CompanySummary {
  name: string
  brand?: {
    displayName?: string | null
    logoUrl?: string | null
  } | null
}

interface SidebarUser {
  displayName: string
  subtitle: string
  initials: string
}
interface EmployeeProfile {
  email: string
  firstName: string
  lastName: string
  role: string
  preferredLanguage?: string
}

interface GeneratedMenuItem {
  id: string
  systemKey: string | null
  label: string
  itemType: 'INTERNAL_PAGE' | 'EXTERNAL_LINK' | 'PARENT_MENU' | 'SECTION_LABEL' | 'DIVIDER'
  routeOrUrl: string | null
  icon: string | null
  parentId: string | null
  openInNewTab: boolean
  displayOrder: number
  children: GeneratedMenuItem[]
}

type SubscriptionAccessLevel = 'full' | 'limited' | 'read_only' | 'none'

function computeInitials(name: string): string {
  const parts = name.trim().split(/\s+/).filter(Boolean)
  if (parts.length === 0) return 'U'
  if (parts.length === 1) return parts[0].slice(0, 1).toUpperCase()
  return `${parts[0].slice(0, 1)}${parts[1].slice(0, 1)}`.toUpperCase()
}

function toSidebarUser(profile: Partial<EmployeeProfile>, fallbackName: string, fallbackSubtitle: string): SidebarUser {
  const fullName = `${profile.firstName ?? ''} ${profile.lastName ?? ''}`.trim()
  const email = profile.email ?? ''
  const role = profile.role ?? ''
  const displayName = fullName || (email ? email.split('@')[0] : fallbackName)
  const subtitle = email || role || fallbackSubtitle
  const initials = computeInitials(fullName || email || fallbackName)
  return { displayName, subtitle, initials }
}

const NAV_ITEMS = [
  { href: '/', key: 'dashboard', icon: LayoutDashboard, exact: true, minRole: 'AGENT' },
  { href: '/reservations', key: 'reservations', icon: Calendar, minRole: 'AGENT' },
  { href: '/fleet', key: 'fleet', icon: Car, minRole: 'AGENT' },
  { href: '/customers', key: 'customers', icon: Users, minRole: 'AGENT' },
  { href: '/reports', key: 'reports', icon: BarChart2, minRole: 'MANAGER' },
  { href: '/billing', key: 'billing', icon: CreditCard, minRole: 'MANAGER' },
  { href: '/settings', key: 'settings', icon: Settings, minRole: 'OWNER' },
] as const

const OWNER_SYSTEM_NAV_ITEMS = [
  { href: '/subscription', key: 'subscription', icon: 'CreditCard', minRole: 'OWNER' },
] as const

export const APPROVED_BASELINE_MENU_KEYS = NAV_ITEMS.map((item) => item.key)

const ICON_MAP = {
  LayoutDashboard,
  Car,
  Calendar,
  Globe,
  Users,
  Tag,
  UserPlus,
  BarChart2,
  CreditCard,
  Bell,
  Settings,
  FileText,
  Star,
  AlertTriangle,
} as const

const SIDEBAR_BRAND_KEY = 'dashboard_brand'

const ROLE_RANK: Record<string, number> = { OWNER: 3, MANAGER: 2, AGENT: 1 }

function hasMinRole(employeeRole: string, minRole: string): boolean {
  return (ROLE_RANK[employeeRole] ?? 0) >= (ROLE_RANK[minRole] ?? 0)
}

export function hasRenderableMenuItems(items: GeneratedMenuItem[] | null): boolean {
  if (!items?.length) return false

  return items.some((item) => {
    if (item.itemType === 'DIVIDER' || item.itemType === 'SECTION_LABEL') return false
    if (item.itemType === 'PARENT_MENU') return hasRenderableMenuItems(item.children)
    return Boolean(item.routeOrUrl)
  })
}

export function shouldUseGeneratedMenu(
  menuLoadState: 'loading' | 'loaded' | 'failed',
  items: GeneratedMenuItem[] | null,
  subscriptionAccessLevel: SubscriptionAccessLevel | null = null,
): boolean {
  if (menuLoadState !== 'loaded') return false
  if (subscriptionAccessLevel === 'none') return true
  return hasRenderableMenuItems(items)
}

function notifyParent(message: Record<string, unknown>) {
  if (typeof window === 'undefined' || window.parent === window) return
  window.parent.postMessage(message, '*')
}

export default function Sidebar() {
  const { dict, language, setLanguage } = useDashboardI18n()
  const isRtl = language === 'ar'
  const pathname = usePathname()
  const appPath = toDashboardAppPath(pathname)
  const [brand, setBrand] = useState<BrandSettings | null>(null)
  const [user, setUser] = useState<SidebarUser>({
    displayName: dict.workspaceUser,
    subtitle: dict.localAuth,
    initials: 'W',
  })
  const [role, setRole] = useState<string>('AGENT')
  const [menuItems, setMenuItems] = useState<GeneratedMenuItem[] | null>(null)
  const [menuAccessLevel, setMenuAccessLevel] = useState<SubscriptionAccessLevel | null>(null)
  const [menuLoadState, setMenuLoadState] = useState<'loading' | 'loaded' | 'failed'>('loading')
  const [open, setOpen] = useState(false)
  const [mounted, setMounted] = useState(false)

  useEffect(() => { setMounted(true) }, [])

  useLayoutEffect(() => {
    try {
      const cached = window.localStorage.getItem(SIDEBAR_BRAND_KEY)
      if (!cached) return
      const parsed = JSON.parse(cached) as Partial<BrandSettings>
      if (typeof parsed.displayName === 'string' && parsed.displayName.trim()) {
        setBrand({
          displayName: parsed.displayName,
          logoUrl: typeof parsed.logoUrl === 'string' ? parsed.logoUrl : null,
        })
      }
    } catch {}
  }, [])

  useEffect(() => {
    let cancelled = false

    async function loadBrand() {
      try {
        const brandData = await apiFetch<BrandSettings | null>('/companies/me/brand')
        if (cancelled) return
        if (brandData?.displayName?.trim()) {
          setBrand(brandData)
          window.localStorage.setItem(SIDEBAR_BRAND_KEY, JSON.stringify(brandData))
          return
        }
      } catch {}

      try {
        const company = await apiFetch<CompanySummary>('/companies/me')
        if (cancelled) return

        const resolvedBrand: BrandSettings = {
          displayName: company.brand?.displayName?.trim() || company.name,
          logoUrl: company.brand?.logoUrl ?? null,
        }

        setBrand(resolvedBrand)
        window.localStorage.setItem(SIDEBAR_BRAND_KEY, JSON.stringify(resolvedBrand))
      } catch {}
    }

    loadBrand()

    return () => { cancelled = true }
  }, [])

  useEffect(() => {
    const cached = window.localStorage.getItem(EMPLOYEE_PROFILE_KEY)
    if (cached) {
      try {
        const profile = JSON.parse(cached) as Partial<EmployeeProfile>
        setUser(toSidebarUser(profile, dict.workspaceUser, dict.localAuth))
        if (profile.role) setRole(profile.role)
      } catch {}
    }

    let cancelled = false

    Promise.all([
      apiFetch<{ employee: EmployeeProfile }>('/auth/employee/me'),
      apiFetch<{ items: GeneratedMenuItem[]; subscriptionAccessLevel?: SubscriptionAccessLevel }>('/auth/employee/menu').catch(() => null),
    ])
      .then(([{ employee }, menu]) => {
        if (cancelled) return
        window.localStorage.setItem(EMPLOYEE_PROFILE_KEY, JSON.stringify(employee))
        setUser(toSidebarUser(employee, dict.workspaceUser, dict.localAuth))
        if (employee.role) setRole(employee.role)
        if (menu) {
          setMenuItems(menu.items)
          setMenuAccessLevel(menu.subscriptionAccessLevel ?? null)
          setMenuLoadState('loaded')
        } else {
          setMenuAccessLevel(null)
          setMenuLoadState('failed')
        }
        if (employee.preferredLanguage === 'en' || employee.preferredLanguage === 'fr' || employee.preferredLanguage === 'ar') {
          // Only apply the server-side preference when the employee has no local preference
          // stored yet — avoids overriding a language the user manually switched to.
          const existingPref = readCurrentUserScopedPreference(SHARED_LANGUAGE_KEY)
          if (!existingPref) {
            setLanguage(employee.preferredLanguage)
            document.cookie = `rentaldrivego-language=${employee.preferredLanguage}; path=/; max-age=31536000; samesite=lax`
          }
        }
      })
      .catch(() => {
        if (cancelled) return
        if (!cached) setUser(toSidebarUser({}, dict.workspaceUser, dict.localAuth))
        setMenuAccessLevel(null)
        setMenuLoadState('failed')
      })

    return () => { cancelled = true }
  }, [dict.localAuth, dict.workspaceUser])

  // Close sidebar when navigating on mobile
  useEffect(() => { setOpen(false) }, [pathname])

  const isActive = (item: typeof NAV_ITEMS[number]) => {
    if ('exact' in item && item.exact) return appPath === item.href
    return appPath.startsWith(item.href)
  }

  const isGeneratedItemActive = (item: GeneratedMenuItem) => {
    if (!item.routeOrUrl || item.itemType !== 'INTERNAL_PAGE') return false
    const route = toDashboardAppPath(item.routeOrUrl)
    if (route === '/') return appPath === '/'
    return appPath === route || appPath.startsWith(`${route}/`)
  }

  const fallbackMenuItems = NAV_ITEMS
    .filter((item) => !mounted || hasMinRole(role, item.minRole))
    .map((item) => ({
      id: item.href,
      systemKey: item.key,
      label: dict.nav[item.key] ?? item.key,
      itemType: 'INTERNAL_PAGE' as const,
      routeOrUrl: item.href,
      icon: item.icon.name,
      parentId: null,
      openInNewTab: false,
      displayOrder: 0,
      children: [],
    }))

  const useGeneratedMenu = shouldUseGeneratedMenu(menuLoadState, menuItems, menuAccessLevel)
  const ownerSystemMenuItems = OWNER_SYSTEM_NAV_ITEMS
    .filter((item) => !mounted || hasMinRole(role, item.minRole))
    .map((item) => ({
      id: `system:${item.href}`,
      systemKey: item.key,
      label: dict.nav[item.key] ?? item.key,
      itemType: 'INTERNAL_PAGE' as const,
      routeOrUrl: item.href,
      icon: item.icon,
      parentId: null,
      openInNewTab: false,
      displayOrder: 0,
      children: [],
    }))
  const generatedMenuItems = useGeneratedMenu ? (menuItems ?? []) : fallbackMenuItems
  const generatedRoutes = new Set(
    generatedMenuItems
      .filter((item) => item.itemType === 'INTERNAL_PAGE' && item.routeOrUrl)
      .map((item) => toDashboardAppPath(item.routeOrUrl)),
  )
  const resolvedMenuItems = [
    ...generatedMenuItems,
    ...ownerSystemMenuItems.filter((item) => !generatedRoutes.has(toDashboardAppPath(item.routeOrUrl))),
  ]

  function renderGeneratedMenu(items: GeneratedMenuItem[], depth = 0): ReactNode {
    return items.map((item) => {
      const label = item.systemKey ? (dict.nav[item.systemKey] ?? item.label) : item.label
      const paddingClass = depth > 0 ? 'pl-6' : ''
      const Icon = item.icon && item.icon in ICON_MAP ? ICON_MAP[item.icon as keyof typeof ICON_MAP] : null

      if (item.itemType === 'DIVIDER') {
        return <div key={item.id} className="mx-3 my-3 h-px bg-gradient-to-r from-transparent via-blue-400/20 to-transparent" />
      }

      if (item.itemType === 'SECTION_LABEL') {
        return (
          <p key={item.id} className="px-3 py-2 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500">
            {label}
          </p>
        )
      }

      if (item.itemType === 'PARENT_MENU') {
        return (
          <div key={item.id} className="space-y-1">
            <div className={`flex items-center gap-3 rounded-lg px-3.5 py-2.5 text-sm font-medium text-slate-600 dark:text-slate-300 ${paddingClass}`}>
              {Icon ? <Icon className="h-4 w-4 flex-shrink-0" /> : null}
              {label}
            </div>
            <div className="space-y-0.5">{renderGeneratedMenu(item.children, depth + 1)}</div>
          </div>
        )
      }

      const active = mounted && isGeneratedItemActive(item)
      const className = [
        'relative flex items-center gap-3 rounded-lg px-3.5 py-3 text-sm font-medium transition-all duration-200',
        paddingClass,
        active
          ? 'bg-blue-500/10 text-blue-950 shadow-[inset_2px_0_0_#3b82f6,0_0_18px_rgba(59,130,246,0.10)] dark:text-slate-50'
          : 'text-slate-500 hover:bg-blue-500/10 hover:text-blue-950 dark:text-slate-400 dark:hover:text-slate-50',
      ].join(' ')

      if (item.itemType === 'EXTERNAL_LINK' && item.routeOrUrl) {
        return (
          <a
            key={item.id}
            href={item.routeOrUrl}
            target={item.openInNewTab ? '_blank' : '_self'}
            rel={item.openInNewTab ? 'noreferrer noopener' : undefined}
            className={className}
          >
            {Icon ? <Icon className="h-4 w-4 flex-shrink-0" /> : null}
            {label}
          </a>
        )
      }

      const href = item.itemType === 'INTERNAL_PAGE' ? toDashboardAppPath(item.routeOrUrl) : (item.routeOrUrl || '/')

      return (
        <Link key={item.id} href={href} className={className}>
          {Icon ? <Icon className="h-4 w-4 flex-shrink-0" /> : null}
          {label}
        </Link>
      )
    })
  }

  function signOut() {
    localStorage.removeItem(EMPLOYEE_PROFILE_KEY)
    void fetch('/dashboard/api/v1/auth/employee/logout', { method: 'POST', credentials: 'include' })
    window.dispatchEvent(new CustomEvent('rentaldrivego:auth-changed'))
    notifyParent({ type: 'rentaldrivego:employee-logout' })
    window.location.href = carplaceUrl
  }

  return (
    <>
      {/* Mobile backdrop */}
      {open && (
        <div
          className="fixed inset-0 z-30 bg-blue-950/50 lg:hidden"
          onClick={() => setOpen(false)}
        />
      )}

      {/* Tab to open sidebar — only visible when sidebar is closed on mobile */}
      {!open && (
        <button
          type="button"
          onClick={() => setOpen(true)}
          aria-label="Open sidebar"
          className={[
            'fixed top-1/2 z-50 flex h-14 w-6 -translate-y-1/2 items-center justify-center bg-[#0a1128] text-white shadow-lg lg:hidden',
            isRtl ? 'right-0 rounded-l-lg' : 'left-0 rounded-r-lg',
          ].join(' ')}
        >
          {isRtl ? <ChevronLeft className="h-3.5 w-3.5" /> : <ChevronRight className="h-3.5 w-3.5" />}
        </button>
      )}

      <aside
        className={[
          'fixed inset-y-0 z-40 flex w-64 flex-col border-r border-blue-200/70 bg-white/90 text-blue-950 shadow-[8px_0_32px_rgba(15,23,42,0.08)] backdrop-blur-xl transition-[transform,background-color,border-color,color,box-shadow] duration-300 dark:border-blue-400/10 dark:bg-[#0a0f1a]/95 dark:text-slate-100 dark:shadow-[8px_0_32px_rgba(0,0,0,0.22)]',
          isRtl ? 'right-0' : 'left-0',
          'lg:translate-x-0',
          open ? 'translate-x-0' : (isRtl ? 'translate-x-full' : '-translate-x-full'),
        ].join(' ')}
      >
        <a
          href={carplaceUrl}
          target="_top"
          className="flex items-center gap-3 border-b border-blue-200/70 px-5 py-5 transition-colors dark:border-blue-400/10"
        >
          <div className="flex h-[38px] w-[38px] flex-shrink-0 items-center justify-center overflow-hidden rounded-lg bg-gradient-to-br from-blue-500 to-blue-700 shadow-[0_4px_14px_rgba(59,130,246,0.34)]">
            {brand?.logoUrl ? (
              // eslint-disable-next-line @next/next/no-img-element
              <img src={brand.logoUrl} alt={brand.displayName} className="h-8 w-8 object-cover" />
            ) : (
              <Car className="h-4 w-4 text-white" />
            )}
          </div>
          <span className="truncate bg-gradient-to-br from-blue-950 to-blue-600 bg-clip-text text-sm font-semibold tracking-[-0.01em] text-transparent dark:from-slate-100 dark:to-blue-300">
            {brand?.displayName ?? 'RentalDriveGo'}
          </span>
        </a>

        <nav className="flex-1 space-y-1.5 overflow-y-auto px-3 py-5">
          {renderGeneratedMenu(resolvedMenuItems)}
        </nav>

        <div className="border-t border-blue-200/70 px-3 py-4 dark:border-blue-400/10">
          <div className="rounded-xl border border-blue-200/70 bg-blue-50/75 p-3 backdrop-blur dark:border-blue-400/10 dark:bg-blue-500/[0.06]">
            <div className="flex items-center gap-3">
            <div className="flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-full bg-gradient-to-br from-blue-500 to-orange-500 text-xs font-semibold text-white">
              {user.initials}
            </div>
            <div className="min-w-0 flex-1">
              <p className="truncate text-sm font-medium text-blue-950 dark:text-white">{user.displayName}</p>
              <p className="truncate text-xs text-slate-500 dark:text-slate-400">{user.subtitle}</p>
            </div>
            </div>
          </div>
          <button
            type="button"
            onClick={signOut}
            className="mt-2 flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-sm text-slate-500 transition-colors hover:bg-blue-500/10 hover:text-blue-950 dark:text-slate-400 dark:hover:text-white"
          >
            <LogOut className="h-4 w-4" />
            {dict.signOut}
          </button>
          <div className="mt-3 flex items-center gap-2 border-t border-blue-200/70 pt-3 dark:border-blue-400/10">
            <DashboardLanguageSwitcher />
            <DashboardThemeSwitcher />
          </div>
        </div>

        {/* Arrow tab to collapse sidebar (mobile only, sticks to outer edge) */}
        <button
          type="button"
          onClick={() => setOpen(false)}
          aria-label="Close sidebar"
          className={[
            'absolute top-1/2 z-10 flex h-14 w-5 -translate-y-1/2 items-center justify-center bg-[#0a1128] text-white shadow-lg lg:hidden',
            isRtl ? '-left-5 rounded-l-lg' : '-right-5 rounded-r-lg',
          ].join(' ')}
        >
          {isRtl ? <ChevronRight className="h-3.5 w-3.5" /> : <ChevronLeft className="h-3.5 w-3.5" />}
        </button>
      </aside>
    </>
  )
}
