import { wrap } from "@typeschema/valibot";
import { TRPCError } from "@trpc/server";
import { createTRPCRouter, protectedProcedure } from "../utils";
import {
  UpdateUserSchema,
  InviteMemberSchema,
  RemoveMemberSchema,
  UpdateRoleSchema,
} from "../schemas/user";
import { getUserById, updateUser, deleteUser } from "~/server/services/user.service";
import {
  getFamilyGroup,
  inviteMember,
  removeMember,
  updateMemberRole,
} from "~/server/services/family.service";

export const userRouter = createTRPCRouter({
  me: protectedProcedure.query(async ({ ctx }) => {
    const user = await getUserById(ctx.user.id);
    return user;
  }),

  update: protectedProcedure
    .input(wrap(UpdateUserSchema))
    .mutation(async ({ ctx, input }) => {
      const updated = await updateUser(ctx.user.id, input);
      return updated;
    }),

  delete: protectedProcedure.mutation(async ({ ctx }) => {
    await deleteUser(ctx.user.id);
    return { success: true };
  }),

  listFamilyMembers: protectedProcedure.query(async ({ ctx }) => {
    const group = await getFamilyGroup(ctx.user.id);
    return group.members;
  }),

  inviteFamilyMember: protectedProcedure
    .input(wrap(InviteMemberSchema))
    .mutation(async ({ ctx, input }) => {
      const group = await getFamilyGroup(ctx.user.id);

      const callerMember = group.members.find(
        (m) => m.userId === ctx.user.id,
      );

      if (!callerMember || (callerMember.role !== "owner" && callerMember.role !== "admin")) {
        throw new TRPCError({
          code: "FORBIDDEN",
          message: "Only owner or admin can invite members",
        });
      }

      const invitation = await inviteMember(
        group.id,
        input.email,
        ctx.user.id,
        input.role,
      );

      return invitation;
    }),

  removeFamilyMember: protectedProcedure
    .input(wrap(RemoveMemberSchema))
    .mutation(async ({ ctx, input }) => {
      const group = await getFamilyGroup(ctx.user.id);
      await removeMember(group.id, input.userId, ctx.user.id);
      return { success: true };
    }),

  updateFamilyMemberRole: protectedProcedure
    .input(wrap(UpdateRoleSchema))
    .mutation(async ({ ctx, input }) => {
      const group = await getFamilyGroup(ctx.user.id);
      const updated = await updateMemberRole(
        group.id,
        input.userId,
        input.role,
        ctx.user.id,
      );
      return updated;
    }),
});
