/**
 * Coolify API client for Vibn project provisioning.
 *
 * Used server-side only. Credentials from env vars:
 *   COOLIFY_URL        — e.g. http://34.19.250.135:8000
 *   COOLIFY_API_TOKEN  — admin bearer token
 */

const COOLIFY_URL = process.env.COOLIFY_URL ?? 'http://34.19.250.135:8000';
const COOLIFY_API_TOKEN = process.env.COOLIFY_API_TOKEN ?? '';

export interface CoolifyProject {
  uuid: string;
  name: string;
  description?: string;
}

export interface CoolifyDatabase {
  uuid: string;
  name: string;
  type: string;
  status: string;
  internal_db_url?: string;
  external_db_url?: string;
}

export interface CoolifyApplication {
  uuid: string;
  name: string;
  status: string;
  fqdn?: string;
  git_repository?: string;
  git_branch?: string;
}

async function coolifyFetch(path: string, options: RequestInit = {}) {
  const url = `${COOLIFY_URL}/api/v1${path}`;
  const res = await fetch(url, {
    ...options,
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${COOLIFY_API_TOKEN}`,
      ...(options.headers ?? {}),
    },
  });

  if (!res.ok) {
    const text = await res.text();
    throw new Error(`Coolify API error ${res.status} on ${path}: ${text}`);
  }

  if (res.status === 204) return null;
  return res.json();
}

// ──────────────────────────────────────────────────
// Projects
// ──────────────────────────────────────────────────

export async function listProjects(): Promise<CoolifyProject[]> {
  return coolifyFetch('/projects');
}

export async function createProject(name: string, description?: string): Promise<CoolifyProject> {
  return coolifyFetch('/projects', {
    method: 'POST',
    body: JSON.stringify({ name, description }),
  });
}

export async function getProject(uuid: string): Promise<CoolifyProject> {
  return coolifyFetch(`/projects/${uuid}`);
}

export async function deleteProject(uuid: string): Promise<void> {
  await coolifyFetch(`/projects/${uuid}`, { method: 'DELETE' });
}

// ──────────────────────────────────────────────────
// Databases
// ──────────────────────────────────────────────────

type DBType = 'postgresql' | 'mysql' | 'mariadb' | 'redis' | 'mongodb' | 'keydb';

export async function createDatabase(opts: {
  projectUuid: string;
  name: string;
  type: DBType;
  serverUuid?: string;
  environmentName?: string;
}): Promise<CoolifyDatabase> {
  const { projectUuid, name, type, serverUuid = '0', environmentName = 'production' } = opts;

  return coolifyFetch(`/databases`, {
    method: 'POST',
    body: JSON.stringify({
      project_uuid: projectUuid,
      name,
      type,
      server_uuid: serverUuid,
      environment_name: environmentName,
    }),
  });
}

export async function getDatabase(uuid: string): Promise<CoolifyDatabase> {
  return coolifyFetch(`/databases/${uuid}`);
}

export async function deleteDatabase(uuid: string): Promise<void> {
  await coolifyFetch(`/databases/${uuid}`, { method: 'DELETE' });
}

// ──────────────────────────────────────────────────
// Applications
// ──────────────────────────────────────────────────

export async function createApplication(opts: {
  projectUuid: string;
  name: string;
  gitRepo: string;       // e.g. "https://git.vibnai.com/mark/taskmaster.git"
  gitBranch?: string;
  serverUuid?: string;
  environmentName?: string;
  buildPack?: string;    // nixpacks, static, dockerfile
  ports?: string;        // e.g. "3000"
}): Promise<CoolifyApplication> {
  const {
    projectUuid, name, gitRepo,
    gitBranch = 'main',
    serverUuid = '0',
    environmentName = 'production',
    buildPack = 'nixpacks',
    ports = '3000',
  } = opts;

  return coolifyFetch(`/applications`, {
    method: 'POST',
    body: JSON.stringify({
      project_uuid: projectUuid,
      name,
      git_repository: gitRepo,
      git_branch: gitBranch,
      server_uuid: serverUuid,
      environment_name: environmentName,
      build_pack: buildPack,
      ports_exposes: ports,
    }),
  });
}

/**
 * Create a Coolify service for one app inside a Turborepo monorepo.
 * Build command uses `turbo run build --filter` to target just that app.
 */
export async function createMonorepoAppService(opts: {
  projectUuid: string;
  appName: string;
  gitRepo: string;
  gitBranch?: string;
  domain: string;
  serverUuid?: string;
  environmentName?: string;
}): Promise<CoolifyApplication> {
  const {
    projectUuid, appName, gitRepo,
    gitBranch = 'main',
    domain,
    serverUuid = '0',
    environmentName = 'production',
  } = opts;

  return coolifyFetch(`/applications`, {
    method: 'POST',
    body: JSON.stringify({
      project_uuid: projectUuid,
      name: appName,
      git_repository: gitRepo,
      git_branch: gitBranch,
      server_uuid: serverUuid,
      environment_name: environmentName,
      build_pack: 'nixpacks',
      build_command: `pnpm install && turbo run build --filter=${appName}`,
      start_command: `turbo run start --filter=${appName}`,
      ports_exposes: '3000',
      fqdn: `https://${domain}`,
    }),
  });
}

export async function deployApplication(uuid: string): Promise<{ deployment_uuid: string }> {
  return coolifyFetch(`/applications/${uuid}/deploy`, { method: 'POST' });
}

export async function getApplication(uuid: string): Promise<CoolifyApplication> {
  return coolifyFetch(`/applications/${uuid}`);
}

export async function getDeploymentLogs(deploymentUuid: string): Promise<{ logs: string }> {
  return coolifyFetch(`/deployments/${deploymentUuid}/logs`);
}
