/**
 * Advanced Player Segmentation Service
 * AI-powered behavior analysis for hyper-targeted campaigns
 */

import { db } from './db.ts';
import { users, wallets } from '../drizzle/schema.ts';
import { eq } from 'drizzle-orm';

/**
 * Player behavior metrics
 */
export interface PlayerBehaviorMetrics {
  playerId: number;
  username: string;
  totalDeposits: number;
  totalWagered: number;
  totalWinnings: number;
  netProfit: number;
  sessionCount: number;
  averageSessionDuration: number; // minutes
  averageSessionValue: number; // USD
  favoriteGameIds: string[];
  lastLoginDate: Date;
  daysSinceLastLogin: number;
  daysSinceFirstDeposit: number;
  bonusUtilizationRate: number; // 0-100
  referralCount: number;
  socialShareCount: number;
  supportTicketCount: number;
  accountAge: number; // days
}

/**
 * Player segment definition
 */
export interface PlayerSegment {
  id: string;
  name: string;
  description: string;
  criteria: SegmentCriteria;
  playerCount: number;
  averageLTV: number;
  churnRate: number;
  engagementScore: number; // 0-100
  recommendedActions: string[];
  campaignTemplates: string[];
}

/**
 * Segment criteria
 */
export interface SegmentCriteria {
  minLTV?: number;
  maxLTV?: number;
  minSessionCount?: number;
  maxSessionCount?: number;
  minDaysSinceLogin?: number;
  maxDaysSinceLogin?: number;
  minAccountAge?: number;
  maxAccountAge?: number;
  favoriteGameCategories?: string[];
  bonusUtilizationRange?: [number, number];
  spendingPattern?: 'high' | 'medium' | 'low' | 'dormant';
  engagementLevel?: 'high' | 'medium' | 'low';
  riskProfile?: 'high' | 'medium' | 'low';
}

/**
 * Segment assignment
 */
export interface SegmentAssignment {
  playerId: number;
  segmentId: string;
  segmentName: string;
  confidence: number; // 0-100
  assignedAt: Date;
  nextReviewDate: Date;
  signals: string[]; // Signals that led to this assignment
}

/**
 * Cohort analysis
 */
export interface CohortAnalysis {
  cohortId: string;
  cohortName: string;
  acquisitionDate: Date;
  playerCount: number;
  retention: {
    day1: number;
    day7: number;
    day30: number;
    day90: number;
  };
  revenue: {
    day1: number;
    day7: number;
    day30: number;
    day90: number;
  };
  averageLTV: number;
  churnRate: number;
}

/**
 * Predictive insights
 */
export interface PredictiveInsights {
  playerId: number;
  predictedLTV: number;
  churnRisk: number; // 0-100
  spendingTrend: 'increasing' | 'stable' | 'decreasing';
  engagementTrend: 'increasing' | 'stable' | 'decreasing';
  nextLikelyAction: string;
  recommendedOffer: string;
  offerUrgency: 'high' | 'medium' | 'low';
  confidence: number; // 0-100
}

/**
 * Predefined segments
 */
