import { Hono } from 'hono';
import { z } from 'zod';

import { getDb, pgGet } from '@/shared/db';
import { registerDevice } from '@/features/devices';

const registerSchema = z.object({
  name: z.string().min(1).max(128),
  platform: z.string().default('macos'),
  hardwareId: z.string().min(1).max(255),
});

const deviceIdParam = z.string().min(1).max(255);

export const devicesClientRouter = new Hono()
  .post('/register', async (c) => {
    const parsed = registerSchema.parse(await c.req.json());
    const result = await registerDevice(parsed.name, parsed.platform, parsed.hardwareId);
    const status = result.created ? 201 : 200;
    // The Swift client reads data.deviceId and data.code. The token IS the code —
    // it's displayed to the user for admin approval, then later returned by /status.
    return c.json({ success: true, data: { deviceId: result.device.id, code: result.token } }, status);
  })
  // Public — no device-token auth required. Called by the Swift client BEFORE it has a token,
  // to poll for admin approval. Returns token only when active and not revoked.
  .get('/:id/status', async (c) => {
    const id = deviceIdParam.parse(c.req.param('id'));
    const pool = getDb();
    const row = await pgGet<{ id: string; revoked_at: string | null; token: string }>(
      pool,
      'SELECT id, revoked_at, token FROM macsync.devices WHERE id = $1',
      [id],
    );

    if (!row) {
      // Return isActive:false rather than 404 — the client polls this before registration is approved.
      return c.json({ success: true, data: { isActive: false, token: null } });
    }

    const isActive = row.revoked_at === null;
    return c.json({
      success: true,
      data: {
        isActive,
        token: isActive ? row.token : null,
      },
    });
  });
