/**
 * Player Support Dashboard
 * Customer service interface for handling disputes, refunds, and player inquiries
 */

export type TicketStatus = 'open' | 'in_progress' | 'waiting_player' | 'resolved' | 'closed';
export type TicketPriority = 'low' | 'medium' | 'high' | 'critical';
export type TicketCategory = 'payment' | 'technical' | 'account' | 'bonus' | 'complaint' | 'kyc' | 'other';
export type DisputeStatus = 'open' | 'under_review' | 'player_responded' | 'resolved' | 'escalated';
export type RefundStatus = 'pending' | 'approved' | 'rejected' | 'processed' | 'failed';

export interface SupportTicket {
  id: string;
  playerId: number;
  playerEmail: string;
  playerName: string;
  category: TicketCategory;
  subject: string;
  description: string;
  status: TicketStatus;
  priority: TicketPriority;
  assignedTo?: number; // Support agent ID
  messages: TicketMessage[];
  attachments: string[]; // File URLs
  createdAt: Date;
  updatedAt: Date;
  resolvedAt?: Date;
  resolutionNotes?: string;
  satisfactionRating?: number; // 1-5
  tags: string[];
}

export interface TicketMessage {
  id: string;
  ticketId: string;
  senderId: number; // Player ID or Support agent ID
  senderName: string;
  senderRole: 'player' | 'support' | 'admin';
  message: string;
  attachments?: string[];
  createdAt: Date;
  isInternal: boolean; // Only visible to support team
}

export interface Dispute {
  id: string;
  playerId: number;
  ticketId: string;
  reason: string;
  amount: number;
  status: DisputeStatus;
  description: string;
  evidence: string[]; // File URLs
  playerResponse?: string;
  adminNotes?: string;
  decision?: 'upheld' | 'overturned' | 'partial';
  decisionReason?: string;
  createdAt: Date;
  updatedAt: Date;
  resolvedAt?: Date;
  escalatedTo?: number; // Manager ID
}

export interface RefundRequest {
  id: string;
  playerId: number;
  ticketId?: string;
  amount: number;
  reason: string;
  status: RefundStatus;
  originalTransactionId: string;
  refundMethod: 'original_payment' | 'account_credit' | 'bank_transfer';
  approvedBy?: number;
  processedAt?: Date;
  failureReason?: string;
  createdAt: Date;
  updatedAt: Date;
}

export interface SupportAgent {
  id: number;
  name: string;
  email: string;
  role: 'support_agent' | 'support_lead' | 'manager';
  status: 'active' | 'inactive' | 'on_break';
  assignedTickets: number;
  resolvedTickets: number;
  averageResolutionTime: number; // minutes
  satisfactionRating: number; // 0-5
  languages: string[];
  specializations: TicketCategory[];
  createdAt: Date;
  lastActiveAt: Date;
}

export interface SupportMetrics {
  totalTickets: number;
  openTickets: number;
  averageResolutionTime: number; // hours
  firstResponseTime: number; // minutes
  satisfactionScore: number; // 0-100
  resolvedToday: number;
  escalatedTickets: number;
  refundsProcessed: number;
  totalRefundAmount: number;
  disputesOpen: number;
}

/**
 * Create support ticket
 */
export function createSupportTicket(
  playerId: number,
  playerEmail: string,
  playerName: string,
  category: TicketCategory,
  subject: string,
  description: string,
  priority: TicketPriority = 'medium'
): SupportTicket {
  return {
    id: `ticket_${playerId}_${Date.now()}`,
    playerId,
    playerEmail,
    playerName,
    category,
    subject,
    description,
    status: 'open',
    priority,
    messages: [],
    attachments: [],
    createdAt: new Date(),
    updatedAt: new Date(),
    tags: [],
  };
}

/**
 * Add message to ticket
 */
export function addTicketMessage(
  ticket: SupportTicket,
  senderId: number,
  senderName: string,
  senderRole: 'player' | 'support' | 'admin',
  message: string,
  isInternal: boolean = false,
  attachments?: string[]
): TicketMessage {
  const ticketMessage: TicketMessage = {
    id: `msg_${ticket.id}_${Date.now()}`,
    ticketId: ticket.id,
    senderId,
    senderName,
    senderRole,
    message,
    attachments,
    createdAt: new Date(),
    isInternal,
  };

  ticket.messages.push(ticketMessage);
  ticket.updatedAt = new Date();

  return ticketMessage;
}

