/**
 * Marketplace proxy routes for cowork-service.
 *
 * Forwards marketplace requests to platform-service's marketplace module.
 * This replaces the local plugin marketplace (Phase 10) with the shared
 * ByteLyst platform marketplace — H.12 in the ecosystem integration roadmap.
 *
 * Endpoints proxied:
 *   Public:   GET /api/marketplace, GET /api/marketplace/:id, GET /api/marketplace/:id/reviews,
 *             GET /api/marketplace/featured, GET /api/marketplace/categories
 *   Consumer: POST /api/marketplace/:id/install, DELETE /api/marketplace/:id/install,
 *             GET /api/marketplace/installs, POST /api/marketplace/:id/reviews,
 *             POST /api/marketplace/:id/vote
 *   Author:   POST /api/marketplace/listings, GET /api/marketplace/listings/mine,
 *             PUT /api/marketplace/listings/:id, DELETE /api/marketplace/listings/:id,
 *             POST /api/marketplace/listings/:id/submit, POST /api/marketplace/listings/:id/publish
 */

import type { FastifyInstance } from 'fastify';
import { config } from '../../lib/config.js';
import { PRODUCT_ID } from '../../lib/product-config.js';
import { ListListingsQuerySchema, ListInstallsQuerySchema, ListReviewsQuerySchema } from './types.js';

const platformUrl = config.PLATFORM_SERVICE_URL;

/** Build standard proxy headers for platform-service. */
function proxyHeaders(req: { id: string; headers: Record<string, string | string[] | undefined>; jwtPayload?: { sub: string } }): Record<string, string> {
  const headers: Record<string, string> = {
    'x-product-id': PRODUCT_ID,
    'x-request-id': req.id,
    'content-type': 'application/json',
  };
  // Forward JWT for authenticated routes (consumer + author endpoints)
  const auth = req.headers.authorization;
  if (typeof auth === 'string') headers['authorization'] = auth;
  return headers;
}

/** Forward a GET request to platform-service and return the JSON response. */
async function proxyGet(
  url: string,
  headers: Record<string, string>,
  req: { log: { warn: (obj: unknown, msg: string) => void } },
  reply: { code: (n: number) => void },
): Promise<unknown> {
  try {
    const res = await fetch(url, { headers });
    if (!res.ok) {
      reply.code(res.status);
      return { error: `Platform returned ${res.status}` };
    }
    return res.json();
  } catch (err) {
    req.log.warn({ err }, 'Failed to proxy marketplace request to platform-service');
    reply.code(502);
    return { error: 'Platform-service unavailable' };
  }
}

/** Forward a mutating request (POST/PUT/DELETE) to platform-service. */
async function proxyMutate(
  method: string,
  url: string,
  headers: Record<string, string>,
  body: unknown,
  req: { log: { warn: (obj: unknown, msg: string) => void } },
  reply: { code: (n: number) => void },
): Promise<unknown> {
  try {
    const res = await fetch(url, {
      method,
      headers,
      body: body ? JSON.stringify(body) : undefined,
    });
    if (!res.ok) {
      reply.code(res.status);
      const text = await res.text();
      try { return JSON.parse(text); } catch { return { error: text || `Platform returned ${res.status}` }; }
    }
    // 204 No Content
    if (res.status === 204) return { success: true };
    return res.json();
  } catch (err) {
    req.log.warn({ err }, 'Failed to proxy marketplace mutation to platform-service');
    reply.code(502);
    return { error: 'Platform-service unavailable' };
  }
}

