import { z } from 'zod';
import { publicProcedure, router } from '../trpc';
import { signUp, signIn, signOut, getCurrentUser, resetPassword } from '@crafted/auth';
import { db } from '@crafted/database';
import { sendWelcomeEmail } from '@crafted/emails';

export const authRouter = router({
  register: publicProcedure
    .input(
      z.object({
        email: z.string().email(),
        password: z.string().min(8),
        name: z.string().optional(),
      })
    )
    .mutation(async ({ input }) => {
      let supabaseUserId: string | undefined;

      try {
        const existingUser = await db.user.findUnique({
          where: { email: input.email },
        });

        if (existingUser) {
          throw new Error('User with this email already exists');
        }

        const data = await signUp(input);

        if (!data.user) {
          throw new Error('Failed to create user in authentication system');
        }

        supabaseUserId = data.user.id;

        await db.user.create({
          data: {
            email: input.email,
            name: input.name,
            supabaseId: data.user.id,
          },
        });

        try {
          await sendWelcomeEmail(input.email, input.name);
        } catch (emailError) {
          console.error('Failed to send welcome email:', emailError);
        }

        return {
          user: data.user,
          session: data.session,
        };
      } catch (error) {
        if (supabaseUserId) {
          try {
            const serviceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
            if (serviceRoleKey) {
              const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
              const { createClient } = await import('@supabase/supabase-js');
              const adminClient = createClient(supabaseUrl, serviceRoleKey);
              await adminClient.auth.admin.deleteUser(supabaseUserId);
            }
          } catch (rollbackError) {
            console.error('Failed to rollback Supabase user:', rollbackError);
          }
        }

        throw error;
      }
    }),

  login: publicProcedure
    .input(
      z.object({
        email: z.string().email(),
        password: z.string(),
      })
    )
    .mutation(async ({ input }) => {
      const data = await signIn(input);
      return {
        user: data.user,
        session: data.session,
      };
    }),

  logout: publicProcedure.mutation(async () => {
    await signOut();
    return { success: true };
  }),

  me: publicProcedure.query(async () => {
    const supabaseUser = await getCurrentUser();
    if (!supabaseUser) return null;

    const dbUser = await db.user.findUnique({
      where: { supabaseId: supabaseUser.id },
    });

    return dbUser;
  }),

  resetPassword: publicProcedure
    .input(
      z.object({
        email: z.string().email(),
      })
    )
    .mutation(async ({ input }) => {
      await resetPassword(input.email);
      return { success: true };
    }),
});