export const PREDEFINED_SEGMENTS: PlayerSegment[] = [
  {
    id: 'vip_high_value',
    name: 'VIP High-Value Players',
    description: 'Top spenders with high engagement and lifetime value',
    criteria: {
      minLTV: 5000,
      minSessionCount: 50,
      maxDaysSinceLogin: 7,
      engagementLevel: 'high',
    },
    playerCount: 0,
    averageLTV: 12500,
    churnRate: 5,
    engagementScore: 95,
    recommendedActions: [
      'Personalized VIP concierge support',
      'Exclusive high-stakes tournaments',
      'Premium rewards and perks',
      'Early access to new games',
    ],
    campaignTemplates: [
      'vip_exclusive_offers',
      'high_value_retention',
      'tournament_invitations',
    ],
  },
  {
    id: 'growth_potential',
    name: 'Growth Potential Players',
    description: 'Medium spenders with increasing engagement and high growth potential',
    criteria: {
      minLTV: 1000,
      maxLTV: 5000,
      minSessionCount: 20,
      engagementLevel: 'high',
      spendingPattern: 'medium',
    },
    playerCount: 0,
    averageLTV: 2500,
    churnRate: 15,
    engagementScore: 75,
    recommendedActions: [
      'Tier upgrade incentives',
      'Bonus multiplier campaigns',
      'Social sharing rewards',
      'Referral program promotion',
    ],
    campaignTemplates: [
      'growth_acceleration',
      'tier_upgrade_offers',
      'bonus_multiplier_events',
    ],
  },
  {
    id: 'casual_players',
    name: 'Casual Players',
    description: 'Low-frequency players with low to medium spending',
    criteria: {
      maxLTV: 1000,
      minSessionCount: 5,
      maxSessionCount: 20,
      engagementLevel: 'low',
    },
    playerCount: 0,
    averageLTV: 300,
    churnRate: 40,
    engagementScore: 40,
    recommendedActions: [
      'Re-engagement campaigns',
      'Free spin offers',
      'Game recommendations',
      'Social features promotion',
    ],
    campaignTemplates: [
      'casual_reengagement',
      'free_spin_offers',
      'game_recommendations',
    ],
  },
  {
    id: 'at_risk_churners',
    name: 'At-Risk Churners',
    description: 'Previously active players showing signs of churn',
    criteria: {
      minDaysSinceLogin: 14,
      maxDaysSinceLogin: 60,
      spendingPattern: 'low',
      engagementLevel: 'low',
    },
    playerCount: 0,
    averageLTV: 500,
    churnRate: 75,
    engagementScore: 20,
    recommendedActions: [
      'Urgent retention offers',
      'Personalized win-back campaigns',
      'Customer support outreach',
      'Special comeback bonuses',
    ],
    campaignTemplates: [
      'urgent_retention',
      'winback_campaign',
      'comeback_bonus',
    ],
  },
  {
    id: 'dormant_accounts',
    name: 'Dormant Accounts',
    description: 'Inactive players with no recent activity',
    criteria: {
      minDaysSinceLogin: 60,
      spendingPattern: 'dormant',
    },
    playerCount: 0,
    averageLTV: 200,
    churnRate: 95,
    engagementScore: 5,
    recommendedActions: [
      'Aggressive reactivation campaigns',
      'Account reset offers',
      'New game announcements',
      'Significant bonus incentives',
    ],
    campaignTemplates: [
      'dormant_reactivation',
      'account_reset',
      'new_game_announcement',
    ],
  },
  {
    id: 'bonus_hunters',
    name: 'Bonus Hunters',
    description: 'Players primarily motivated by bonuses and promotions',
    criteria: {
      bonusUtilizationRange: [80, 100],
      minSessionCount: 30,
      spendingPattern: 'low',
    },
    playerCount: 0,
    averageLTV: 400,
    churnRate: 50,
    engagementScore: 50,
    recommendedActions: [
      'Bonus-focused campaigns',
      'Promotion calendar sharing',
      'Early bonus notifications',
      'Exclusive bonus tiers',
    ],
    campaignTemplates: [
      'bonus_focused_campaigns',
      'early_bonus_notifications',
      'exclusive_bonus_tiers',
    ],
  },
  {
    id: 'social_sharers',
    name: 'Social Sharers',
    description: 'Highly social players who frequently share and refer',
    criteria: {
      minSessionCount: 20,
      referralCount: 3,
      socialShareCount: 10,
    },
    playerCount: 0,
    averageLTV: 1500,
    churnRate: 25,
    engagementScore: 70,
    recommendedActions: [
      'Referral program expansion',
      'Social sharing incentives',
      'Community ambassador program',
      'Viral campaign participation',
    ],
    campaignTemplates: [
      'referral_expansion',
      'social_sharing_incentives',
      'ambassador_program',
    ],
  },
  {
    id: 'game_specialists',
    name: 'Game Specialists',
    description: 'Players with strong preference for specific game types',
    criteria: {
      minSessionCount: 25,
      favoriteGameCategories: ['slots', 'table_games', 'arcade'],
    },
    playerCount: 0,
    averageLTV: 2000,
    churnRate: 20,
    engagementScore: 65,
    recommendedActions: [
      'Game-specific recommendations',
      'Specialist tournaments',
      'Game-themed bonuses',
      'Early access to similar games',
    ],
    campaignTemplates: [
      'game_specialist_recommendations',
      'specialist_tournaments',
      'game_themed_bonuses',
    ],
  },
];

