/**
 * Admin Withdrawal Router
 * tRPC procedures for managing withdrawal requests
 */

import { router, protectedProcedure, adminProcedure } from "../_core/trpc.ts";
import { z } from "zod";
import { TRPCError } from "@trpc/server";
import {
  approveWithdrawalRequest,
  rejectWithdrawalRequest,
  completeWithdrawal,
  failWithdrawal,
  calculateWithdrawalFee,
  DEFAULT_WITHDRAWAL_POLICY,
} from "../withdrawalManagementSystem.ts";
import {
  sendEmailNotification,
  notifyAdminWithdrawal,
} from "../emailNotificationService.ts";
import {
  recordWithdrawalEvent,
  recordFraudAlertEvent,
} from "../realtimeMonitoringService.ts";

/**
 * ENFORCEMENT RULES - SITEWIDE:
 * - Minimum withdrawal amount: 100 SC
 * - KYC verification: REQUIRED for all withdrawals
 * - These rules are enforced at all levels: user, admin, and system
 */

export const adminWithdrawalRouter = router({
  /**
   * Get pending withdrawal requests
   */
  getPendingWithdrawals: adminProcedure.query(async ({ ctx }) => {
    // TODO: Fetch from database
    return {
      withdrawals: [
        {
          id: "w_001",
          playerId: 123,
          playerName: "John Doe",
          playerEmail: "john@example.com",
          amount: 500,
          currency: "SC" as const,
          method: "bank_transfer" as const,
          status: "pending" as const,
          requestedAt: new Date(),
          kycVerified: true,
        },
      ],
      total: 1,
    };
  }),

  /**
   * Get withdrawal details
   */
  getWithdrawalDetails: adminProcedure
    .input(z.object({ withdrawalId: z.string() }))
    .query(async ({ input, ctx }) => {
      // TODO: Fetch from database
      return {
        id: input.withdrawalId,
        playerId: 123,
        playerName: "John Doe",
        playerEmail: "john@example.com",
        amount: 500,
        currency: "SC" as const,
        method: "bank_transfer" as const,
        status: "pending" as const,
        requestedAt: new Date(),
        kycVerified: true,
        bankDetails: {
          accountHolderName: "John Doe",
          accountNumber: "****1234",
          routingNumber: "****5678",
          bankName: "Example Bank",
        },
      };
    }),

  /**
   * Approve withdrawal request
   */
  approveWithdrawal: adminProcedure
    .input(
      z.object({
        withdrawalId: z.string(),
        notes: z.string().optional(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      try {
        // TODO: Fetch withdrawal from database
        const withdrawal = {
          id: input.withdrawalId,
          playerId: 123,
          playerName: "John Doe",
          playerEmail: "john@example.com",
          amount: 500,
          currency: "SC" as const,
          method: "bank_transfer" as const,
          status: "pending" as const,
          requestedAt: new Date(),
          kycVerified: true,
        };

        // Validate withdrawal
        if (withdrawal.status !== "pending") {
          throw new TRPCError({
            code: "BAD_REQUEST",
            message: "Withdrawal is not in pending status",
          });
        }

        if (!withdrawal.kycVerified) {
          throw new TRPCError({
            code: "BAD_REQUEST",
            message: "Player has not completed KYC verification",
          });
        }

        // Calculate fee
        const { fee, netAmount } = calculateWithdrawalFee(
          withdrawal.amount,
          DEFAULT_WITHDRAWAL_POLICY
        );

        // Update withdrawal status
        const updatedWithdrawal = {
          ...withdrawal,
          status: "approved" as const,
          approvedAt: new Date(),
          approvedBy: ctx.user.id,
          notes: input.notes,
        };

        // TODO: Save to database

        // Send email notification to player
        await sendEmailNotification(
          "withdrawal_approved",
          withdrawal.playerEmail,
          withdrawal.playerName,
          {
            playerName: withdrawal.playerName,
            amount: withdrawal.amount,
            currency: withdrawal.currency,
            method: withdrawal.method,
            withdrawalId: withdrawal.id,
          }
        );

        // Record event
        recordWithdrawalEvent(
          "withdrawal_approved",
          withdrawal.playerId,
          withdrawal.playerName,
          withdrawal.amount,
          withdrawal.currency,
          withdrawal.id
        );

        return {
          success: true,
          withdrawal: updatedWithdrawal,
          fee,
          netAmount,
          message: "Withdrawal approved successfully",
        };
      } catch (error) {
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: (error as Error).message,
        });
      }
    }),

  /**
   * Reject withdrawal request
   */
  rejectWithdrawal: adminProcedure
    .input(
      z.object({
        withdrawalId: z.string(),
        reason: z.string().min(10, "Reason must be at least 10 characters"),
      })
    )
    .mutation(async ({ input, ctx }) => {
      try {
        // TODO: Fetch withdrawal from database
        const withdrawal = {
          id: input.withdrawalId,
          playerId: 123,
          playerName: "John Doe",
          playerEmail: "john@example.com",
          amount: 500,
          currency: "SC" as const,
          method: "bank_transfer" as const,
          status: "pending" as const,
          requestedAt: new Date(),
          kycVerified: true,
        };

        if (withdrawal.status !== "pending") {
          throw new TRPCError({
            code: "BAD_REQUEST",
            message: "Withdrawal is not in pending status",
          });
        }

        // Update withdrawal status
        const updatedWithdrawal = {
          ...withdrawal,
          status: "rejected" as const,
          failureReason: input.reason,
          approvedBy: ctx.user.id,
        };

        // TODO: Save to database

        // Send email notification to player
        await sendEmailNotification(
          "withdrawal_rejected",
          withdrawal.playerEmail,
          withdrawal.playerName,
          {
            playerName: withdrawal.playerName,
            amount: withdrawal.amount,
            currency: withdrawal.currency,
            reason: input.reason,
            withdrawalId: withdrawal.id,
          }
        );

        // Record event
        recordWithdrawalEvent(
          "withdrawal_rejected",
          withdrawal.playerId,
          withdrawal.playerName,
          withdrawal.amount,
          withdrawal.currency,
          withdrawal.id
        );

        return {
          success: true,
          withdrawal: updatedWithdrawal,
          message: "Withdrawal rejected successfully",
        };
      } catch (error) {
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: (error as Error).message,
        });
      }
    }),

  /**
   * Process withdrawal (mark as completed)
   */
  processWithdrawal: adminProcedure
    .input(
      z.object({
        withdrawalId: z.string(),
        payoutId: z.string().optional(),
        checkNumber: z.string().optional(),
      })
    )
    .mutation(async ({ input, ctx }) => {
      try {
        // TODO: Fetch withdrawal from database
        const withdrawal = {
          id: input.withdrawalId,
          playerId: 123,
          playerName: "John Doe",
          playerEmail: "john@example.com",
          amount: 500,
          currency: "SC" as const,
          method: "bank_transfer" as const,
          status: "approved" as const,
          requestedAt: new Date(),
          kycVerified: true,
        };

        if (withdrawal.status !== "approved") {
          throw new TRPCError({
            code: "BAD_REQUEST",
            message: "Withdrawal must be approved before processing",
          });
        }

        // Update withdrawal status
        const updatedWithdrawal = {
          ...withdrawal,
          status: "completed" as const,
          completedAt: new Date(),
          payoutId: input.payoutId,
          checkNumber: input.checkNumber,
        };

        // TODO: Save to database

        // Send email notification to player
        await sendEmailNotification(
          "withdrawal_completed",
          withdrawal.playerEmail,
          withdrawal.playerName,
          {
            playerName: withdrawal.playerName,
            amount: withdrawal.amount,
            currency: withdrawal.currency,
            method: withdrawal.method,
            withdrawalId: withdrawal.id,
            payoutId: input.payoutId || "N/A",
            completedDate: new Date().toLocaleDateString(),
          }
        );

        // Record event
        recordWithdrawalEvent(
          "withdrawal_completed",
          withdrawal.playerId,
          withdrawal.playerName,
          withdrawal.amount,
          withdrawal.currency,
          withdrawal.id
        );

        return {
          success: true,
          withdrawal: updatedWithdrawal,
          message: "Withdrawal processed successfully",
        };
      } catch (error) {
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: (error as Error).message,
        });
      }
    }),

  /**
   * Get withdrawal statistics
   */
  getWithdrawalStats: adminProcedure.query(async ({ ctx }) => {
    // TODO: Calculate from database
    return {
      totalRequests: 150,
      totalAmount: 45000,
      pendingRequests: 12,
      pendingAmount: 8750.25,
      approvedRequests: 85,
      approvedAmount: 28500,
      completedRequests: 45,
      completedAmount: 15000,
      rejectedRequests: 8,
      rejectedAmount: 2750,
      averageWithdrawalAmount: 300,
      averageProcessingTime: 18, // hours
      successRate: 90,
    };
  }),

  /**
   * Get withdrawal history for a player
   */
  getPlayerWithdrawalHistory: adminProcedure
    .input(z.object({ playerId: z.number() }))
    .query(async ({ input, ctx }) => {
      // TODO: Fetch from database
      return {
        withdrawals: [
          {
            id: "w_001",
            playerId: input.playerId,
            amount: 500,
            currency: "SC" as const,
            method: "bank_transfer" as const,
            status: "completed" as const,
            requestedAt: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
            completedAt: new Date(Date.now() - 6 * 24 * 60 * 60 * 1000),
          },
        ],
        total: 1,
      };
    }),
});
