import { wrap } from "@typeschema/valibot";
import {
  object,
  string,
  optional,
  record,
  boolean,
  picklist,
} from "valibot";
import { createTRPCRouter, protectedProcedure, adminProcedure } from "../utils";
import {
  sendEmail,
  sendPush,
  sendSMS,
  registerDevice,
  unregisterDevice,
  listDevices,
  getPreferences,
  updatePreferences,
} from "~/server/services/notification.service";

const SendEmailSchema = object({
  to: string(),
  subject: string(),
  html: string(),
  text: optional(string()),
});

const SendPushSchema = object({
  title: string(),
  body: string(),
  data: optional(record(string(), string())),
});

const SendSMSSchema = object({
  phoneNumber: string(),
  message: string(),
});

const RegisterDeviceSchema = object({
  token: string(),
  platform: picklist(["ios", "android", "web"]),
  deviceType: picklist(["mobile", "web", "desktop"]),
});

const UnregisterDeviceSchema = object({
  token: string(),
});

const UpdatePreferencesSchema = object({
  emailEnabled: optional(boolean()),
  pushEnabled: optional(boolean()),
  smsEnabled: optional(boolean()),
});

export const notificationRouter = createTRPCRouter({
  sendEmail: adminProcedure
    .input(wrap(SendEmailSchema))
    .mutation(async ({ input }) => {
      return sendEmail(input.to, input.subject, input.html, input.text);
    }),

  sendPush: protectedProcedure
    .input(wrap(SendPushSchema))
    .mutation(async ({ ctx, input }) => {
      return sendPush(ctx.user.id, input.title, input.body, input.data);
    }),

  sendSMS: protectedProcedure
    .input(wrap(SendSMSSchema))
    .mutation(async ({ input }) => {
      return sendSMS(input.phoneNumber, input.message);
    }),

  registerDevice: protectedProcedure
    .input(wrap(RegisterDeviceSchema))
    .mutation(async ({ ctx, input }) => {
      return registerDevice(ctx.user.id, input.token, input.platform, input.deviceType);
    }),

  unregisterDevice: protectedProcedure
    .input(wrap(UnregisterDeviceSchema))
    .mutation(async ({ ctx, input }) => {
      return unregisterDevice(ctx.user.id, input.token);
    }),

  listDevices: protectedProcedure.query(async ({ ctx }) => {
    return listDevices(ctx.user.id);
  }),

  getPreferences: protectedProcedure.query(async ({ ctx }) => {
    return getPreferences(ctx.user.id);
  }),

  updatePreferences: protectedProcedure
    .input(wrap(UpdatePreferencesSchema))
    .mutation(async ({ ctx, input }) => {
      return updatePreferences(ctx.user.id, input);
    }),
});
