/**
 * GET  /api/v1/libs  — list all repositories
 * POST /api/v1/libs  — add a new repository
 */
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import type { Repository } from '$lib/types';
import { getClient } from '$lib/server/db/client';
import { RepositoryService } from '$lib/server/services/repository.service';
import { getQueue } from '$lib/server/pipeline/startup';
import { handleServiceError } from '$lib/server/utils/validation';

// ---------------------------------------------------------------------------
// Row mapper — better-sqlite3 returns snake_case column names from SELECT *;
// this converts them to the camelCase shape expected by the Repository type
// and by client components (e.g. RepositoryCard reads repo.trustScore).
// ---------------------------------------------------------------------------

interface RawRepoRow {
	id: string;
	title: string;
	description: string | null;
	source: string;
	source_url: string;
	branch: string | null;
	state: string;
	total_snippets: number;
	total_tokens: number;
	trust_score: number;
	benchmark_score: number;
	stars: number | null;
	github_token: string | null;
	last_indexed_at: number | null;
	created_at: number;
	updated_at: number;
}

function mapRepo(raw: Repository): Repository {
	const r = raw as unknown as RawRepoRow;
	return {
		id: r.id,
		title: r.title,
		description: r.description ?? null,
		source: r.source as Repository['source'],
		sourceUrl: r.source_url,
		branch: r.branch ?? null,
		state: r.state as Repository['state'],
		totalSnippets: r.total_snippets ?? 0,
		totalTokens: r.total_tokens ?? 0,
		trustScore: r.trust_score ?? 0,
		benchmarkScore: r.benchmark_score ?? 0,
		stars: r.stars ?? null,
		githubToken: r.github_token ?? null,
		lastIndexedAt:
			r.last_indexed_at != null ? new Date(r.last_indexed_at * 1000) : null,
		createdAt: new Date(r.created_at * 1000),
		updatedAt: new Date(r.updated_at * 1000)
	};
}

function getService() {
	return new RepositoryService(getClient());
}

export const GET: RequestHandler = ({ url }) => {
	try {
		const service = getService();
		const state = url.searchParams.get('state') as
			| 'pending'
			| 'indexing'
			| 'indexed'
			| 'error'
			| undefined;
		const limit = Math.min(parseInt(url.searchParams.get('limit') ?? '50'), 200);
		const offset = parseInt(url.searchParams.get('offset') ?? '0');

		const libraries = service.list({ state: state ?? undefined, limit, offset });
		const total = service.count(state ?? undefined);

		// Map raw snake_case rows to camelCase, augment with versions, strip sensitive fields.
		const enriched = libraries.map((rawRepo) => {
			const { githubToken: _token, ...repo } = mapRepo(rawRepo);
			return {
				...repo,
				versions: service.getVersions(repo.id)
			};
		});

		return json({ libraries: enriched, total, limit, offset });
	} catch (err) {
		return handleServiceError(err);
	}
};

export const POST: RequestHandler = async ({ request }) => {
	try {
		const body = await request.json();
		const service = getService();

		const repo = service.add({
			source: body.source,
			sourceUrl: body.sourceUrl,
			title: body.title,
			description: body.description,
			branch: body.branch,
			githubToken: body.githubToken
		});

		let jobResponse: { id: string; status: string } | null = null;
		if (body.autoIndex !== false) {
			const queue = getQueue();
			const job = queue
				? queue.enqueue(repo.id)
				: service.createIndexingJob(repo.id);
			jobResponse = { id: job.id, status: job.status };
		}

		const { githubToken: _token, ...safeRepo } = repo;
		return json(
			{ library: safeRepo, ...(jobResponse ? { job: jobResponse } : {}) },
			{ status: 201 }
		);
	} catch (err) {
		return handleServiceError(err);
	}
};

export const OPTIONS: RequestHandler = () => {
	return new Response(null, {
		status: 204,
		headers: corsHeaders()
	});
};

function corsHeaders(): Record<string, string> {
	return {
		'Access-Control-Allow-Origin': '*',
		'Access-Control-Allow-Methods': 'GET, POST, PATCH, DELETE, OPTIONS',
		'Access-Control-Allow-Headers': 'Content-Type, Authorization'
	};
}