/**
 * Analyze player behavior and generate metrics
 */
export async function analyzePlayerBehavior(
  playerId: number,
  username: string,
  deposits: number,
  wagered: number,
  winnings: number,
  sessions: number,
  avgSessionDuration: number,
  lastLogin: Date,
  firstDeposit: Date,
  bonusUtilization: number,
  referrals: number,
  shares: number,
  tickets: number
): Promise<PlayerBehaviorMetrics> {
  const now = new Date();
  const daysSinceLastLogin = Math.floor((now.getTime() - lastLogin.getTime()) / (1000 * 60 * 60 * 24));
  const daysSinceFirstDeposit = Math.floor((now.getTime() - firstDeposit.getTime()) / (1000 * 60 * 60 * 24));

  return {
    playerId,
    username,
    totalDeposits: deposits,
    totalWagered: wagered,
    totalWinnings: winnings,
    netProfit: winnings - wagered,
    sessionCount: sessions,
    averageSessionDuration: avgSessionDuration,
    averageSessionValue: sessions > 0 ? wagered / sessions : 0,
    favoriteGameIds: [],
    lastLoginDate: lastLogin,
    daysSinceLastLogin,
    daysSinceFirstDeposit,
    bonusUtilizationRate: bonusUtilization,
    referralCount: referrals,
    socialShareCount: shares,
    supportTicketCount: tickets,
    accountAge: daysSinceFirstDeposit,
  };
}

/**
 * Assign player to segments based on behavior
 */
export function assignPlayerToSegments(
  metrics: PlayerBehaviorMetrics
): SegmentAssignment[] {
  const assignments: SegmentAssignment[] = [];
  const now = new Date();

  for (const segment of PREDEFINED_SEGMENTS) {
    const match = evaluateSegmentCriteria(metrics, segment.criteria);
    if (match.isMatch) {
      assignments.push({
        playerId: metrics.playerId,
        segmentId: segment.id,
        segmentName: segment.name,
        confidence: match.confidence,
        assignedAt: now,
        nextReviewDate: new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000), // 7 days
        signals: match.signals,
      });
    }
  }

  return assignments;
}

/**
 * Evaluate if player matches segment criteria
 */
function evaluateSegmentCriteria(
  metrics: PlayerBehaviorMetrics,
  criteria: SegmentCriteria
): { isMatch: boolean; confidence: number; signals: string[] } {
  const signals: string[] = [];
  let matchCount = 0;
  let totalCriteria = 0;

  // Calculate LTV
  const ltv = metrics.totalDeposits * 5; // Simplified LTV calculation

  // Check LTV range
  if (criteria.minLTV !== undefined || criteria.maxLTV !== undefined) {
    totalCriteria++;
    if (
      (criteria.minLTV === undefined || ltv >= criteria.minLTV) &&
      (criteria.maxLTV === undefined || ltv <= criteria.maxLTV)
    ) {
      matchCount++;
      signals.push(`LTV ${ltv} within range`);
    }
  }

  // Check session count
  if (criteria.minSessionCount !== undefined || criteria.maxSessionCount !== undefined) {
    totalCriteria++;
    if (
      (criteria.minSessionCount === undefined || metrics.sessionCount >= criteria.minSessionCount) &&
      (criteria.maxSessionCount === undefined || metrics.sessionCount <= criteria.maxSessionCount)
    ) {
      matchCount++;
      signals.push(`Session count ${metrics.sessionCount} matches`);
    }
  }

  // Check days since login
  if (criteria.minDaysSinceLogin !== undefined || criteria.maxDaysSinceLogin !== undefined) {
    totalCriteria++;
    if (
      (criteria.minDaysSinceLogin === undefined ||
        metrics.daysSinceLastLogin >= criteria.minDaysSinceLogin) &&
      (criteria.maxDaysSinceLogin === undefined ||
        metrics.daysSinceLastLogin <= criteria.maxDaysSinceLogin)
    ) {
      matchCount++;
      signals.push(`Days since login ${metrics.daysSinceLastLogin} matches`);
    }
  }

  // Check account age
  if (criteria.minAccountAge !== undefined || criteria.maxAccountAge !== undefined) {
    totalCriteria++;
    if (
      (criteria.minAccountAge === undefined || metrics.accountAge >= criteria.minAccountAge) &&
      (criteria.maxAccountAge === undefined || metrics.accountAge <= criteria.maxAccountAge)
    ) {
      matchCount++;
      signals.push(`Account age ${metrics.accountAge} days matches`);
    }
  }

  // Check bonus utilization
  if (criteria.bonusUtilizationRange) {
    totalCriteria++;
    if (
      metrics.bonusUtilizationRate >= criteria.bonusUtilizationRange[0] &&
      metrics.bonusUtilizationRate <= criteria.bonusUtilizationRange[1]
    ) {
      matchCount++;
      signals.push(`Bonus utilization ${metrics.bonusUtilizationRate}% matches`);
    }
  }

  // Check spending pattern
  if (criteria.spendingPattern) {
    totalCriteria++;
    const spendingPattern = getSpendingPattern(metrics);
    if (spendingPattern === criteria.spendingPattern) {
      matchCount++;
      signals.push(`Spending pattern ${spendingPattern} matches`);
    }
  }

  // Check engagement level
  if (criteria.engagementLevel) {
    totalCriteria++;
    const engagement = getEngagementLevel(metrics);
    if (engagement === criteria.engagementLevel) {
      matchCount++;
      signals.push(`Engagement level ${engagement} matches`);
    }
  }

  const confidence = totalCriteria > 0 ? (matchCount / totalCriteria) * 100 : 0;
  const isMatch = confidence >= 60; // 60% match threshold

  return { isMatch, confidence, signals };
}

