import { existsSync } from "fs";
import { access, copyFile, mkdir, readdir, rm, writeFile } from "fs/promises";
import path from "path";
import { appVersion } from "./version";

export const dataDirectory = path.join(process.cwd(), "data");
export const storageDirectory = path.join(process.cwd(), "storage");
export const configDirectory = path.join(storageDirectory, "config");
export const contentDirectory = path.join(storageDirectory, "content");
export const contentBackupDirectory = path.join(contentDirectory, "backups");
export const uploadDirectory = path.join(storageDirectory, "uploads", "images");
export const legacyPublicUploadDirectory = path.join(process.cwd(), "public", "uploads", "images");

export function adminConfigurationStatus() {
  return process.env.ADMIN_EMAIL && process.env.ADMIN_PASSWORD && process.env.ADMIN_SESSION_SECRET ? "configured" : "missing";
}

export function isDockerEnvironment() {
  return process.env.DOCKER_ENV === "true" || process.env.CONTAINER === "true" || existsSync("/.dockerenv");
}

export async function ensureRuntimeDirectories() {
  await mkdir(dataDirectory, { recursive: true });
  await mkdir(configDirectory, { recursive: true });
  await mkdir(contentBackupDirectory, { recursive: true });
  await mkdir(uploadDirectory, { recursive: true });
  await migrateLegacyUploads();
}

export async function checkStorage() {
  await ensureRuntimeDirectories();
  const probe = path.join(dataDirectory, `.storage-check-${Date.now()}`);
  await writeFile(probe, "ok", "utf8");
  await rm(probe, { force: true });
  await access(uploadDirectory);
  return "ok";
}

export function olympusStatus() {
  return process.env.OLYMPUS_INTAKE_API_URL && process.env.OLYMPUS_INTAKE_API_TOKEN ? "configured" : "not_configured";
}

export function smtpStatus() {
  return "prepared";
}

export async function migrateLegacyUploads() {
  if (!existsSync(legacyPublicUploadDirectory)) return;

  await mkdir(uploadDirectory, { recursive: true });
  const entries = await readdir(legacyPublicUploadDirectory, { withFileTypes: true });

  await Promise.all(entries.map(async (entry) => {
    if (!entry.isFile() || entry.name.startsWith(".")) return;

    const source = path.join(legacyPublicUploadDirectory, entry.name);
    const target = path.join(uploadDirectory, entry.name);

    if (!existsSync(target)) await copyFile(source, target);
  }));
}

export { appVersion };
