import { useCallback, useEffect, useMemo, useState } from 'react'
import { Link, NavLink, Outlet, useLocation } from 'react-router-dom'
import { api } from '../api/client.js'

function emailDomain(email) {
  const s = (email || '').trim().toLowerCase()
  const at = s.lastIndexOf('@')
  if (at < 0 || at === s.length - 1) return '其他'
  return s.slice(at + 1)
}

function groupAccountsByDomain(accounts) {
  const map = new Map()
  for (const a of accounts) {
    const d = emailDomain(a.email)
    if (!map.has(d)) map.set(d, [])
    map.get(d).push(a)
  }
  const groups = Array.from(map.entries()).map(([domain, items]) => ({
    domain,
    items: items.slice().sort((x, y) => (x.email || '').localeCompare(y.email || '', 'zh-CN')),
  }))
  groups.sort((a, b) => a.domain.localeCompare(b.domain, 'zh-CN'))
  return groups
}

function useMailboxAccountId() {
  const loc = useLocation()
  return useMemo(() => {
    const m = loc.pathname.match(/\/admin\/(?:mailbox|compose)\/(\d+)/)
    return m ? Number(m[1]) : null
  }, [loc.pathname])
}

function accountActive(location, id) {
  return (
    location.pathname === `/admin/mailbox/${id}` || location.pathname === `/admin/compose/${id}`
  )
}

function SidebarMailboxLink({ accountId, name }) {
  const location = useLocation()
  const current = new URLSearchParams(location.search).get('mailbox') || 'INBOX'
  const active =
    location.pathname === `/admin/mailbox/${accountId}` && current === name
  return (
    <Link
      to={`/admin/mailbox/${accountId}?mailbox=${encodeURIComponent(name)}`}
      className={'sidebar-item' + (active ? ' active' : '')}
    >
      {name}
    </Link>
  )
}

export default function MainLayout() {
  const location = useLocation()
  const [accounts, setAccounts] = useState([])
  const [boxes, setBoxes] = useState([])
  const [domainCollapsed, setDomainCollapsed] = useState({})
  const accountId = useMailboxAccountId()

  const groupedAccounts = useMemo(() => groupAccountsByDomain(accounts), [accounts])

  const expandAllDomains = useCallback(() => setDomainCollapsed({}), [])
  const collapseAllDomains = useCallback(() => {
    const next = {}
    for (const g of groupedAccounts) next[g.domain] = true
    setDomainCollapsed(next)
  }, [groupedAccounts])

  const toggleDomain = useCallback((domain) => {
    setDomainCollapsed((c) => ({ ...c, [domain]: !c[domain] }))
  }, [])

  useEffect(() => {
    api
      .listAccounts()
      .then((rows) => setAccounts(Array.isArray(rows) ? rows : []))
      .catch(() => setAccounts([]))
  }, [location.pathname])

  // 当前选中的账户所在分组自动展开
  useEffect(() => {
    const active = accounts.find((a) => accountActive(location, a.id))
    if (!active) return
    const d = emailDomain(active.email)
    setDomainCollapsed((c) => {
      if (!c[d]) return c
      const next = { ...c }
      delete next[d]
      return next
    })
  }, [location.pathname, accounts])

  useEffect(() => {
    if (!accountId) {
      setBoxes([])
      return
    }
    api
      .listMailboxes(accountId)
      .then((b) => setBoxes(Array.isArray(b) ? b : []))
      .catch(() => setBoxes([]))
  }, [accountId])

  return (
    <div className="app-shell">
      <aside className="sidebar">
        <div className="sidebar-section">
          <div className="sidebar-label-row">
            <div className="sidebar-label">邮箱</div>
            {accounts.length > 0 && (
              <div className="sidebar-label-actions">
                <button type="button" className="sidebar-mini-btn" onClick={expandAllDomains}>
                  全部展开
                </button>
                <button type="button" className="sidebar-mini-btn" onClick={collapseAllDomains}>
                  全部收起
                </button>
              </div>
            )}
          </div>
          {groupedAccounts.map(({ domain, items }) => {
            const collapsed = !!domainCollapsed[domain]
            return (
              <div key={domain} className="sidebar-group">
                <button
                  type="button"
                  className="sidebar-group-header"
                  onClick={() => toggleDomain(domain)}
                  aria-expanded={!collapsed}
                >
                  <span className="sidebar-group-chevron" aria-hidden>
                    {collapsed ? '\u25B8' : '\u25BE'}
                  </span>
                  <span className="sidebar-group-title">@{domain}</span>
                  <span className="sidebar-group-count">{items.length}</span>
                </button>
                {!collapsed && (
                  <div className="sidebar-group-body">
                    {items.map((a) => (
                      <NavLink
                        key={a.id}
                        to={`/admin/mailbox/${a.id}`}
                        className={() =>
                          'sidebar-item' + (accountActive(location, a.id) ? ' active' : '')
                        }
                      >
                        <span className="sidebar-item-title">{a.name || '未命名'}</span>
                        <span className="sidebar-item-sub muted">{a.email}</span>
                      </NavLink>
                    ))}
                  </div>
                )}
              </div>
            )
          })}
          {accounts.length === 0 && <p className="sidebar-muted">暂无账户</p>}
          <Link to="/admin/accounts" className="sidebar-foot">
            管理账户
          </Link>
        </div>
      </aside>
      <main className="main-area">
        <Outlet />
      </main>
      {accountId != null && (
        <aside className="sidebar sidebar-right" aria-label="邮件夹">
          <div className="sidebar-section">
            <div className="sidebar-label">邮件夹</div>
            {boxes.map((b) => (
              <SidebarMailboxLink key={b} accountId={accountId} name={b} />
            ))}
            {boxes.length === 0 && <p className="sidebar-muted">暂无或加载中</p>}
            <Link to={`/admin/compose/${accountId}`} className="sidebar-foot">
              写邮件
            </Link>
          </div>
        </aside>
      )}
    </div>
  )
}
