import { promises as fs } from "fs";
import path from "path";
import type { Project } from "@/types/workflow";
import type { ProjectScopedData } from "@/lib/project/defaults";
import { isMariaDbEnabled } from "@/lib/db/config";
import {
  getUserProjectsFromDb,
  saveUserProjectsToDb,
  type UserProjectsSnapshot,
} from "@/lib/db/repositories/projects-repo";
import { listDbUserIds } from "@/lib/db/repositories/users-repo";

export type { UserProjectsSnapshot };

const DATA_DIR = path.join(process.cwd(), "data");
const USERS_DIR = path.join(DATA_DIR, "users");

function safeUserId(userId: string): string {
  return userId.replace(/[^a-zA-Z0-9_-]/g, "_");
}

function projectsFilePath(userId: string): string {
  return path.join(USERS_DIR, safeUserId(userId), "projects.json");
}

async function ensureUserDir(userId: string) {
  await fs.mkdir(path.join(USERS_DIR, safeUserId(userId)), { recursive: true });
}

async function getUserProjectsJson(userId: string): Promise<UserProjectsSnapshot | null> {
  const filePath = projectsFilePath(userId);
  try {
    const raw = await fs.readFile(filePath, "utf-8");
    return JSON.parse(raw) as UserProjectsSnapshot;
  } catch {
    return null;
  }
}

async function saveUserProjectsJson(
  userId: string,
  snapshot: Omit<UserProjectsSnapshot, "updatedAt">,
): Promise<UserProjectsSnapshot> {
  await ensureUserDir(userId);
  const payload: UserProjectsSnapshot = {
    ...snapshot,
    updatedAt: new Date().toISOString(),
  };
  await fs.writeFile(projectsFilePath(userId), JSON.stringify(payload, null, 2), "utf-8");
  return payload;
}

export async function getUserProjects(
  userId: string,
  meta?: { email?: string; name?: string },
): Promise<UserProjectsSnapshot | null> {
  if (isMariaDbEnabled()) {
    try {
      return await getUserProjectsFromDb(userId, meta?.email, meta?.name);
    } catch (err) {
      console.error("[PostSync] MariaDB getUserProjects failed — falling back to JSON:", err);
      return getUserProjectsJson(userId);
    }
  }
  return getUserProjectsJson(userId);
}

export async function saveUserProjects(
  userId: string,
  snapshot: Omit<UserProjectsSnapshot, "updatedAt">,
  meta?: { email?: string; name?: string },
): Promise<UserProjectsSnapshot> {
  if (isMariaDbEnabled()) {
    try {
      return await saveUserProjectsToDb(userId, snapshot, meta?.email, meta?.name);
    } catch (err) {
      console.error("[PostSync] MariaDB saveUserProjects failed — falling back to JSON:", err);
      return saveUserProjectsJson(userId, snapshot);
    }
  }
  return saveUserProjectsJson(userId, snapshot);
}

export async function listAllUserIds(): Promise<string[]> {
  if (isMariaDbEnabled()) {
    try {
      const ids = await listDbUserIds();
      if (ids.length) return ids;
    } catch (err) {
      console.error("[PostSync] MariaDB listAllUserIds failed — falling back to JSON:", err);
    }
  }

  try {
    const entries = await fs.readdir(USERS_DIR, { withFileTypes: true });
    return entries.filter((e) => e.isDirectory()).map((e) => e.name);
  } catch {
    return [];
  }
}

/** @deprecated Type re-export helper for older imports */
export type ProjectsFileShape = {
  projects: Project[];
  dataByProjectId: Record<string, ProjectScopedData>;
};
