import { z } from "zod";
import { publicProcedure, protectedProcedure, router } from "../_core/trpc";
import { getDb } from "../db";
import { cashappPayments, wallets, users } from "../drizzle/schema";
import { eq, and } from "drizzle-orm";
import { TRPCError } from "@trpc/server";

export const cashappPaymentRouter = router({
  // Submit CashApp payment request
  submitPaymentRequest: protectedProcedure
    .input(
      z.object({
        packageId: z.number().int().positive(),
        cashtag: z.string().min(2).max(100),
        amount: z.number().positive(),
      })
    )
    .mutation(async ({ ctx, input }: any) => {
      const db = await getDb();
      if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });

      // Verify user is KYC verified
      if (ctx.user.kycStatus !== "approved") {
        throw new TRPCError({
          code: "FORBIDDEN",
          message: "You must be KYC verified to make CashApp payments",
        });
      }

      // Verify minimum amount (100 SC)
      if (input.amount < 100) {
        throw new TRPCError({
          code: "BAD_REQUEST",
          message: "Minimum CashApp payment is $100",
        });
      }

      // Create payment request
      await db.insert(cashappPayments).values({
        userId: ctx.user.id,
        packageId: input.packageId,
        amount: input.amount.toString(),
        cashtag: input.cashtag,
        status: "pending",
      });

      return {
        status: "pending",
        message: "Payment request submitted. We'll verify within 24 hours.",
      };
    }),

  // Get user's CashApp payment history
  getPaymentHistory: protectedProcedure
    .input(
      z.object({
        limit: z.number().int().positive().default(10),
        offset: z.number().int().nonnegative().default(0),
      })
    )
    .query(async ({ ctx, input }: any) => {
      const db = await getDb();
      if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });

      const payments = await db
        .select()
        .from(cashappPayments)
        .where(eq(cashappPayments.userId, ctx.user.id))
        .orderBy(cashappPayments.createdAt)
        .limit(input.limit)
        .offset(input.offset);

      return payments;
    }),

  // Admin: Get all pending CashApp payments
  getPendingPayments: protectedProcedure.query(async ({ ctx }: any) => {
    if (ctx.user.role !== "admin") {
      throw new TRPCError({
        code: "FORBIDDEN",
        message: "Only admins can view pending payments",
      });
    }

    const db = await getDb();
    if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });

    const payments = await db
      .select({
        id: cashappPayments.id,
        userId: cashappPayments.userId,
        username: users.username,
        email: users.email,
        amount: cashappPayments.amount,
        cashtag: cashappPayments.cashtag,
        status: cashappPayments.status,
        createdAt: cashappPayments.createdAt,
      })
      .from(cashappPayments)
      .innerJoin(users, eq(cashappPayments.userId, users.id))
      .where(eq(cashappPayments.status, "pending"))
      .orderBy(cashappPayments.createdAt);

    return payments;
  }),

  // Admin: Verify and complete CashApp payment
  verifyPayment: protectedProcedure
    .input(
      z.object({
        paymentId: z.number().int().positive(),
        approve: z.boolean(),
        failureReason: z.string().optional(),
      })
    )
    .mutation(async ({ ctx, input }: any) => {
      if (ctx.user.role !== "admin") {
        throw new TRPCError({
          code: "FORBIDDEN",
          message: "Only admins can verify payments",
        });
      }

      const db = await getDb();
      if (!db) throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });

      // Get payment
      const payment = await db
        .select()
        .from(cashappPayments)
        .where(eq(cashappPayments.id, input.paymentId));

      if (!payment.length) {
        throw new TRPCError({
          code: "NOT_FOUND",
          message: "Payment not found",
        });
      }

      const p = payment[0];

      if (input.approve) {
        // Credit user's wallet with coins
        const wallet = await db
          .select()
          .from(wallets)
          .where(eq(wallets.userId, p.userId));

        if (wallet.length) {
          const currentBalance = parseFloat(wallet[0].scBalance || "0");
          const newBalance = (currentBalance + parseFloat(p.amount)).toString();

          await db
            .update(wallets)
            .set({ scBalance: newBalance })
            .where(eq(wallets.userId, p.userId));
        }

        // Update payment status
        await db
          .update(cashappPayments)
          .set({
            status: "completed",
            verifiedAt: new Date(),
            verifiedBy: ctx.user.id,
            completedAt: new Date(),
          })
          .where(eq(cashappPayments.id, input.paymentId));

        return {
          success: true,
          message: `Payment approved. ${p.amount} SC credited to user.`,
        };
      } else {
        // Reject payment
        await db
          .update(cashappPayments)
          .set({
            status: "failed",
            failureReason: input.failureReason || "Admin rejected",
            verifiedAt: new Date(),
            verifiedBy: ctx.user.id,
          })
          .where(eq(cashappPayments.id, input.paymentId));

        return {
          success: true,
          message: "Payment rejected.",
        };
      }
    }),
});