/**
 * Assign ticket to support agent
 */
export function assignTicketToAgent(ticket: SupportTicket, agentId: number): void {
  ticket.assignedTo = agentId;
  ticket.status = 'in_progress';
  ticket.updatedAt = new Date();
}

/**
 * Update ticket status
 */
export function updateTicketStatus(
  ticket: SupportTicket,
  status: TicketStatus,
  resolutionNotes?: string
): void {
  ticket.status = status;

  if (status === 'resolved' || status === 'closed') {
    ticket.resolvedAt = new Date();
    ticket.resolutionNotes = resolutionNotes;
  }

  ticket.updatedAt = new Date();
}

/**
 * Create dispute
 */
export function createDispute(
  playerId: number,
  ticketId: string,
  reason: string,
  amount: number,
  description: string,
  evidence: string[]
): Dispute {
  return {
    id: `dispute_${playerId}_${Date.now()}`,
    playerId,
    ticketId,
    reason,
    amount,
    status: 'open',
    description,
    evidence,
    createdAt: new Date(),
    updatedAt: new Date(),
  };
}

/**
 * Respond to dispute
 */
export function respondToDispute(
  dispute: Dispute,
  playerResponse: string,
  evidence?: string[]
): void {
  dispute.playerResponse = playerResponse;
  if (evidence) {
    dispute.evidence.push(...evidence);
  }
  dispute.status = 'player_responded';
  dispute.updatedAt = new Date();
}

/**
 * Resolve dispute
 */
export function resolveDispute(
  dispute: Dispute,
  decision: 'upheld' | 'overturned' | 'partial',
  reason: string,
  approvedBy: number
): void {
  dispute.decision = decision;
  dispute.decisionReason = reason;
  dispute.status = 'resolved';
  dispute.resolvedAt = new Date();
  dispute.updatedAt = new Date();
}

/**
 * Escalate dispute
 */
export function escalateDispute(dispute: Dispute, managerId: number, notes?: string): void {
  dispute.escalatedTo = managerId;
  dispute.status = 'escalated';
  dispute.adminNotes = notes;
  dispute.updatedAt = new Date();
}

/**
 * Create refund request
 */
export function createRefundRequest(
  playerId: number,
  amount: number,
  reason: string,
  originalTransactionId: string,
  refundMethod: 'original_payment' | 'account_credit' | 'bank_transfer',
  ticketId?: string
): RefundRequest {
  return {
    id: `refund_${playerId}_${Date.now()}`,
    playerId,
    ticketId,
    amount,
    reason,
    status: 'pending',
    originalTransactionId,
    refundMethod,
    createdAt: new Date(),
    updatedAt: new Date(),
  };
}

/**
 * Approve refund
 */
export function approveRefund(refund: RefundRequest, approvedBy: number): void {
  refund.status = 'approved';
  refund.approvedBy = approvedBy;
  refund.updatedAt = new Date();
}

/**
 * Reject refund
 */
export function rejectRefund(refund: RefundRequest, reason: string): void {
  refund.status = 'rejected';
  refund.failureReason = reason;
  refund.updatedAt = new Date();
}

/**
 * Process refund
 */
export function processRefund(refund: RefundRequest): void {
  refund.status = 'processed';
  refund.processedAt = new Date();
  refund.updatedAt = new Date();
}

/**
 * Mark refund as failed
 */
export function markRefundFailed(refund: RefundRequest, reason: string): void {
  refund.status = 'failed';
  refund.failureReason = reason;
  refund.updatedAt = new Date();
}

/**
 * Create support agent
 */
export function createSupportAgent(
  id: number,
  name: string,
  email: string,
  role: 'support_agent' | 'support_lead' | 'manager',
  languages: string[] = ['en'],
  specializations: TicketCategory[] = []
): SupportAgent {
  return {
    id,
    name,
    email,
    role,
    status: 'active',
    assignedTickets: 0,
    resolvedTickets: 0,
    averageResolutionTime: 0,
    satisfactionRating: 5,
    languages,
    specializations,
    createdAt: new Date(),
    lastActiveAt: new Date(),
  };
}

