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

import { mailSendPayloadSchema } from '@/entities/mailSendItem';
import { queryMailConversations, queryMailMessages, getLastMailSync } from '@/features/imail';
import { enqueueMailSend } from '@/features/imail/sendService';

const limitParam = z.coerce.number().int().positive().max(500).default(100);
const sinceParam = z.string().optional();
const convIdParam = z.string().min(1);

const requiredDeviceId = z.object({ deviceId: z.string().min(1) });

function errorResponse(c: Context, err: unknown, fallback: string) {
  if (err instanceof z.ZodError) {
    return c.json(
      {
        success: false,
        error: { code: 'validation_error', message: 'invalid request payload', issues: err.issues },
      },
      400,
    );
  }
  return c.json(
    {
      success: false,
      error: { code: 'enqueue_error', message: err instanceof Error ? err.message : fallback },
    },
    500,
  );
}

export const mailMyRouter = new Hono()
  .get('/conversations', async (c) => {
    const deviceId = c.req.query('deviceId') ?? undefined;
    return c.json(await queryMailConversations(deviceId));
  })
  .get('/conversations/:id/messages', async (c) => {
    const convId = convIdParam.parse(c.req.param('id'));
    const limit = limitParam.parse(c.req.query('limit') ?? '100');
    const since = sinceParam.parse(c.req.query('since'));
    return c.json(await queryMailMessages({ conversationId: convId, limit, since }));
  })
  .get('/last-sync', async (c) => {
    const deviceId = c.req.query('deviceId') ?? '';
    if (!deviceId) return c.json({ lastSync: null });
    return c.json({ lastSync: await getLastMailSync(deviceId) });
  })
  .post('/send', async (c) => {
    try {
      const { deviceId } = requiredDeviceId.parse({ deviceId: c.req.query('deviceId') });
      const payload = mailSendPayloadSchema.parse(await c.req.json());
      const { id } = await enqueueMailSend({ deviceId, action: 'send_mail', payload });
      return c.json({ success: true, data: { sendQueueId: id } });
    } catch (err) {
      return errorResponse(c, err, 'failed to enqueue send_mail');
    }
  });