/**
 * Determine spending pattern
 */
function getSpendingPattern(
  metrics: PlayerBehaviorMetrics
): 'high' | 'medium' | 'low' | 'dormant' {
  if (metrics.daysSinceLastLogin > 60) return 'dormant';
  if (metrics.totalDeposits > 5000) return 'high';
  if (metrics.totalDeposits > 1000) return 'medium';
  return 'low';
}

/**
 * Determine engagement level
 */
function getEngagementLevel(metrics: PlayerBehaviorMetrics): 'high' | 'medium' | 'low' {
  const engagementScore =
    (metrics.sessionCount * 2 + metrics.referralCount * 10 + metrics.socialShareCount * 5) / 10;

  if (engagementScore > 50) return 'high';
  if (engagementScore > 20) return 'medium';
  return 'low';
}

/**
 * Generate predictive insights for player
 */
export function generatePredictiveInsights(
  metrics: PlayerBehaviorMetrics,
  assignments: SegmentAssignment[]
): PredictiveInsights {
  // Calculate predicted LTV
  const predictedLTV = Math.floor(metrics.totalDeposits * 5 * (1 + metrics.sessionCount / 100));

  // Calculate churn risk
  let churnRisk = 0;
  if (metrics.daysSinceLastLogin > 30) churnRisk += 40;
  else if (metrics.daysSinceLastLogin > 14) churnRisk += 25;
  else if (metrics.daysSinceLastLogin > 7) churnRisk += 15;

  if (metrics.sessionCount < 5) churnRisk += 30;
  if (metrics.totalDeposits < 100) churnRisk += 20;

  // Determine spending trend
  const spendingTrend: 'increasing' | 'stable' | 'decreasing' =
    metrics.averageSessionValue > metrics.totalDeposits / metrics.sessionCount * 1.1
      ? 'increasing'
      : metrics.averageSessionValue < metrics.totalDeposits / metrics.sessionCount * 0.9
        ? 'decreasing'
        : 'stable';

  // Determine engagement trend
  const engagementTrend: 'increasing' | 'stable' | 'decreasing' =
    metrics.daysSinceLastLogin < 3
      ? 'increasing'
      : metrics.daysSinceLastLogin > 14
        ? 'decreasing'
        : 'stable';

  // Recommend next action
  let nextLikelyAction = 'Continue playing';
  if (churnRisk > 70) nextLikelyAction = 'Likely to churn - needs intervention';
  else if (spendingTrend === 'increasing') nextLikelyAction = 'Increase spending - capitalize on momentum';
  else if (metrics.sessionCount < 10) nextLikelyAction = 'Low engagement - needs re-engagement';

  // Recommend offer
  let recommendedOffer = 'Standard bonus';
  if (churnRisk > 70) recommendedOffer = 'VIP retention offer';
  else if (metrics.totalDeposits > 5000) recommendedOffer = 'Exclusive high-value tournament';
  else if (metrics.sessionCount < 10) recommendedOffer = 'Free spins offer';

  // Offer urgency
  const offerUrgency: 'high' | 'medium' | 'low' =
    churnRisk > 70 ? 'high' : churnRisk > 40 ? 'medium' : 'low';

  // Confidence
  const confidence = Math.min(100, 60 + metrics.sessionCount * 2);

  return {
    playerId: metrics.playerId,
    predictedLTV,
    churnRisk: Math.min(100, churnRisk),
    spendingTrend,
    engagementTrend,
    nextLikelyAction,
    recommendedOffer,
    offerUrgency,
    confidence,
  };
}

