import { useEffect, useMemo, useState } from 'react'
import { NavLink, useLocation, useNavigate } from 'react-router-dom'
import {
  Home,
  ShoppingBag,
  Store,
  Users,
  Settings,
  FileText,
  Briefcase,
  Globe,
  HelpCircle,
  LogOut,
  ChevronDown,
  Building2,
  Pencil,
} from 'lucide-react'
import type { LucideIcon } from 'lucide-react'
import { useLocale } from '@meshkee/dashboard-ui'
import { useAuth } from '../context/AuthContext'
import { useT } from '../i18n/useT'
import type { BusinessMessageKey } from '../i18n/messages'
import {
  BUSINESS_PROFILE_UPDATED_EVENT,
  getActiveBusinessDomain,
} from '../lib/businessContext'
import { isAbortError } from '../lib/api'
import { getBusinessProfile } from '../services/businessProfileService'
import { Tooltip } from './Tooltip'
import styles from './Sidebar.module.css'

interface NavChild {
  labelKey: BusinessMessageKey
  to: string
}

interface NavGroup {
  type: 'group'
  id: string
  icon: LucideIcon
  labelKey: BusinessMessageKey
  basePath: string
  children: NavChild[]
}

interface NavLinkItem {
  type: 'link'
  id: string
  icon: LucideIcon
  labelKey: BusinessMessageKey
  to: string
}

type NavItem = NavLinkItem | NavGroup

function isGroupActive(basePath: string, pathname: string) {
  return pathname === basePath || pathname.startsWith(`${basePath}/`)
}

