import fs from 'fs';
import path from 'path';
import { env } from '../../config/env';
import { logger } from '../../utils/logger';

/**
 * Registry service — queries Gitea Packages API for container image status.
 * Build/mirror triggers are handled via trigger files read by the host watcher
 * (same pattern as upgrade service).
 */

const UPGRADE_DIR = path.resolve('/app/upgrade');
const REGISTRY_TRIGGER_FILE = path.join(UPGRADE_DIR, 'registry-trigger.json');

export interface RegistryImage {
  name: string;
  version: string;
  created_at: string;
}

async function getRegistryStatus(): Promise<RegistryImage[]> {
  const registryUrl = env.GITEA_REGISTRY || 'gitea.bnkops.com/admin';
  const [host, org] = registryUrl.split('/');
  const user = env.GITEA_REGISTRY_USER;
  const pass = env.GITEA_REGISTRY_PASS;

  if (!user || !pass) {
    throw new Error('GITEA_REGISTRY_USER and GITEA_REGISTRY_PASS must be configured');
  }

  const auth = Buffer.from(`${user}:${pass}`).toString('base64');
  const res = await fetch(`https://${host}/api/v1/packages/${org}?type=container&limit=50`, {
    headers: { Authorization: `Basic ${auth}` },
  });

  if (!res.ok) {
    throw new Error(`Gitea API error: ${res.status} ${res.statusText}`);
  }

  const data = await res.json() as RegistryImage[];
  return data;
}

interface RegistryTrigger {
  action: 'build-push' | 'mirror';
  triggeredAt: string;
  triggeredBy: string;
  options: Record<string, unknown>;
}

function writeTrigger(action: RegistryTrigger['action'], triggeredBy: string, options: Record<string, unknown>): void {
  try {
    fs.mkdirSync(UPGRADE_DIR, { recursive: true });
    const trigger: RegistryTrigger = {
      action,
      triggeredAt: new Date().toISOString(),
      triggeredBy,
      options,
    };
    fs.writeFileSync(REGISTRY_TRIGGER_FILE, JSON.stringify(trigger, null, 2), 'utf-8');
    logger.info(`Registry trigger written: ${action} by ${triggeredBy}`);
  } catch (err) {
    logger.error('Failed to write registry trigger:', err);
    throw err;
  }
}

function triggerBuildPush(triggeredBy: string, options: { skipCodeServer?: boolean; services?: string } = {}): void {
  writeTrigger('build-push', triggeredBy, options);
}

function triggerMirror(triggeredBy: string, options: { all?: boolean } = {}): void {
  writeTrigger('mirror', triggeredBy, options);
}

export const registryService = { getRegistryStatus, triggerBuildPush, triggerMirror };
