import { protectedProcedure, router } from "../_core/trpc.ts";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { getDb } from "../db.ts";
import { playerProfiles, friends, gameChat, winShareEvents } from "../../drizzle/schema.ts";
import { eq, and } from "drizzle-orm";

export const socialRouter = router({
  // Player Profiles
  getProfile: protectedProcedure
    .input(z.object({ userId: z.number() }))
    .query(async ({ input }) => {
      const db = await getDb();
      if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });
      const profile = await db.select().from(playerProfiles).where(eq(playerProfiles.userId, input.userId)).limit(1);
      return profile[0] || null;
    }),

  updateProfile: protectedProcedure
    .input(
      z.object({
        bio: z.string().optional(),
        avatarUrl: z.string().optional(),
        bannerUrl: z.string().optional(),
        isPublic: z.boolean().optional(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const db = await getDb();
      if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });

      const existing = await db.select().from(playerProfiles).where(eq(playerProfiles.userId, ctx.user!.id)).limit(1);

      if (existing[0]) {
        await db.update(playerProfiles).set({...input, updatedAt: new Date()}).where(eq(playerProfiles.userId, ctx.user!.id));
      } else {
        await db.insert(playerProfiles).values({
          userId: ctx.user!.id,
          bio: input.bio || null,
          avatarUrl: input.avatarUrl || null,
          bannerUrl: input.bannerUrl || null,
          isPublic: input.isPublic ?? true,
          createdAt: new Date(),
          updatedAt: new Date(),
        });
      }

      return { success: true };
    }),

  // Friends
  sendFriendRequest: protectedProcedure
    .input(z.object({ friendId: z.number() }))
    .mutation(async ({ ctx, input }) => {
      const db = await getDb();
      if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });

      await db.insert(friends).values({
        userId: ctx.user!.id,
        friendId: input.friendId,
        status: "pending",
        requestedAt: new Date(),
      } as any);

      return { success: true };
    }),

  acceptFriendRequest: protectedProcedure
    .input(z.object({ friendId: z.number() }))
    .mutation(async ({ ctx, input }) => {
      const db = await getDb();
      if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });

      await db
        .update(friends)
        .set({ status: "accepted", acceptedAt: new Date() })
        .where(eq(friends.friendId, ctx.user!.id));

      return { success: true };
    }),

  getFriends: protectedProcedure.query(async ({ ctx }) => {
    const db = await getDb();
    if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });
    return await db.select().from(friends).where(eq(friends.userId, ctx.user!.id));
  }),

  // Game Chat
  sendChatMessage: protectedProcedure
    .input(
      z.object({
        gameId: z.number().optional(),
        message: z.string(),
        isPublic: z.boolean().default(true),
        recipientId: z.number().optional(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const db = await getDb();
      if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });

      await db.insert(gameChat).values({
        gameId: input.gameId,
        userId: ctx.user!.id,
        message: input.message,
        isPublic: input.isPublic,
        recipientId: input.recipientId,
        createdAt: new Date(),
      } as any);

      return { success: true };
    }),

  getGameChat: protectedProcedure
    .input(z.object({ gameId: z.number() }))
    .query(async ({ input }) => {
      const db = await getDb();
      if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });
      return await db.select().from(gameChat).where(eq(gameChat.gameId, input.gameId));
    }),

  // Win Sharing
  createWinShare: protectedProcedure
    .input(
      z.object({
        gameId: z.number(),
        winAmount: z.number(),
        platform: z.enum(["facebook", "messenger", "sms", "twitter"]),
        referralCode: z.string(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      const db = await getDb();
      if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });

      const shareMessage = `I just won ${input.winAmount} SC playing a game on PlayCoinKrazy.com! Join me: ${input.referralCode}`;

      await db.insert(winShareEvents).values({
        userId: ctx.user!.id,
        gameId: input.gameId,
        winAmount: input.winAmount.toString(),
        shareMessage,
        platform: input.platform,
        referralCode: input.referralCode,
        sharedAt: new Date(),
      } as any);

      return { shareMessage };
    }),
});