export function Sidebar() {
  const { pathname } = useLocation()
  const navigate = useNavigate()
  const { user, logout } = useAuth()
  const { locale } = useLocale()
  const t = useT()
  const [openGroups, setOpenGroups] = useState<Record<string, boolean>>({})
  const [brandLogoUrl, setBrandLogoUrl] = useState<string | null>(null)
  const [nameEn, setNameEn] = useState('')
  const [nameFa, setNameFa] = useState('')

  const businessDomain = getActiveBusinessDomain()
  const fallbackBusinessName = user?.businesses[0]?.name ?? t('app.storeFallback')

  const brandName = useMemo(() => {
    if (locale === 'fa') {
      return nameFa.trim() || nameEn.trim() || fallbackBusinessName
    }
    return nameEn.trim() || nameFa.trim() || fallbackBusinessName
  }, [locale, nameEn, nameFa, fallbackBusinessName])

  const navItems = useMemo<NavItem[]>(
    () => [
      { type: 'link', id: 'home', icon: Home, labelKey: 'nav.home', to: '/' },
      {
        type: 'link',
        id: 'business-profile',
        icon: Building2,
        labelKey: 'nav.businessProfile',
        to: '/business-profile',
      },
      {
        type: 'group',
        id: 'products',
        icon: ShoppingBag,
        labelKey: 'nav.products',
        basePath: '/products',
        children: [
          { labelKey: 'nav.products.overview', to: '/products' },
          { labelKey: 'nav.products.list', to: '/products/list' },
          { labelKey: 'nav.products.new', to: '/products/new' },
          { labelKey: 'nav.products.categories', to: '/products/categories' },
          { labelKey: 'nav.products.brands', to: '/products/brands' },
          { labelKey: 'nav.products.settings', to: '/products/settings' },
        ],
      },
      {
        type: 'group',
        id: 'store',
        icon: Store,
        labelKey: 'nav.store',
        basePath: '/store',
        children: [
          { labelKey: 'nav.store.overview', to: '/store' },
          { labelKey: 'nav.store.items', to: '/store/items' },
          { labelKey: 'nav.store.orders', to: '/store/orders' },
          { labelKey: 'nav.store.shipping', to: '/store/shipping' },
          { labelKey: 'nav.store.cards', to: '/store/cards' },
          { labelKey: 'nav.store.settings', to: '/store/settings' },
        ],
      },
      { type: 'link', id: 'customers', icon: Users, labelKey: 'nav.customers', to: '/customers' },
      {
        type: 'group',
        id: 'blog',
        icon: FileText,
        labelKey: 'nav.blog',
        basePath: '/blog',
        children: [
          { labelKey: 'nav.blog.overview', to: '/blog' },
          { labelKey: 'nav.blog.list', to: '/blog/list' },
          { labelKey: 'nav.blog.new', to: '/blog/new' },
          { labelKey: 'nav.blog.categories', to: '/blog/categories' },
          { labelKey: 'nav.blog.settings', to: '/blog/settings' },
        ],
      },
      {
        type: 'group',
        id: 'portfolios',
        icon: Briefcase,
        labelKey: 'nav.portfolios',
        basePath: '/portfolios',
        children: [
          { labelKey: 'nav.portfolios.overview', to: '/portfolios' },
          { labelKey: 'nav.portfolios.list', to: '/portfolios/list' },
          { labelKey: 'nav.portfolios.new', to: '/portfolios/new' },
          { labelKey: 'nav.portfolios.categories', to: '/portfolios/categories' },
          { labelKey: 'nav.portfolios.settings', to: '/portfolios/settings' },
        ],
      },
      {
        type: 'group',
        id: 'website',
        icon: Globe,
        labelKey: 'nav.website',
        basePath: '/website',
        children: [
          { labelKey: 'nav.website.overview', to: '/website' },
          { labelKey: 'nav.website.sliders', to: '/website/sliders' },
          { labelKey: 'nav.website.specialCategories', to: '/website/special-categories' },
          { labelKey: 'nav.website.specialBrands', to: '/website/special-brands' },
          { labelKey: 'nav.website.specialItems', to: '/website/special-items' },
          { labelKey: 'nav.website.contact', to: '/website/contact' },
          { labelKey: 'nav.website.subscriptions', to: '/website/subscriptions' },
          { labelKey: 'nav.website.faq', to: '/website/faq' },
          { labelKey: 'nav.website.badges', to: '/website/badges' },
          { labelKey: 'nav.website.ePayment', to: '/website/e-payment' },
        ],
      },
      { type: 'link', id: 'settings', icon: Settings, labelKey: 'nav.settings', to: '/settings' },
    ],
    [],
  )

  useEffect(() => {
    const controller = new AbortController()

    async function loadBranding() {
      try {
        const data = await getBusinessProfile(controller.signal)
        setBrandLogoUrl(data.profile.logoUrl)
        setNameEn(data.profile.nameEn.trim())
        setNameFa(data.profile.nameFa.trim())
      } catch (err) {
        if (isAbortError(err)) return
        setBrandLogoUrl(null)
        setNameEn('')
        setNameFa('')
      }
    }

    void loadBranding()

    function handleProfileUpdated() {
      void loadBranding()
    }

    window.addEventListener(BUSINESS_PROFILE_UPDATED_EVENT, handleProfileUpdated)
    return () => {
      controller.abort()
      window.removeEventListener(BUSINESS_PROFILE_UPDATED_EVENT, handleProfileUpdated)
    }
  }, [])

  useEffect(() => {
    const activeGroup = navItems.find(
      (item) => item.type === 'group' && isGroupActive(item.basePath, pathname),
    )
    if (!activeGroup || activeGroup.type !== 'group') return
    setOpenGroups({ [activeGroup.id]: true })
  }, [pathname, navItems])

  function toggleGroup(id: string) {
    setOpenGroups((prev) => {
      const willOpen = !prev[id]
      return willOpen ? { [id]: true } : {}
    })
  }

  return (
    <aside className={styles.sidebar}>
      <div className={styles.brand}>
        {brandLogoUrl ? (
          <img
            src={brandLogoUrl}
            alt={brandName || t('app.storeFallback')}
            className={`${styles.brandLogo} ${styles.brandLogoUploaded}`}
          />
        ) : (
          <Tooltip label={t('sidebar.addLogo')}>
            <NavLink
              to="/business-profile"
              className={styles.brandEditBtn}
              aria-label={t('sidebar.addLogo')}
            >
              <Pencil size={16} />
            </NavLink>
          </Tooltip>
        )}
        <div className={styles.brandText}>
          <span className={styles.brandName}>{brandName || fallbackBusinessName}</span>
          <span className={styles.brandDomain}>{businessDomain}</span>
        </div>
      </div>

      <nav className={styles.nav}>
        {navItems.map((item) => {
          if (item.type === 'link') {
            return (
              <NavLink
                key={item.id}
                to={item.to}
                end={item.to === '/'}
                className={({ isActive }) =>
                  `${styles.navItem} ${isActive ? styles.active : ''}`
                }
              >
                <item.icon size={20} />
                <span>{t(item.labelKey)}</span>
              </NavLink>
            )
          }

          const isOpen = openGroups[item.id] ?? false
          const groupActive = isGroupActive(item.basePath, pathname)

          return (
            <div key={item.id} className={styles.navGroup}>
              <button
                type="button"
                className={`${styles.navItem} ${styles.navGroupBtn} ${groupActive ? styles.active : ''}`}
                onClick={() => toggleGroup(item.id)}
                aria-expanded={isOpen}
              >
                <item.icon size={20} />
                <span className={styles.navGroupLabel}>{t(item.labelKey)}</span>
                <ChevronDown
                  size={16}
                  className={`${styles.chevron} ${isOpen ? styles.chevronOpen : ''}`}
                />
              </button>

              {isOpen && (
                <div className={styles.subNav}>
                  {item.children.map((child) => (
                    <NavLink
                      key={child.to}
                      to={child.to}
                      end={child.to === item.basePath}
                      className={({ isActive }) =>
                        `${styles.subNavItem} ${isActive ? styles.subNavActive : ''}`
                      }
                    >
                      {t(child.labelKey)}
                    </NavLink>
                  ))}
                </div>
              )}
            </div>
          )
        })}
      </nav>

      <div className={styles.footer}>
        <button type="button" className={styles.navItem}>
          <HelpCircle size={20} />
          <span>{t('nav.help')}</span>
        </button>
        <button
          type="button"
          className={styles.navItem}
          onClick={() => {
            logout()
            navigate('/login')
          }}
        >
          <LogOut size={20} />
          <span>{t('nav.logout')}</span>
        </button>
      </div>
    </aside>
  )
}
