import { db } from './db.ts';
import { sql } from 'drizzle-orm';

/**
 * Admin Database Helper Functions
 * These functions provide database operations for all admin features
 */

// ============= AUDIT LOGS =============

export async function logAdminAction(
  adminId: number,
  actionType: string,
  entityType: string,
  entityId: string,
  oldValues?: Record<string, any>,
  newValues?: Record<string, any>,
  reason?: string,
  ipAddress?: string
) {
  try {
    const result = await db.execute(
      sql`INSERT INTO admin_actions (admin_id, action_type, entity_type, entity_id, old_values, new_values, reason, ip_address)
          VALUES (${adminId}, ${actionType}, ${entityType}, ${entityId}, ${JSON.stringify(oldValues)}, ${JSON.stringify(newValues)}, ${reason}, ${ipAddress})`
    );
    return result;
  } catch (error) {
    console.error('[DB] Error logging admin action:', error);
    throw error;
  }
}

export async function getAdminAuditLogs(limit = 100, offset = 0) {
  try {
    const logs = await db.execute(
      sql`SELECT * FROM admin_actions ORDER BY created_at DESC LIMIT ${limit} OFFSET ${offset}`
    );
    return logs;
  } catch (error) {
    console.error('[DB] Error fetching audit logs:', error);
    throw error;
  }
}

// ============= SUPPORT TICKETS =============

export async function createSupportTicket(
  userId: number,
  subject: string,
  message: string,
  category?: string,
  priority = 'medium'
) {
  try {
    const result = await db.execute(
      sql`INSERT INTO support_tickets (user_id, subject, message, category, priority)
          VALUES (${userId}, ${subject}, ${message}, ${category}, ${priority})`
    );
    return result;
  } catch (error) {
    console.error('[DB] Error creating support ticket:', error);
    throw error;
  }
}

export async function getSupportTickets(
  status?: string,
  priority?: string,
  assignedTo?: number,
  limit = 50,
  offset = 0
) {
  try {
    let query = `SELECT * FROM support_tickets WHERE 1=1`;
    const params: any[] = [];

    if (status) {
      query += ` AND status = ?`;
      params.push(status);
    }
    if (priority) {
      query += ` AND priority = ?`;
      params.push(priority);
    }
    if (assignedTo !== undefined) {
      query += ` AND assigned_to = ?`;
      params.push(assignedTo);
    }

    query += ` ORDER BY created_at DESC LIMIT ? OFFSET ?`;
    params.push(limit, offset);

    const tickets = await db.execute(sql.raw(query, params));
    return tickets;
  } catch (error) {
    console.error('[DB] Error fetching support tickets:', error);
    throw error;
  }
}

export async function updateTicketStatus(ticketId: number, status: string, resolvedAt?: Date) {
  try {
    const result = await db.execute(
      sql`UPDATE support_tickets SET status = ${status}, resolved_at = ${resolvedAt}, updated_at = NOW()
          WHERE id = ${ticketId}`
    );
    return result;
  } catch (error) {
    console.error('[DB] Error updating ticket status:', error);
    throw error;
  }
}

export async function assignTicket(ticketId: number, adminId: number) {
  try {
    const result = await db.execute(
      sql`UPDATE support_tickets SET assigned_to = ${adminId}, updated_at = NOW()
          WHERE id = ${ticketId}`
    );
    return result;
  } catch (error) {
    console.error('[DB] Error assigning ticket:', error);
    throw error;
  }
}

export async function addTicketReply(ticketId: number, userId: number, message: string, isAdmin = false) {
  try {
    const result = await db.execute(
      sql`INSERT INTO support_ticket_replies (ticket_id, user_id, message, is_admin)
          VALUES (${ticketId}, ${userId}, ${message}, ${isAdmin})`
    );
    return result;
  } catch (error) {
    console.error('[DB] Error adding ticket reply:', error);
    throw error;
  }
}

export async function getTicketReplies(ticketId: number) {
  try {
    const replies = await db.execute(
      sql`SELECT * FROM support_ticket_replies WHERE ticket_id = ${ticketId} ORDER BY created_at ASC`
    );
    return replies;
  } catch (error) {
    console.error('[DB] Error fetching ticket replies:', error);
    throw error;
  }
}

// ============= FRAUD ALERTS =============

export async function createFraudAlert(
  userId: number,
  alertType: string,
  riskScore: number,
  details?: Record<string, any>
) {
  try {
    const result = await db.execute(
      sql`INSERT INTO fraud_alerts (user_id, alert_type, risk_score, details)
          VALUES (${userId}, ${alertType}, ${riskScore}, ${JSON.stringify(details)})`
    );
    return result;
  } catch (error) {
    console.error('[DB] Error creating fraud alert:', error);
    throw error;
  }
}