/**
 * Update agent status
 */
export function updateAgentStatus(
  agent: SupportAgent,
  status: 'active' | 'inactive' | 'on_break'
): void {
  agent.status = status;
  agent.lastActiveAt = new Date();
}

/**
 * Calculate support metrics
 */
export function calculateSupportMetrics(
  tickets: SupportTicket[],
  refunds: RefundRequest[],
  disputes: Dispute[]
): SupportMetrics {
  const openTickets = tickets.filter((t) => t.status === 'open').length;
  const resolvedTickets = tickets.filter((t) => t.status === 'resolved' || t.status === 'closed');
  const resolvedToday = tickets.filter(
    (t) =>
      (t.status === 'resolved' || t.status === 'closed') &&
      t.resolvedAt &&
      new Date(t.resolvedAt).toDateString() === new Date().toDateString()
  ).length;

  const resolutionTimes = resolvedTickets
    .filter((t) => t.resolvedAt && t.createdAt)
    .map((t) => (t.resolvedAt!.getTime() - t.createdAt.getTime()) / (1000 * 60 * 60));

  const avgResolutionTime =
    resolutionTimes.length > 0
      ? resolutionTimes.reduce((a, b) => a + b, 0) / resolutionTimes.length
      : 0;

  const satisfactionRatings = tickets
    .filter((t) => t.satisfactionRating)
    .map((t) => t.satisfactionRating!);

  const satisfactionScore =
    satisfactionRatings.length > 0
      ? (satisfactionRatings.reduce((a, b) => a + b, 0) / satisfactionRatings.length / 5) * 100
      : 0;

  const escalatedTickets = tickets.filter((t) => t.priority === 'critical').length;
  const refundsProcessed = refunds.filter((r) => r.status === 'processed').length;
  const totalRefundAmount = refunds
    .filter((r) => r.status === 'processed')
    .reduce((sum, r) => sum + r.amount, 0);

  const disputesOpen = disputes.filter((d) => d.status === 'open' || d.status === 'escalated')
    .length;

  return {
    totalTickets: tickets.length,
    openTickets,
    averageResolutionTime: avgResolutionTime,
    firstResponseTime: 15, // Placeholder
    satisfactionScore,
    resolvedToday,
    escalatedTickets,
    refundsProcessed,
    totalRefundAmount,
    disputesOpen,
  };
}

/**
 * Generate support report
 */
export interface SupportReport {
  period: 'daily' | 'weekly' | 'monthly';
  startDate: Date;
  endDate: Date;
  metrics: SupportMetrics;
  topIssues: Array<{ category: TicketCategory; count: number }>;
  agentPerformance: Array<{
    agentId: number;
    agentName: string;
    ticketsResolved: number;
    averageResolutionTime: number;
    satisfactionRating: number;
  }>;
}

export function generateSupportReport(
  period: 'daily' | 'weekly' | 'monthly',
  startDate: Date,
  endDate: Date,
  tickets: SupportTicket[],
  refunds: RefundRequest[],
  disputes: Dispute[],
  agents: SupportAgent[]
): SupportReport {
  const periodTickets = tickets.filter(
    (t) => t.createdAt >= startDate && t.createdAt <= endDate
  );

  const metrics = calculateSupportMetrics(periodTickets, refunds, disputes);

  // Calculate top issues
  const issueCounts: Record<TicketCategory, number> = {
    payment: 0,
    technical: 0,
    account: 0,
    bonus: 0,
    complaint: 0,
    kyc: 0,
    other: 0,
  };

  periodTickets.forEach((t) => {
    issueCounts[t.category]++;
  });

  const topIssues = Object.entries(issueCounts)
    .map(([category, count]) => ({ category: category as TicketCategory, count }))
    .sort((a, b) => b.count - a.count)
    .slice(0, 5);

  // Calculate agent performance
  const agentPerformance = agents.map((agent) => ({
    agentId: agent.id,
    agentName: agent.name,
    ticketsResolved: agent.resolvedTickets,
    averageResolutionTime: agent.averageResolutionTime,
    satisfactionRating: agent.satisfactionRating,
  }));

  return {
    period,
    startDate,
    endDate,
    metrics,
    topIssues,
    agentPerformance,
  };
}
