import { router, protectedProcedure } from "../_core/trpc.ts";
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { getDb } from "../db.ts";
import { eq, desc, sql } from "drizzle-orm";
import { users, transactions, casinoGames, kycDocuments } from "../../drizzle/schema.ts";
import { AlertTemplates, emitCustomAlert } from "../_core/alertEmitter.ts";
import { ActivityTemplates, logAdminActivity } from "../_core/activityLogger.ts";

const adminProcedure = protectedProcedure.use(({ ctx, next }) => {
  if (ctx.user.role !== "admin") throw new TRPCError({ code: "FORBIDDEN", message: "Admin access required" });
  return next({ ctx });
});

export const adminSectionsRouter = router({
  // ============ GAMES & CONTENT ============
  gamesManager: adminProcedure
    .input(z.object({ 
      limit: z.number().default(20), 
      offset: z.number().default(0),
      search: z.string().optional(),
      status: z.enum(['active', 'inactive', 'pending', 'all']).default('all')
    }))
    .query(async ({ input }) => {
      const db = await getDb();
      if (!db) return { games: [], total: 0 };
      
      try {
        const result = await db.select().from(casinoGames).limit(input.limit).offset(input.offset);
        return { 
          games: result || [], 
          total: result?.length || 0,
          limit: input.limit,
          offset: input.offset
        };
      } catch (error) {
        console.error('Error fetching games:', error);
        return { games: [], total: 0 };
      }
    }),

  gameAnalytics: adminProcedure
    .input(z.object({ 
      gameId: z.number().optional(),
      days: z.number().default(30)
    }))
    .query(async ({ input }) => {
      const db = await getDb();
      if (!db) return { analytics: { plays: 0, revenue: 0, avgWin: 0, rtp: 0 } };
      
      try {
        const since = new Date(Date.now() - input.days * 86400000);
        const result = await db.execute(sql`
          SELECT 
            COUNT(*) as plays,
            SUM(CASE WHEN type LIKE '%_win' THEN CAST(amount AS DECIMAL) ELSE 0 END) as revenue,
            AVG(CASE WHEN type LIKE '%_win' THEN CAST(amount AS DECIMAL) ELSE 0 END) as avgWin
          FROM transactions
          WHERE createdAt >= ${since} AND type LIKE '%casino%'
        `);
        
        const data = (result[0] as any[])?.[0] || {};
        return {
          analytics: {
            plays: parseInt(data.plays) || 0,
            revenue: parseFloat(data.revenue) || 0,
            avgWin: parseFloat(data.avgWin) || 0,
            rtp: 96.5 // Placeholder
          }
        };
      } catch (error) {
        console.error('Error fetching game analytics:', error);
        return { analytics: { plays: 0, revenue: 0, avgWin: 0, rtp: 0 } };
      }
    }),

  // ============ FINANCE ============
  makeItRain: adminProcedure
    .input(z.object({
      amount: z.number().min(0),
      targetUsers: z.enum(['all', 'active', 'vip']).default('active'),
      message: z.string().optional()
    }))
    .mutation(async ({ ctx, input }) => {
      const campaignId = `campaign_${Date.now()}`;
      
      // Emit alert for campaign launch
      AlertTemplates.campaignLaunched('Make It Rain', input.targetUsers === 'all' ? 999999 : 10000);
      
      // Log activity
      await ActivityTemplates.campaignLaunched(
        ctx.user.id,
        ctx.user.name || 'Admin',
        campaignId,
        'Make It Rain',
        input.targetUsers === 'all' ? 999999 : 10000
      );
      
      return {
        success: true,
        campaignId,
        totalAmount: input.amount,
        targetUsers: input.targetUsers,
        message: 'Make It Rain campaign created'
      };
    }),

  goldCoinStore: adminProcedure
    .query(async () => {
      // Placeholder for gold coin store management
      return {
        packages: [
          { id: 1, name: '$9.99', coins: 100, price: 9.99 },
          { id: 2, name: '$49.99', coins: 600, price: 49.99 },
          { id: 3, name: '$99.99', coins: 1300, price: 99.99 }
        ]
      };
    }),

  paymentsBanking: adminProcedure
    .input(z.object({
      limit: z.number().default(50),
      offset: z.number().default(0),
      status: z.enum(['pending', 'completed', 'failed', 'all']).default('all')
    }))
    .query(async ({ input }) => {
      const db = await getDb();
      if (!db) return { transactions: [], total: 0 };
      
      try {
        const result = await db.select().from(transactions)
          .limit(input.limit)
          .offset(input.offset)
          .orderBy(desc(transactions.createdAt));
        
        return {
          transactions: result || [],
          total: result?.length || 0
        };
      } catch (error) {
        console.error('Error fetching payments:', error);
        return { transactions: [], total: 0 };
      }
    }),

  processPayment: adminProcedure
    .input(z.object({
      transactionId: z.string(),
      amount: z.number(),
      userId: z.number()
    }))
    .mutation(async ({ ctx, input }) => {
      // Emit alert for payment processing
      AlertTemplates.paymentProcessed(input.amount, 'USD', input.userId);
      
      // Log activity
      await ActivityTemplates.paymentProcessed(
        ctx.user.id,
        ctx.user.name || 'Admin',
        input.transactionId,
        input.userId,
        input.amount,
        'USD'
      );
      
      return {
        success: true,
        message: 'Payment processed',
        transactionId: input.transactionId
      };
    }),

  refundPayment: adminProcedure
    .input(z.object({
      transactionId: z.string(),
      amount: z.number(),
      reason: z.string()
    }))
    .mutation(async ({ ctx, input }) => {
      // Emit alert for payment refund
      AlertTemplates.paymentFailed(input.amount, 'USD', input.reason);
      
      // Log activity
      await ActivityTemplates.paymentRefunded(
        ctx.user.id,
        ctx.user.name || 'Admin',
        input.transactionId,
        0,
        input.amount,
        input.reason
      );
      
      return {
        success: true,
        message: 'Payment refunded',
        transactionId: input.transactionId
      };
    }),

  cashappPayments: adminProcedure
    .input(z.object({
      limit: z.number().default(50),
      offset: z.number().default(0)
    }))
    .query(async () => {
      // Placeholder for CashApp payments management
      return {
        payments: [],
        total: 0,
        message: 'CashApp payments data'
      };
    }),

  // ============ USERS & OPERATIONS ============
  users: adminProcedure
    .input(z.object({
      limit: z.number().default(50),
      offset: z.number().default(0),
      search: z.string().optional(),
      role: z.enum(['all', 'admin', 'user']).default('all')
    }))
    .query(async ({ input }) => {
      const db = await getDb();
      if (!db) return { users: [], total: 0 };
      
      try {
        const result = await db.select().from(users)
          .limit(input.limit)
          .offset(input.offset)
          .orderBy(desc(users.createdAt));
        
        return {
          users: result || [],
          total: result?.length || 0
        };
      } catch (error) {
        console.error('Error fetching users:', error);
        return { users: [], total: 0 };
      }
    }),

  kycReview: adminProcedure
    .input(z.object({
      limit: z.number().default(50),
      offset: z.number().default(0),
      status: z.enum(['pending', 'approved', 'rejected', 'all']).default('pending')
    }))
    .query(async ({ input }) => {
      const db = await getDb();
      if (!db) return { kycDocuments: [], total: 0 };
      
      try {
        const result = await db.select().from(kycDocuments)
          .limit(input.limit)
          .offset(input.offset);
        
        return {
          kycDocuments: result || [],
          total: result?.length || 0
        };
      } catch (error) {
        console.error('Error fetching KYC documents:', error);
        return { kycDocuments: [], total: 0 };
      }
    }),

  approveKyc: adminProcedure
    .input(z.object({ kycId: z.number() }))
    .mutation(async ({ ctx, input }) => {
      // Emit alert for KYC approval
      AlertTemplates.kycApproved('User', ctx.user.id);
      
      // Log activity
      await logAdminActivity(
        ctx.user.id,
        ctx.user.name || 'Admin',
        'kyc_approved',
        'kyc',
        input.kycId,
        `KYC #${input.kycId}`,
        { status: 'approved' }
      );
      
      return {
        success: true,
        message: 'KYC approved',
        kycId: input.kycId
      };
    }),

  rejectKyc: adminProcedure
    .input(z.object({ 
      kycId: z.number(),
      reason: z.string()
    }))
    .mutation(async ({ ctx, input }) => {
      // Emit alert for KYC rejection
      AlertTemplates.kycRejected('User', ctx.user.id, input.reason);
      
      // Log activity
      await logAdminActivity(
        ctx.user.id,
        ctx.user.name || 'Admin',
        'kyc_rejected',
        'kyc',
        input.kycId,
        `KYC #${input.kycId}`,
        { status: 'rejected', reason: input.reason }
      );
      
      return {
        success: true,
        message: 'KYC rejected',
        kycId: input.kycId,
        reason: input.reason
      };
    }),

  bulkActions: adminProcedure
    .input(z.object({
      action: z.enum(['approve', 'reject', 'ban', 'unban']),
      targetIds: z.array(z.number()),
      reason: z.string().optional()
    }))
    .mutation(async ({ ctx, input }) => {
      // Emit alert for bulk action
      emitCustomAlert(
        'info',
        `Bulk ${input.action} executed`,
        `${input.targetIds.length} items processed with action: ${input.action}`,
        'medium',
        { action: input.action, count: input.targetIds.length, reason: input.reason }
      );
      
      // Log activity
      await ActivityTemplates.bulkActionExecuted(
        ctx.user.id,
        ctx.user.name || 'Admin',
        input.action,
        input.targetIds.length,
        { reason: input.reason }
      );
      
      return {
        success: true,
        action: input.action,
        processed: input.targetIds.length,
        message: `Bulk action '${input.action}' completed for ${input.targetIds.length} items`
      };
    }),

  aiEmployees: adminProcedure
    .query(async () => {
      // Placeholder for AI employees management
      return {
        employees: [
          { id: 1, name: 'Lucky AI', role: 'Game Manager', status: 'active' },
          { id: 2, name: 'Fraud AI', role: 'Security', status: 'active' },
          { id: 3, name: 'Game AI', role: 'Analytics', status: 'active' }
        ]
      };
    }),

  // ============ COMMUNICATIONS ============
  banUser: adminProcedure
    .input(z.object({
      userId: z.number(),
      userName: z.string(),
      reason: z.string()
    }))
    .mutation(async ({ ctx, input }) => {
      // Emit alert for user ban
      AlertTemplates.userBanned(input.userName, input.userId, input.reason);
      
      // Log activity
      await ActivityTemplates.userBanned(
        ctx.user.id,
        ctx.user.name || 'Admin',
        input.userId,
        input.userName,
        input.reason
      );
      
      return {
        success: true,
        message: 'User banned',
        userId: input.userId
      };
    }),

  unbanUser: adminProcedure
    .input(z.object({
      userId: z.number(),
      userName: z.string()
    }))
    .mutation(async ({ ctx, input }) => {
      // Emit alert for user unban
      AlertTemplates.userUnbanned(input.userName, input.userId);
      
      // Log activity
      await ActivityTemplates.userUnbanned(
        ctx.user.id,
        ctx.user.name || 'Admin',
        input.userId,
        input.userName
      );
      
      return {
        success: true,
        message: 'User unbanned',
        userId: input.userId
      };
    }),

  reportFraud: adminProcedure
    .input(z.object({
      userId: z.number(),
      userName: z.string(),
      fraudType: z.string(),
      details: z.string()
    }))
    .mutation(async ({ ctx, input }) => {
      // Emit alert for fraud detection
      AlertTemplates.fraudDetected(input.fraudType, input.userId, input.details);
      
      // Log activity
      await ActivityTemplates.fraudDetected(
        ctx.user.id,
        ctx.user.name || 'Admin',
        input.userId,
        input.userName,
        input.fraudType,
        input.details
      );
      
      return {
        success: true,
        message: 'Fraud reported',
        userId: input.userId
      };
    }),

  emailCampaigns: adminProcedure
    .input(z.object({
      limit: z.number().default(20),
      offset: z.number().default(0)
    }))
    .query(async () => {
      // Placeholder for email campaigns
      return {
        campaigns: [],
        total: 0
      };
    }),

  createEmailCampaign: adminProcedure
    .input(z.object({
      subject: z.string(),
      content: z.string(),
      targetAudience: z.enum(['all', 'active', 'vip', 'inactive']),
      scheduleTime: z.date().optional()
    }))
    .mutation(async ({ ctx, input }) => {
      return {
        success: true,
        campaignId: `email_${Date.now()}`,
        message: 'Email campaign created'
      };
    }),

  alertPreferences: adminProcedure
    .query(async ({ ctx }) => {
      // Placeholder for alert preferences
      return {
        preferences: {
          gameApprovals: true,
          fraudAlerts: true,
          paymentIssues: true,
          systemErrors: true,
          channels: ['in-app', 'email']
        }
      };
    }),

  updateAlertPreferences: adminProcedure
    .input(z.object({
      gameApprovals: z.boolean().optional(),
      fraudAlerts: z.boolean().optional(),
      paymentIssues: z.boolean().optional(),
      systemErrors: z.boolean().optional(),
      channels: z.array(z.enum(['in-app', 'email', 'sms', 'slack'])).optional()
    }))
    .mutation(async ({ ctx, input }) => {
      return {
        success: true,
        message: 'Alert preferences updated'
      };
    }),

  // ============ SYSTEM ============
  auditLogs: adminProcedure
    .input(z.object({
      limit: z.number().default(50),
      offset: z.number().default(0),
      action: z.string().optional(),
      adminId: z.number().optional()
    }))
    .query(async () => {
      // Placeholder for audit logs
      return {
        logs: [],
        total: 0
      };
    }),

  systemSettings: adminProcedure
    .query(async () => {
      // Placeholder for system settings
      return {
        settings: {
          maintenanceMode: false,
          maxConcurrentGames: 1000,
          rtpMultiplier: 1.0,
          bonusMultiplier: 1.0
        }
      };
    }),

  updateSystemSettings: adminProcedure
    .input(z.object({
      maintenanceMode: z.boolean().optional(),
      maxConcurrentGames: z.number().optional(),
      rtpMultiplier: z.number().optional(),
      bonusMultiplier: z.number().optional()
    }))
    .mutation(async ({ ctx, input }) => {
      return {
        success: true,
        message: 'System settings updated'
      };
    }),

  // ============ SEARCH & DISCOVERY ============
  searchAdminData: adminProcedure
    .input(z.object({
      query: z.string().min(1),
      categories: z.array(z.enum(['games', 'users', 'transactions', 'kyc', 'campaigns'])).optional(),
      limit: z.number().default(10)
    }))
    .query(async ({ input }) => {
      const db = await getDb();
      if (!db) return { results: [] };
      
      try {
        const searchTerm = `%${input.query}%`;
        const results = [];
        
        // Search games
        if (!input.categories || input.categories.includes('games')) {
          const games = await db.select().from(casinoGames).limit(3);
          results.push(...games.map(g => ({ 
            type: 'game', 
            id: g.id, 
            title: g.name || 'Unknown Game',
            path: '/admin/games-manager'
          })));
        }
        
        // Search users
        if (!input.categories || input.categories.includes('users')) {
          const foundUsers = await db.select().from(users).limit(3);
          results.push(...foundUsers.map(u => ({ 
            type: 'user', 
            id: u.id, 
            title: u.name || u.email || 'Unknown User',
            path: '/admin/users'
          })));
        }
        
        return { results: results.slice(0, input.limit) };
      } catch (error) {
        console.error('Error searching admin data:', error);
        return { results: [] };
      }
    })
});
