// GET/POST /api/companies — company management (admin pool, bypasses RLS by
// design: there is no company scope yet to be inside of when creating one,
// and the list endpoint powers the UI's company switcher across all
// companies). Reuses the same company+owner upsert logic as the chart:load
// CLI (tools/lib/chart-load.ts) — one code path, two frontends (see
// docs/superpowers/specs/2026-07-31-local-app-design.md).

import type { FastifyInstance } from "fastify";
import { z } from "zod";
import type { Db } from "./db.js";
import { mapPgError } from "./errors.js";
import { ensureCompanyAndOwner } from "../../tools/lib/chart-load.js";

const createCompanySchema = z.object({
  name: z.string().trim().min(1, "name is required"),
});

interface CompanyListRow {
  id: string;
  name: string;
  created_at: string;
  entry_count: string;
  is_sample: boolean;
}

export function registerCompanyRoutes(fastify: FastifyInstance, db: Db): void {
  fastify.get("/api/companies", async (_request, reply) => {
    const result = await db.adminPool.query<CompanyListRow>(
      `SELECT c.id, c.name, c.created_at, c.is_sample, count(je.id) AS entry_count
         FROM companies c
         LEFT JOIN journal_entries je ON je.company_id = c.id
        GROUP BY c.id, c.name, c.created_at, c.is_sample
        ORDER BY c.name`,
    );
    return reply.send({
      companies: result.rows.map((row) => ({
        id: row.id,
        name: row.name,
        createdAt: row.created_at,
        entryCount: Number(row.entry_count),
        isSample: row.is_sample,
      })),
    });
  });

  fastify.post("/api/companies", async (request, reply) => {
    const parsed = createCompanySchema.safeParse(request.body);
    if (!parsed.success) {
      return reply.code(400).send({
        error: parsed.error.issues.map((i) => i.message).join("; "),
      });
    }

    const client = await db.adminPool.connect();
    try {
      await client.query("BEGIN");
      const result = await ensureCompanyAndOwner(client, { name: parsed.data.name });
      await client.query("COMMIT");
      return reply.code(201).send({
        id: result.companyId,
        name: parsed.data.name,
        created: result.companyCreated,
        ownerId: result.ownerId,
        ownerEmail: result.ownerEmail,
      });
    } catch (err) {
      await client.query("ROLLBACK").catch(() => {});
      const mapped = mapPgError(err);
      if (mapped.status === 500) {
        request.log.error({ err }, "unmapped error creating company");
      }
      return reply.code(mapped.status).send({ error: mapped.message });
    } finally {
      client.release();
    }
  });
}