/**
 * Create cohort analysis
 */
export function createCohortAnalysis(
  cohortName: string,
  acquisitionDate: Date,
  playerMetrics: PlayerBehaviorMetrics[]
): CohortAnalysis {
  const now = new Date();
  const daysSinceAcquisition = Math.floor(
    (now.getTime() - acquisitionDate.getTime()) / (1000 * 60 * 60 * 24)
  );

  // Calculate retention rates
  const retention = {
    day1: playerMetrics.filter((m) => m.daysSinceFirstDeposit <= 1).length,
    day7: playerMetrics.filter((m) => m.daysSinceFirstDeposit <= 7).length,
    day30: playerMetrics.filter((m) => m.daysSinceFirstDeposit <= 30).length,
    day90: playerMetrics.filter((m) => m.daysSinceFirstDeposit <= 90).length,
  };

  // Calculate revenue
  const revenue = {
    day1: playerMetrics
      .filter((m) => m.daysSinceFirstDeposit <= 1)
      .reduce((sum, m) => sum + m.totalDeposits, 0),
    day7: playerMetrics
      .filter((m) => m.daysSinceFirstDeposit <= 7)
      .reduce((sum, m) => sum + m.totalDeposits, 0),
    day30: playerMetrics
      .filter((m) => m.daysSinceFirstDeposit <= 30)
      .reduce((sum, m) => sum + m.totalDeposits, 0),
    day90: playerMetrics
      .filter((m) => m.daysSinceFirstDeposit <= 90)
      .reduce((sum, m) => sum + m.totalDeposits, 0),
  };

  const averageLTV = playerMetrics.reduce((sum, m) => sum + m.totalDeposits * 5, 0) / playerMetrics.length;
  const churnRate = playerMetrics.filter((m) => m.daysSinceLastLogin > 30).length / playerMetrics.length * 100;

  return {
    cohortId: `cohort_${acquisitionDate.toISOString().split('T')[0]}`,
    cohortName,
    acquisitionDate,
    playerCount: playerMetrics.length,
    retention,
    revenue,
    averageLTV,
    churnRate,
  };
}

/**
 * Get segment recommendations
 */
export function getSegmentRecommendations(segment: PlayerSegment): {
  campaignType: string;
  messaging: string;
  offerType: string;
  urgency: 'high' | 'medium' | 'low';
}[] {
  const recommendations = [];

  if (segment.id === 'vip_high_value') {
    recommendations.push({
      campaignType: 'VIP Exclusive',
      messaging: 'Premium rewards and early access',
      offerType: 'Tournament invitation',
      urgency: 'medium',
    });
  } else if (segment.id === 'growth_potential') {
    recommendations.push({
      campaignType: 'Growth Acceleration',
      messaging: 'Reach VIP status faster',
      offerType: 'Tier upgrade bonus',
      urgency: 'medium',
    });
  } else if (segment.id === 'casual_players') {
    recommendations.push({
      campaignType: 'Engagement',
      messaging: 'Discover new games',
      offerType: 'Free spins',
      urgency: 'low',
    });
  } else if (segment.id === 'at_risk_churners') {
    recommendations.push({
      campaignType: 'Retention',
      messaging: 'We miss you - special offer',
      offerType: 'Comeback bonus',
      urgency: 'high',
    });
  } else if (segment.id === 'dormant_accounts') {
    recommendations.push({
      campaignType: 'Reactivation',
      messaging: 'Come back for new games',
      offerType: 'Account reset bonus',
      urgency: 'high',
    });
  }

  return recommendations;
}
