import { Injectable, Inject, Logger } from '@nestjs/common';
import { NotificationChannel, NotificationStatus } from '../../domain/entities/notification.entity';
import { NOTIFICATION_REPOSITORY, INotificationRepository } from '../../domain/repositories/notification.repository.interface';
import { NotificationService } from './notification.service';
import { BroadcastDto } from '../../interface/http/dto/broadcast.dto';

export interface NotificationStats {
  totalSent: number;
  totalFailed: number;
  totalPending: number;
  totalRead: number;
  deliveryRate: number;
  channelBreakdown: Record<string, { sent: number; failed: number }>;
  todaySent: number;
}

export interface NotificationTemplate {
  id: string;
  name: string;
  channel: NotificationChannel;
  titleTemplate: string;
  bodyTemplate: string;
  description: string;
}

@Injectable()
export class AdminNotificationService {
  private readonly logger = new Logger('AdminNotificationService');

  constructor(
    @Inject(NOTIFICATION_REPOSITORY)
    private readonly notificationRepo: INotificationRepository,
    private readonly notificationService: NotificationService,
  ) {}

  /**
   * Get notification delivery stats.
   */
  async getStats(): Promise<NotificationStats> {
    const statusCounts = await this.notificationRepo.getStatusCounts();
    const channelCounts = await this.notificationRepo.getChannelStatusCounts();
    const todaySent = await this.notificationRepo.countTodaySent();

    const statusMap: Record<string, number> = {};
    for (const row of statusCounts) {
      statusMap[row.status] = parseInt(row.count, 10);
    }

    const totalSent = statusMap[NotificationStatus.SENT] || 0;
    const totalFailed = statusMap[NotificationStatus.FAILED] || 0;
    const totalPending = statusMap[NotificationStatus.PENDING] || 0;
    const totalRead = statusMap[NotificationStatus.READ] || 0;
    const totalAll = totalSent + totalFailed + totalPending + totalRead;
    const deliveryRate = totalAll > 0 ? (totalSent + totalRead) / totalAll : 0;

    // Build channel breakdown
    const channelBreakdown: Record<string, { sent: number; failed: number }> = {};
    for (const row of channelCounts) {
      if (!channelBreakdown[row.channel]) {
        channelBreakdown[row.channel] = { sent: 0, failed: 0 };
      }
      if (row.status === NotificationStatus.SENT || row.status === NotificationStatus.READ) {
        channelBreakdown[row.channel].sent += parseInt(row.count, 10);
      } else if (row.status === NotificationStatus.FAILED) {
        channelBreakdown[row.channel].failed += parseInt(row.count, 10);
      }
    }

    return {
      totalSent,
      totalFailed,
      totalPending,
      totalRead,
      deliveryRate: Math.round(deliveryRate * 10000) / 100,
      channelBreakdown,
      todaySent,
    };
  }

  /**
   * Send broadcast notification to all or segmented users.
   * In production, this would query the user-service for user IDs based on segment.
   */
  async sendBroadcast(dto: BroadcastDto): Promise<{ queued: number; message: string }> {
    // Mock: In production, we would query user-service for user IDs
    const mockUserIds = this.getMockUserIds(dto.segment || 'all');

    let queued = 0;
    for (const userId of mockUserIds) {
      try {
        await this.notificationService.send({
          userId,
          channel: dto.channel,
          title: dto.title,
          body: dto.body,
          data: { ...dto.data, broadcast: true, segment: dto.segment || 'all' },
        });
        queued++;
      } catch (error) {
        this.logger.error(`Failed to queue broadcast for user ${userId}: ${error.message}`);
      }
    }

    this.logger.log(`Broadcast sent: ${queued} notifications queued for segment "${dto.segment || 'all'}"`);
    return { queued, message: `Broadcast queued for ${queued} users` };
  }

  /**
   * Get available notification templates.
   * In production, templates would be stored in the database.
   */
  async getTemplates(): Promise<NotificationTemplate[]> {
    return [
      {
        id: 'welcome',
        name: 'Welcome Notification',
        channel: NotificationChannel.IN_APP,
        titleTemplate: 'Welcome to Genex!',
        bodyTemplate: 'Your account has been created successfully. Complete your KYC to unlock all features.',
        description: 'Sent to new users upon registration',
      },
      {
        id: 'trade-executed',
        name: 'Trade Executed',
        channel: NotificationChannel.PUSH,
        titleTemplate: 'Trade Executed',
        bodyTemplate: 'Your {{side}} order was filled: {{quantity}} unit(s) at ${{price}}',
        description: 'Sent when a trade order is matched and executed',
      },
      {
        id: 'kyc-approved',
        name: 'KYC Approved',
        channel: NotificationChannel.IN_APP,
        titleTemplate: 'KYC Approved',
        bodyTemplate: 'Your KYC verification has been approved. You are now at Level {{level}}.',
        description: 'Sent when KYC verification is approved',
      },
      {
        id: 'settlement-complete',
        name: 'Settlement Complete',
        channel: NotificationChannel.IN_APP,
        titleTemplate: 'Settlement Processed',
        bodyTemplate: 'Your settlement of ${{amount}} has been processed successfully.',
        description: 'Sent when a trade settlement is completed',
      },
      {
        id: 'refund-processed',
        name: 'Refund Processed',
        channel: NotificationChannel.EMAIL,
        titleTemplate: 'Refund Processed',
        bodyTemplate: 'Your refund of ${{amount}} has been processed. It may take 3-5 business days to appear.',
        description: 'Sent when a refund is completed',
      },
      {
        id: 'security-alert',
        name: 'Security Alert',
        channel: NotificationChannel.SMS,
        titleTemplate: 'Security Notice',
        bodyTemplate: 'We have detected unusual activity on your account. Please verify your recent transactions.',
        description: 'Sent when anomalous activity is detected on an account',
      },
      {
        id: 'system-maintenance',
        name: 'System Maintenance',
        channel: NotificationChannel.IN_APP,
        titleTemplate: 'Scheduled Maintenance',
        bodyTemplate: 'The platform will undergo scheduled maintenance on {{date}} from {{startTime}} to {{endTime}}.',
        description: 'Broadcast for planned system maintenance windows',
      },
    ];
  }

  /**
   * Mock user IDs for broadcast (in production: query user-service).
   */
  private getMockUserIds(segment: string): string[] {
    const baseMockIds = [
      '00000000-0000-0000-0000-000000000001',
      '00000000-0000-0000-0000-000000000002',
      '00000000-0000-0000-0000-000000000003',
    ];

    switch (segment) {
      case 'new':
        return baseMockIds.slice(0, 1);
      case 'active':
        return baseMockIds.slice(0, 2);
      case 'all':
      default:
        return baseMockIds;
    }
  }
}