export async function marketplaceRoutes(app: FastifyInstance): Promise<void> {

  // ── Public Routes ──

  // Browse catalog
  app.get('/api/marketplace', async (req, reply) => {
    const parsed = ListListingsQuerySchema.safeParse(req.query);
    if (!parsed.success) {
      reply.code(400);
      return { error: 'Invalid query', details: parsed.error.issues };
    }
    const params = new URLSearchParams();
    params.set('productId', PRODUCT_ID);
    for (const [k, v] of Object.entries(parsed.data)) {
      if (v !== undefined) params.set(k, String(v));
    }
    return proxyGet(`${platformUrl}/public/marketplace?${params}`, proxyHeaders(req), req, reply);
  });

  // Featured listings
  app.get('/api/marketplace/featured', async (req, reply) => {
    const limit = (req.query as Record<string, string>).limit || '10';
    const params = new URLSearchParams({ limit });
    return proxyGet(
      `${platformUrl}/public/marketplace/featured?${params}`,
      { ...proxyHeaders(req) },
      req, reply,
    );
  });

  // Categories
  app.get('/api/marketplace/categories', async (req, reply) => {
    return proxyGet(
      `${platformUrl}/public/marketplace/categories`,
      { ...proxyHeaders(req) },
      req, reply,
    );
  });

  // Listing detail
  app.get('/api/marketplace/:id', async (req, reply) => {
    const { id } = req.params as { id: string };
    return proxyGet(
      `${platformUrl}/public/marketplace/${encodeURIComponent(id)}`,
      proxyHeaders(req),
      req, reply,
    );
  });

  // Listing reviews
  app.get('/api/marketplace/:id/reviews', async (req, reply) => {
    const { id } = req.params as { id: string };
    const parsed = ListReviewsQuerySchema.safeParse(req.query);
    if (!parsed.success) {
      reply.code(400);
      return { error: 'Invalid query', details: parsed.error.issues };
    }
    const params = new URLSearchParams();
    for (const [k, v] of Object.entries(parsed.data)) {
      if (v !== undefined) params.set(k, String(v));
    }
    return proxyGet(
      `${platformUrl}/public/marketplace/${encodeURIComponent(id)}/reviews?${params}`,
      proxyHeaders(req),
      req, reply,
    );
  });

  // ── Consumer Routes (Authenticated) ──

  // Install listing
  app.post('/api/marketplace/:id/install', async (req, reply) => {
    const { id } = req.params as { id: string };
    return proxyMutate(
      'POST',
      `${platformUrl}/marketplace/listings/${encodeURIComponent(id)}/install`,
      proxyHeaders(req),
      null,
      req, reply,
    );
  });

  // Uninstall listing
  app.delete('/api/marketplace/:id/install', async (req, reply) => {
    const { id } = req.params as { id: string };
    return proxyMutate(
      'DELETE',
      `${platformUrl}/marketplace/listings/${encodeURIComponent(id)}/install`,
      proxyHeaders(req),
      null,
      req, reply,
    );
  });

  // My installs
  app.get('/api/marketplace/installs', async (req, reply) => {
    const parsed = ListInstallsQuerySchema.safeParse(req.query);
    if (!parsed.success) {
      reply.code(400);
      return { error: 'Invalid query', details: parsed.error.issues };
    }
    const params = new URLSearchParams();
    params.set('productId', PRODUCT_ID);
    for (const [k, v] of Object.entries(parsed.data)) {
      if (v !== undefined) params.set(k, String(v));
    }
    return proxyGet(
      `${platformUrl}/marketplace/installs?${params}`,
      proxyHeaders(req),
      req, reply,
    );
  });

  // Add review
  app.post('/api/marketplace/:id/reviews', async (req, reply) => {
    const { id } = req.params as { id: string };
    return proxyMutate(
      'POST',
      `${platformUrl}/marketplace/listings/${encodeURIComponent(id)}/reviews`,
      proxyHeaders(req),
      req.body,
      req, reply,
    );
  });

  // Vote/upvote toggle
  app.post('/api/marketplace/:id/vote', async (req, reply) => {
    const { id } = req.params as { id: string };
    return proxyMutate(
      'POST',
      `${platformUrl}/marketplace/listings/${encodeURIComponent(id)}/vote`,
      proxyHeaders(req),
      null,
      req, reply,
    );
  });

  // ── Author Routes (Authenticated) ──

  // Create listing
  app.post('/api/marketplace/listings', async (req, reply) => {
    return proxyMutate(
      'POST',
      `${platformUrl}/marketplace/listings`,
      proxyHeaders(req),
      req.body,
      req, reply,
    );
  });

  // My listings
  app.get('/api/marketplace/listings/mine', async (req, reply) => {
    return proxyGet(
      `${platformUrl}/marketplace/listings/mine`,
      proxyHeaders(req),
      req, reply,
    );
  });

  // Update listing
  app.put('/api/marketplace/listings/:id', async (req, reply) => {
    const { id } = req.params as { id: string };
    return proxyMutate(
      'PUT',
      `${platformUrl}/marketplace/listings/${encodeURIComponent(id)}`,
      proxyHeaders(req),
      req.body,
      req, reply,
    );
  });

  // Delete listing
  app.delete('/api/marketplace/listings/:id', async (req, reply) => {
    const { id } = req.params as { id: string };
    return proxyMutate(
      'DELETE',
      `${platformUrl}/marketplace/listings/${encodeURIComponent(id)}`,
      proxyHeaders(req),
      null,
      req, reply,
    );
  });

  // Submit for certification
  app.post('/api/marketplace/listings/:id/submit', async (req, reply) => {
    const { id } = req.params as { id: string };
    return proxyMutate(
      'POST',
      `${platformUrl}/marketplace/listings/${encodeURIComponent(id)}/submit`,
      proxyHeaders(req),
      req.body,
      req, reply,
    );
  });

  // Publish listing
  app.post('/api/marketplace/listings/:id/publish', async (req, reply) => {
    const { id } = req.params as { id: string };
    return proxyMutate(
      'POST',
      `${platformUrl}/marketplace/listings/${encodeURIComponent(id)}/publish`,
      proxyHeaders(req),
      null,
      req, reply,
    );
  });
}