export async function getFraudAlerts(
  status?: string,
  minRiskScore = 0,
  limit = 50,
  offset = 0
) {
  try {
    let query = `SELECT * FROM fraud_alerts WHERE risk_score >= ?`;
    const params: any[] = [minRiskScore];

    if (status) {
      query += ` AND status = ?`;
      params.push(status);
    }

    query += ` ORDER BY risk_score DESC, created_at DESC LIMIT ? OFFSET ?`;
    params.push(limit, offset);

    const alerts = await db.execute(sql.raw(query, params));
    return alerts;
  } catch (error) {
    console.error('[DB] Error fetching fraud alerts:', error);
    throw error;
  }
}

export async function updateFraudAlertStatus(alertId: number, status: string, notes?: string) {
  try {
    const result = await db.execute(
      sql`UPDATE fraud_alerts SET status = ${status}, notes = ${notes}, updated_at = NOW()
          WHERE id = ${alertId}`
    );
    return result;
  } catch (error) {
    console.error('[DB] Error updating fraud alert:', error);
    throw error;
  }
}

// ============= GAME METRICS =============

export async function recordGameMetrics(
  gameId: number,
  date: Date,
  plays: number,
  wins: number,
  losses: number,
  totalWagered: number,
  totalWon: number,
  avgSessionDuration: number,
  playerCount: number,
  rtpActual?: number
) {
  try {
    const result = await db.execute(
      sql`INSERT INTO game_metrics (game_id, date, plays, wins, losses, total_wagered, total_won, avg_session_duration, player_count, rtp_actual)
          VALUES (${gameId}, ${date}, ${plays}, ${wins}, ${losses}, ${totalWagered}, ${totalWon}, ${avgSessionDuration}, ${playerCount}, ${rtpActual})
          ON DUPLICATE KEY UPDATE
          plays = ${plays}, wins = ${wins}, losses = ${losses}, total_wagered = ${totalWagered}, total_won = ${totalWon}, avg_session_duration = ${avgSessionDuration}, player_count = ${playerCount}, rtp_actual = ${rtpActual}`
    );
    return result;
  } catch (error) {
    console.error('[DB] Error recording game metrics:', error);
    throw error;
  }
}

export async function getGameMetrics(gameId: number, startDate: Date, endDate: Date) {
  try {
    const metrics = await db.execute(
      sql`SELECT * FROM game_metrics WHERE game_id = ${gameId} AND date BETWEEN ${startDate} AND ${endDate} ORDER BY date DESC`
    );
    return metrics;
  } catch (error) {
    console.error('[DB] Error fetching game metrics:', error);
    throw error;
  }
}

// ============= PLAYER SEGMENTS =============

export async function createPlayerSegment(
  name: string,
  description: string,
  criteria: Record<string, any>,
  createdBy: number
) {
  try {
    const result = await db.execute(
      sql`INSERT INTO player_segments (name, description, criteria, created_by)
          VALUES (${name}, ${description}, ${JSON.stringify(criteria)}, ${createdBy})`
    );
    return result;
  } catch (error) {
    console.error('[DB] Error creating player segment:', error);
    throw error;
  }
}

export async function getPlayerSegments(limit = 50, offset = 0) {
  try {
    const segments = await db.execute(
      sql`SELECT * FROM player_segments ORDER BY created_at DESC LIMIT ${limit} OFFSET ${offset}`
    );
    return segments;
  } catch (error) {
    console.error('[DB] Error fetching player segments:', error);
    throw error;
  }
}

export async function addPlayerToSegment(segmentId: number, userId: number) {
  try {
    const result = await db.execute(
      sql`INSERT INTO player_segment_members (segment_id, user_id) VALUES (${segmentId}, ${userId})
          ON DUPLICATE KEY UPDATE added_at = NOW()`
    );
    return result;
  } catch (error) {
    console.error('[DB] Error adding player to segment:', error);
    throw error;
  }
}

export async function getSegmentMembers(segmentId: number, limit = 100, offset = 0) {
  try {
    const members = await db.execute(
      sql`SELECT u.* FROM player_segment_members psm
          JOIN users u ON psm.user_id = u.id
          WHERE psm.segment_id = ${segmentId}
          ORDER BY psm.added_at DESC LIMIT ${limit} OFFSET ${offset}`
    );
    return members;
  } catch (error) {
    console.error('[DB] Error fetching segment members:', error);
    throw error;
  }
}

// ============= STATISTICS =============

export async function getAdminDashboardStats() {
  try {
    const stats = await db.execute(sql`
      SELECT
        (SELECT COUNT(*) FROM support_tickets WHERE status = 'open') as open_tickets,
        (SELECT COUNT(*) FROM fraud_alerts WHERE status = 'pending') as pending_fraud_alerts,
        (SELECT COUNT(*) FROM admin_actions WHERE DATE(created_at) = CURDATE()) as admin_actions_today,
        (SELECT COUNT(*) FROM users WHERE DATE(created_at) = CURDATE()) as new_players_today,
        (SELECT SUM(total_wagered) FROM game_metrics WHERE DATE(date) = CURDATE()) as total_wagered_today,
        (SELECT SUM(total_won) FROM game_metrics WHERE DATE(date) = CURDATE()) as total_won_today
    `);
    return stats[0];
  } catch (error) {
    console.error('[DB] Error fetching dashboard stats:', error);
    throw error;
  }
}
