import { z } from "zod";
import { router, protectedProcedure } from "../_core/trpc.ts";
import { TRPCError } from "@trpc/server";
import { notifyOwner } from "../_core/notification.ts";
import { getDb } from "../db.ts";
import { eq } from "drizzle-orm";
import { fraudAlerts, users } from "../../drizzle/schema.ts";

/**
 * Router for sending fraud alert notifications to admins
 */
export const fraudAlertNotificationsRouter = router({
  /**
   * Send fraud alert notification to owner/admins
   */
  sendAlertNotification: protectedProcedure
    .input(
      z.object({
        alertId: z.number(),
        urgency: z.enum(["normal", "high", "critical"]).default("normal"),
      })
    )
    .mutation(async ({ ctx, input }) => {
      // Verify admin role
      if (ctx.user.role !== "admin") {
        throw new TRPCError({ code: "FORBIDDEN", message: "Admin access required" });
      }

      const db = await getDb();
      if (!db) throw new Error("Database unavailable");

      // Get alert details
      const alert = await db
        .select()
        .from(fraudAlerts)
        .where(eq(fraudAlerts.id, input.alertId))
        .limit(1);

      if (!alert[0]) {
        throw new TRPCError({ code: "NOT_FOUND", message: "Alert not found" });
      }

      // Get user details
      const user = await db
        .select()
        .from(users)
        .where(eq(users.id, alert[0].userId))
        .limit(1);

      const userData = user[0];
      const alertData = alert[0];

      // Format notification message
      const urgencyEmoji = {
        normal: "⚠️",
        high: "🔴",
        critical: "🚨",
      }[input.urgency];

      const title = `${urgencyEmoji} Fraud Alert: ${alertData.alertType.replace(/_/g, " ").toUpperCase()}`;

      const content = `
**Alert ID:** ${alertData.id}
**User:** ${userData?.name || "Unknown"} (ID: ${userData?.id})
**Email:** ${userData?.email || "N/A"}
**Severity:** ${alertData.severity.toUpperCase()}
**Type:** ${alertData.alertType.replace(/_/g, " ")}

**Description:**
${alertData.description}

**Details:**
${JSON.stringify(alertData.details ? JSON.parse(alertData.details) : {}, null, 2)}

**Created:** ${new Date(alertData.createdAt).toLocaleString()}
**Status:** ${alertData.status}

---
Review this alert in the admin dashboard and take appropriate action.
      `.trim();

      // Send notification to owner
      const notificationSent = await notifyOwner({
        title,
        content,
      });

      if (!notificationSent) {
        throw new TRPCError({
          code: "INTERNAL_SERVER_ERROR",
          message: "Failed to send notification",
        });
      }

      console.log(`[Fraud Alert Notification] Sent alert ${input.alertId} to owner`);

      return { success: true, message: "Notification sent to admin" };
    }),

  /**
   * Send batch notification for critical alerts
   */
  sendCriticalAlertsNotification: protectedProcedure.mutation(async ({ ctx }) => {
    // Verify admin role
    if (ctx.user.role !== "admin") {
      throw new TRPCError({ code: "FORBIDDEN", message: "Admin access required" });
    }

    const db = await getDb();
    if (!db) throw new Error("Database unavailable");

    // Get all open critical alerts from last 24 hours
    const oneDayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();

    const criticalAlerts = await db
      .select()
      .from(fraudAlerts)
      .where(
        (table) =>
          `${table.severity} = 'critical' AND ${table.status} = 'open' AND ${table.createdAt} >= '${oneDayAgo}'`
      );

    if (criticalAlerts.length === 0) {
      return { success: true, message: "No critical alerts to notify" };
    }

    // Group by user
    const alertsByUser: Record<number, typeof criticalAlerts> = {};
    for (const alert of criticalAlerts) {
      if (!alertsByUser[alert.userId]) {
        alertsByUser[alert.userId] = [];
      }
      alertsByUser[alert.userId].push(alert);
    }

    // Send summary notification
    const summary = Object.entries(alertsByUser)
      .map(([userId, alerts]) => `- User ${userId}: ${alerts.length} critical alert(s)`)
      .join("\n");

    const title = `🚨 Critical Fraud Alerts Summary`;
    const content = `
**Total Critical Alerts (Last 24h):** ${criticalAlerts.length}
**Affected Users:** ${Object.keys(alertsByUser).length}

${summary}

Please review and investigate these alerts immediately.
    `.trim();

    const notificationSent = await notifyOwner({
      title,
      content,
    });

    if (!notificationSent) {
      throw new TRPCError({
        code: "INTERNAL_SERVER_ERROR",
        message: "Failed to send notification",
      });
    }

    console.log(
      `[Fraud Alert Notification] Sent critical alerts summary to owner (${criticalAlerts.length} alerts)`
    );

    return {
      success: true,
      message: `Sent summary notification for ${criticalAlerts.length} critical alerts`,
    };
  }),

  /**
   * Get notification preferences
   */
  getPreferences: protectedProcedure.query(async ({ ctx }) => {
    // Verify admin role
    if (ctx.user.role !== "admin") {
      throw new TRPCError({ code: "FORBIDDEN", message: "Admin access required" });
    }

    // Return default preferences (can be extended to store in DB)
    return {
      notifyOnCritical: true,
      notifyOnHigh: true,
      notifyOnMedium: false,
      notifyOnLow: false,
      batchNotifications: true,
      batchIntervalMinutes: 60,
      enabledAlertTypes: [
        "abnormal_rtp",
        "rapid_betting",
        "multi_account",
        "bonus_abuse",
        "velocity",
        "pattern",
      ],
    };
  }),

  /**
   * Update notification preferences
   */
  updatePreferences: protectedProcedure
    .input(
      z.object({
        notifyOnCritical: z.boolean().optional(),
        notifyOnHigh: z.boolean().optional(),
        notifyOnMedium: z.boolean().optional(),
        notifyOnLow: z.boolean().optional(),
        batchNotifications: z.boolean().optional(),
        batchIntervalMinutes: z.number().min(5).max(1440).optional(),
        enabledAlertTypes: z
          .array(
            z.enum([
              "abnormal_rtp",
              "rapid_betting",
              "multi_account",
              "bonus_abuse",
              "unusual_withdrawal",
              "velocity",
              "pattern",
            ])
          )
          .optional(),
      })
    )
    .mutation(async ({ ctx, input }) => {
      // Verify admin role
      if (ctx.user.role !== "admin") {
        throw new TRPCError({ code: "FORBIDDEN", message: "Admin access required" });
      }

      // In a full implementation, store preferences in database
      console.log(`[Fraud Alert Preferences] Updated by admin ${ctx.user.id}:`, input);

      return { success: true, message: "Preferences updated" };
    }),
});
