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

import { reminderSendPayloadSchema } from '@/entities/reminderSendItem';
import {
  enqueueReminderChange,
  getIReminderStats,
  queryReminders,
} from '@/features/ireminders';

// Auth follow-up: deviceId is currently passed as a query/body param. Once
// SSO session resolution lands, derive it from the session.
const deviceIdQuery = z.string().min(1);
const optionalDeviceIdQuery = z.string().min(1).optional();
const limitParam = z.coerce.number().int().positive().max(1000).default(200);

const createSchema = reminderSendPayloadSchema.extend({
  deviceId: z.string().min(1),
});
const updateSchema = reminderSendPayloadSchema.extend({
  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 remindersMyRouter = new Hono()
  .get('/stats', async (c) => {
    try {
      const deviceId = deviceIdQuery.parse(c.req.query('deviceId'));
      return c.json({ success: true, data: await getIReminderStats(deviceId) });
    } catch (err) {
      return errorResponse(c, err, 'failed to load reminder stats');
    }
  })
  .get('/', async (c) => {
    try {
      const deviceId = optionalDeviceIdQuery.parse(c.req.query('deviceId'));
      const calendarId = z.string().optional().parse(c.req.query('calendarId'));
      const isCompletedRaw = c.req.query('isCompleted');
      const isCompleted =
        isCompletedRaw === undefined ? undefined : isCompletedRaw === 'true';
      const limit = limitParam.parse(c.req.query('limit') ?? '200');
      const offset = z.coerce
        .number()
        .int()
        .nonnegative()
        .default(0)
        .parse(c.req.query('offset') ?? '0');
      const reminders = await queryReminders({ deviceId, calendarId, isCompleted, limit, offset });
      return c.json({ success: true, data: { reminders } });
    } catch (err) {
      return errorResponse(c, err, 'failed to list reminders');
    }
  })
  .post('/', async (c) => {
    try {
      const body = createSchema.parse(await c.req.json());
      const { deviceId, ...payload } = body;
      const { id } = await enqueueReminderChange({
        deviceId,
        action: 'create_reminder',
        payload,
      });
      return c.json({ success: true, data: { sendQueueId: id } });
    } catch (err) {
      return errorResponse(c, err, 'failed to enqueue create_reminder');
    }
  })
  .put('/:id', async (c) => {
    try {
      const reminderIdentifier = c.req.param('id');
      const body = updateSchema.parse(await c.req.json());
      const { deviceId, ...rest } = body;
      const payload = { ...rest, reminderIdentifier };
      const { id } = await enqueueReminderChange({
        deviceId,
        action: 'update_reminder',
        payload,
      });
      return c.json({ success: true, data: { sendQueueId: id } });
    } catch (err) {
      return errorResponse(c, err, 'failed to enqueue update_reminder');
    }
  })
  .delete('/:id', async (c) => {
    try {
      const reminderIdentifier = c.req.param('id');
      const deviceId = deviceIdQuery.parse(c.req.query('deviceId'));
      const { id } = await enqueueReminderChange({
        deviceId,
        action: 'delete_reminder',
        payload: { reminderIdentifier },
      });
      return c.json({ success: true, data: { sendQueueId: id } });
    } catch (err) {
      return errorResponse(c, err, 'failed to enqueue delete_reminder');
    }
  });
