/**
 * GET  /api/workspaces/[slug]/databases — list databases in this workspace
 * POST /api/workspaces/[slug]/databases — provision a new database
 *
 * Supported `type` values (all that Coolify v4 can deploy):
 *   postgresql | mysql | mariadb | mongodb | redis | keydb | dragonfly | clickhouse
 *
 * POST body:
 *   {
 *     type: "postgresql",
 *     name?: "my-db",
 *     isPublic?: true,           // expose a host port for remote clients
 *     publicPort?: 5433,
 *     image?: "postgres:16",
 *     credentials?: { ... }      // type-specific (e.g. postgres_user)
 *     limits?: { memory?: "1G", cpus?: "1" },
 *   }
 *
 * Tenancy: every returned record is filtered to the workspace's own
 * Coolify project UUID.
 */

import { NextResponse } from 'next/server';
import { requireWorkspacePrincipal } from '@/lib/auth/workspace-auth';
import {
  listDatabasesInProject,
  createDatabase,
  getDatabase,
  projectUuidOf,
  type CoolifyDatabaseType,
} from '@/lib/coolify';
import { slugify } from '@/lib/naming';

const SUPPORTED_TYPES: readonly CoolifyDatabaseType[] = [
  'postgresql',
  'mysql',
  'mariadb',
  'mongodb',
  'redis',
  'keydb',
  'dragonfly',
  'clickhouse',
];

export async function GET(
  request: Request,
  { params }: { params: Promise<{ slug: string }> }
) {
  const { slug } = await params;
  const principal = await requireWorkspacePrincipal(request, { targetSlug: slug });
  if (principal instanceof NextResponse) return principal;

  const ws = principal.workspace;
  if (!ws.coolify_project_uuid) {
    return NextResponse.json(
      { error: 'Workspace has no Coolify project yet', databases: [] },
      { status: 503 }
    );
  }

  try {
    const dbs = await listDatabasesInProject(ws.coolify_project_uuid);
    return NextResponse.json({
      workspace: { slug: ws.slug, coolifyProjectUuid: ws.coolify_project_uuid },
      databases: dbs.map(d => ({
        uuid: d.uuid,
        name: d.name,
        type: d.type ?? null,
        status: d.status,
        isPublic: d.is_public ?? false,
        publicPort: d.public_port ?? null,
        projectUuid: projectUuidOf(d),
      })),
    });
  } catch (err) {
    return NextResponse.json(
      { error: 'Coolify request failed', details: err instanceof Error ? err.message : String(err) },
      { status: 502 }
    );
  }
}

export async function POST(
  request: Request,
  { params }: { params: Promise<{ slug: string }> }
) {
  const { slug } = await params;
  const principal = await requireWorkspacePrincipal(request, { targetSlug: slug });
  if (principal instanceof NextResponse) return principal;

  const ws = principal.workspace;
  if (!ws.coolify_project_uuid) {
    return NextResponse.json({ error: 'Workspace has no Coolify project yet' }, { status: 503 });
  }

  type Body = {
    type?: string;
    name?: string;
    description?: string;
    isPublic?: boolean;
    publicPort?: number;
    image?: string;
    credentials?: Record<string, unknown>;
    limits?: { memory?: string; cpus?: string };
    instantDeploy?: boolean;
  };
  let body: Body = {};
  try {
    body = (await request.json()) as Body;
  } catch {
    return NextResponse.json({ error: 'Invalid JSON body' }, { status: 400 });
  }

  const type = body.type as CoolifyDatabaseType | undefined;
  if (!type || !SUPPORTED_TYPES.includes(type)) {
    return NextResponse.json(
      { error: `\`type\` must be one of: ${SUPPORTED_TYPES.join(', ')}` },
      { status: 400 }
    );
  }

  const name = slugify(body.name ?? `${type}-${Date.now().toString(36)}`);

  try {
    const created = await createDatabase({
      type,
      name,
      description: body.description,
      projectUuid: ws.coolify_project_uuid,
      serverUuid: ws.coolify_server_uuid ?? undefined,
      environmentName: ws.coolify_environment_name,
      destinationUuid: ws.coolify_destination_uuid ?? undefined,
      isPublic: body.isPublic,
      publicPort: body.publicPort,
      image: body.image,
      credentials: body.credentials,
      limits: body.limits,
      instantDeploy: body.instantDeploy ?? true,
    });

    const db = await getDatabase(created.uuid);
    return NextResponse.json(
      {
        uuid: db.uuid,
        name: db.name,
        type: db.type ?? type,
        status: db.status,
        isPublic: db.is_public ?? false,
        publicPort: db.public_port ?? null,
        internalUrl: db.internal_db_url ?? null,
        externalUrl: db.external_db_url ?? null,
      },
      { status: 201 }
    );
  } catch (err) {
    return NextResponse.json(
      { error: 'Coolify create failed', details: err instanceof Error ? err.message : String(err) },
      { status: 502 }
    );
  }
}
