import fs from "node:fs"
import { normalizeComparablePath } from "@anybox/platform"
import path from "node:path"
import type { AgentFolderWorkspace, AgentProjectInfo, AgentProjectWorkspace } from "./types"

function normalizePath(input: string) {
  const resolved = path.resolve(input)
  const normalized = path.normalize(resolved)
  return normalizeComparablePath(normalized)
}

function samePath(left: string, right: string) {
  return normalizePath(left) === normalizePath(right)
}

function getProjectName(project: { name?: string; worktree: string }) {
  const trimmed = project.name?.trim()
  if (trimmed) return trimmed

  const fallback = project.worktree.split(/[\\/]/).filter(Boolean).pop()
  return fallback || project.worktree
}

function getFolderName(directory: string) {
  const normalized = directory.replace(/[\\/]+$/, "")
  const fallback = normalized.split(/[\\/]/).filter(Boolean).pop()
  return fallback || directory
}

function getSessionsForDirectory(workspace: AgentProjectWorkspace, directory: string) {
  return workspace.sessions
    .filter((session) => samePath(session.directory, directory))
    .sort((left, right) => right.updated - left.updated)
}

function checkDirectoryExists(directory: string, existsSync: (path: string) => boolean) {
  try {
    return existsSync(directory)
  } catch {
    return false
  }
}

export function buildFolderWorkspaceForDirectory(
  project: AgentProjectInfo,
  workspace: AgentProjectWorkspace,
  directory: string,
  options?: {
    existsSync?: (path: string) => boolean
  },
): AgentFolderWorkspace {
  const sessions = getSessionsForDirectory(workspace, directory)
  const exists = checkDirectoryExists(directory, options?.existsSync ?? fs.existsSync)

  return {
    id: directory,
    directory,
    name: getFolderName(directory),
    exists,
    created: sessions[0]?.created ?? workspace.created,
    updated: sessions[0]?.updated ?? workspace.updated,
    project: {
      id: project.id,
      name: getProjectName(project),
      worktree: project.worktree,
    },
    sessions,
  }
}

export function buildFolderWorkspaces(
  projects: AgentProjectInfo[],
  workspaces: AgentProjectWorkspace[],
  options?: {
    existsSync?: (path: string) => boolean
  },
) {
  const folderWorkspaces: AgentFolderWorkspace[] = []

  for (const [index, workspace] of workspaces.entries()) {
    const project = projects[index]
    if (!project) continue

    const directories = new Map<string, string>()
    for (const session of workspace.sessions) {
      directories.set(normalizePath(session.directory), session.directory)
    }

    for (const directory of directories.values()) {
      folderWorkspaces.push(buildFolderWorkspaceForDirectory(project, workspace, directory, options))
    }
  }

  return folderWorkspaces.sort((left, right) => right.updated - left.updated)
}
