/**
 * Rules Routes
 *
 * REST API endpoints for rules management.
 */

import { Hono } from 'hono';
import { zValidator } from '@hono/zod-validator';
import { z } from 'zod';
import type { AppContext } from '../router.js';
import { createRulesLoader } from '../../rules/index.js';

export const rulesRoutes = new Hono<AppContext>();

/**
 * Save rule request schema
 */
const SaveRuleSchema = z.object({
  content: z.string(),
});

/**
 * GET /rules - List all rule files
 */
rulesRoutes.get('/', async (c) => {
  const repoRoot = c.get('repoRoot');
  const loader = createRulesLoader({ repoRoot });

  try {
    const rules = await loader.listRules();

    return c.json({
      rules: rules.map((name) => ({
        name: name.replace('.md', ''),
        filename: name,
      })),
      total: rules.length,
    });
  } catch (error) {
    return c.json(
      { error: error instanceof Error ? error.message : 'Unknown error' },
      500
    );
  }
});

/**
 * GET /rules/combined - Get all rules combined
 */
rulesRoutes.get('/combined', async (c) => {
  const repoRoot = c.get('repoRoot');
  const loader = createRulesLoader({ repoRoot });

  try {
    const rules = await loader.loadRules();

    return c.json({
      content: rules,
      formatted: loader.formatRulesForPrompt(rules),
    });
  } catch (error) {
    return c.json(
      { error: error instanceof Error ? error.message : 'Unknown error' },
      500
    );
  }
});

/**
 * GET /rules/agent/:name - Get rules for a specific agent
 */
rulesRoutes.get('/agent/:name', async (c) => {
  const repoRoot = c.get('repoRoot');
  const { name } = c.req.param();
  const loader = createRulesLoader({ repoRoot });

  try {
    const rules = await loader.getRulesForAgent(name);

    return c.json({
      agentName: name,
      content: rules,
      formatted: loader.formatRulesForPrompt(rules),
    });
  } catch (error) {
    return c.json(
      { error: error instanceof Error ? error.message : 'Unknown error' },
      500
    );
  }
});

/**
 * GET /rules/:name - Get a specific rule file
 */
rulesRoutes.get('/:name', async (c) => {
  const repoRoot = c.get('repoRoot');
  const { name } = c.req.param();
  const loader = createRulesLoader({ repoRoot });

  try {
    const content = await loader.getRule(name);

    if (content === null) {
      return c.json({ error: `Rule not found: ${name}` }, 404);
    }

    return c.json({
      name: name.replace('.md', ''),
      filename: name.endsWith('.md') ? name : `${name}.md`,
      content,
    });
  } catch (error) {
    return c.json(
      { error: error instanceof Error ? error.message : 'Unknown error' },
      500
    );
  }
});

/**
 * PUT /rules/:name - Create or update a rule file
 */
rulesRoutes.put('/:name', zValidator('json', SaveRuleSchema), async (c) => {
  const repoRoot = c.get('repoRoot');
  const { name } = c.req.param();
  const body = c.req.valid('json');
  const loader = createRulesLoader({ repoRoot });

  try {
    await loader.saveRule(name, body.content);

    return c.json({
      success: true,
      name: name.replace('.md', ''),
      message: `Rule "${name}" saved`,
    });
  } catch (error) {
    return c.json(
      { error: error instanceof Error ? error.message : 'Unknown error' },
      500
    );
  }
});

/**
 * DELETE /rules/:name - Delete a rule file
 */
rulesRoutes.delete('/:name', async (c) => {
  const repoRoot = c.get('repoRoot');
  const { name } = c.req.param();
  const loader = createRulesLoader({ repoRoot });

  try {
    const deleted = await loader.deleteRule(name);

    if (!deleted) {
      return c.json({ error: `Rule not found: ${name}` }, 404);
    }

    return c.json({
      success: true,
      message: `Rule "${name}" deleted`,
    });
  } catch (error) {
    return c.json(
      { error: error instanceof Error ? error.message : 'Unknown error' },
      500
    );
  }
});
