import type { FastifyInstance } from 'fastify';
import { z } from 'zod';
import { withTenant } from '../data/db.js';

const listQuerySchema = z.object({
  page: z.coerce.number().min(1).default(1),
  limit: z.coerce.number().min(1).max(100).default(20),
  type: z.string().optional(),
  owner: z.string().optional(),
  lifecycle: z.enum(['active', 'deprecated', 'decommissioned']).optional(),
  tier: z.enum(['critical', 'high', 'medium', 'low']).optional(),
});

const upsertServiceSchema = z.object({
  name: z.string().min(1).max(200),
  type: z.string().default('unknown'),
  owner: z.string().default('unknown'),
  description: z.string().max(2000).optional(),
  tier: z.enum(['critical', 'high', 'medium', 'low']).default('medium'),
  lifecycle: z.enum(['active', 'deprecated', 'decommissioned']).default('active'),
  links: z.record(z.string()).default({}),
  tags: z.record(z.string()).default({}),
});

export function registerServiceRoutes(app: FastifyInstance) {
  // List services
  app.get('/api/v1/services', async (req, reply) => {
    const query = listQuerySchema.parse(req.query);
    const tenantId = (req as any).tenantId;
    const offset = (query.page - 1) * query.limit;

    const result = await withTenant(tenantId, async (client) => {
      let sql = 'SELECT * FROM services WHERE 1=1';
      const params: any[] = [];
      let idx = 1;

      if (query.type) { sql += ` AND type = $${idx++}`; params.push(query.type); }
      if (query.owner) { sql += ` AND owner = $${idx++}`; params.push(query.owner); }
      if (query.lifecycle) { sql += ` AND lifecycle = $${idx++}`; params.push(query.lifecycle); }
      if (query.tier) { sql += ` AND tier = $${idx++}`; params.push(query.tier); }

      sql += ` ORDER BY name LIMIT $${idx++} OFFSET $${idx++}`;
      params.push(query.limit, offset);

      return client.query(sql, params);
    });

    return { services: result.rows, page: query.page, limit: query.limit };
  });

  // Get service detail
  app.get('/api/v1/services/:id', async (req, reply) => {
    const { id } = req.params as { id: string };
    const tenantId = (req as any).tenantId;

    const result = await withTenant(tenantId, async (client) => {
      return client.query('SELECT * FROM services WHERE id = $1', [id]);
    });

    if (!result.rows[0]) return reply.status(404).send({ error: 'Not found' });
    return { service: result.rows[0] };
  });

  // Create/update service (manual entry)
  app.put('/api/v1/services', async (req, reply) => {
    const body = upsertServiceSchema.parse(req.body);
    const tenantId = (req as any).tenantId;

    const result = await withTenant(tenantId, async (client) => {
      return client.query(
        `INSERT INTO services (tenant_id, name, type, owner, owner_source, description, tier, lifecycle, links, tags)
         VALUES ($1, $2, $3, $4, 'config', $5, $6, $7, $8, $9)
         ON CONFLICT (tenant_id, name) DO UPDATE SET
           type = EXCLUDED.type, owner = EXCLUDED.owner, owner_source = 'config',
           description = EXCLUDED.description, tier = EXCLUDED.tier, lifecycle = EXCLUDED.lifecycle,
           links = EXCLUDED.links, tags = EXCLUDED.tags, updated_at = now()
         RETURNING *`,
        [tenantId, body.name, body.type, body.owner, body.description, body.tier, body.lifecycle, JSON.stringify(body.links), JSON.stringify(body.tags)],
      );
    });

    return reply.status(201).send({ service: result.rows[0] });
  });

  // Delete service
  app.delete('/api/v1/services/:id', async (req, reply) => {
    const { id } = req.params as { id: string };
    const tenantId = (req as any).tenantId;

    await withTenant(tenantId, async (client) => {
      await client.query('DELETE FROM services WHERE id = $1', [id]);
    });

    return { status: 'deleted' };
  });

  // Ownership summary (who owns what)
  app.get('/api/v1/ownership', async (req, reply) => {
    const tenantId = (req as any).tenantId;

    const result = await withTenant(tenantId, async (client) => {
      return client.query(`
        SELECT owner, owner_source, COUNT(*)::int as service_count,
               array_agg(name ORDER BY name) as services
        FROM services
        WHERE lifecycle = 'active'
        GROUP BY owner, owner_source
        ORDER BY service_count DESC
      `);
    });

    return { owners: result.rows };
  });
}
