import type { ApiFolder } from '@/lib/api/types'
import type { FolderTreeNode } from '@/lib/sidebar-nav-maps'

function imapPathDelimiter(remoteNames: string[]): string {
  if (remoteNames.some((n) => n.includes('/'))) return '/'
  if (remoteNames.some((n) => n.includes('.'))) return '.'
  return '/'
}

function splitImapPath(remoteName: string, delimiter: string): string[] {
  return remoteName.split(delimiter).filter(Boolean)
}

/** Custom IMAP folders (system folders use fixed route slugs in the sidebar). */
export function filterImapFoldersForNav(
  folders: ApiFolder[],
  accountId?: string
): ApiFolder[] {
  return folders.filter(
    (folder) =>
      folder.folder_type === 'custom' &&
      (!accountId || folder.account_id === accountId)
  )
}

/** Build a hierarchical tree from IMAP folder paths (remote_name). */
export function buildFolderTreeFromImap(
  folders: ApiFolder[],
  accountId?: string
): FolderTreeNode[] {
  const custom = filterImapFoldersForNav(folders, accountId).sort((a, b) =>
    a.remote_name.localeCompare(b.remote_name)
  )
  if (custom.length === 0) return []

  const delimiter = imapPathDelimiter(custom.map((f) => f.remote_name))
  const nodesByRemote = new Map(custom.map((f) => [f.remote_name, f]))
  const childrenOf = new Map<string | null, ApiFolder[]>()

  for (const folder of custom) {
    const segments = splitImapPath(folder.remote_name, delimiter)
    let parentRemote: string | null = null
    for (let i = 0; i < segments.length - 1; i++) {
      const prefix = segments.slice(0, i + 1).join(delimiter)
      if (nodesByRemote.has(prefix)) {
        parentRemote = prefix
      }
    }
    const list = childrenOf.get(parentRemote) ?? []
    list.push(folder)
    childrenOf.set(parentRemote, list)
  }

  function walk(parentRemote: string | null): FolderTreeNode[] {
    const kids = childrenOf.get(parentRemote) ?? []
    return kids
      .sort((a, b) => a.name.localeCompare(b.name))
      .map((folder) => {
        const node: FolderTreeNode = {
          id: folder.id,
          label: folder.name,
        }
        if (folder.unread_count > 0) node.count = folder.unread_count
        const children = walk(folder.remote_name)
        if (children.length) node.children = children
        return node
      })
  }

  return walk(null)
}

export type ImapFolderSettingsNode = {
  id: string
  label: string
  remoteName?: string
  children?: ImapFolderSettingsNode[]
}

/** Settings tree with IMAP remote paths for display. */
export function buildImapFolderSettingsTree(
  folders: ApiFolder[],
  accountId: string
): ImapFolderSettingsNode[] {
  const custom = filterImapFoldersForNav(folders, accountId)
  const remoteById = new Map(custom.map((f) => [f.id, f.remote_name]))

  function attachRemote(nodes: FolderTreeNode[]): ImapFolderSettingsNode[] {
    return nodes.map((node) => ({
      id: node.id,
      label: node.label,
      remoteName: remoteById.get(node.id),
      children: node.children?.length ? attachRemote(node.children) : undefined,
    }))
  }

  return attachRemote(buildFolderTreeFromImap(folders, accountId))
}
