import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Between } from 'typeorm';
import { AggregatedMetric } from '../entities/aggregated-metric.entity';
import { FunnelQueryDto } from './dto/funnel-query.dto';

export interface FunnelStep {
  name: string;
  eventType: string;
  count: number;
  conversionRate: number;
  dropoffRate: number;
}

export interface FunnelResult {
  steps: FunnelStep[];
  overallConversionRate: number;
  totalStarted: number;
  totalCompleted: number;
}

@Injectable()
export class FunnelsService {
  constructor(
    @InjectRepository(AggregatedMetric)
    private readonly metricsRepository: Repository<AggregatedMetric>,
  ) {}

  async analyzeFunnel(query: FunnelQueryDto): Promise<FunnelResult> {
    const { steps, startDate, endDate } = query;

    const stepCounts: number[] = [];

    for (const step of steps) {
      const count = await this.metricsRepository
        .createQueryBuilder('m')
        .select('COALESCE(SUM(m.count), 0)', 'total')
        .where('m.dimension = :dimension', { dimension: 'event_type' })
        .andWhere('m.dimensionValue = :eventType', { eventType: step.eventType })
        .andWhere('m.timestamp BETWEEN :start AND :end', {
          start: new Date(startDate),
          end: new Date(endDate),
        })
        .getRawOne();

      stepCounts.push(Number(count?.total ?? 0));
    }

    const funnelSteps: FunnelStep[] = steps.map((step, index) => {
      const count = stepCounts[index] ?? 0;
      const previousCount = index > 0 ? stepCounts[index - 1] ?? 0 : count;
      const conversionRate = previousCount > 0 ? (count / previousCount) * 100 : 0;
      const dropoffRate = 100 - conversionRate;

      return {
        name: step.name,
        eventType: step.eventType,
        count,
        conversionRate,
        dropoffRate: index === 0 ? 0 : dropoffRate,
      };
    });

    const totalStarted = stepCounts[0] ?? 0;
    const totalCompleted = stepCounts[stepCounts.length - 1] ?? 0;
    const overallConversionRate =
      totalStarted > 0 ? (totalCompleted / totalStarted) * 100 : 0;

    return {
      steps: funnelSteps,
      overallConversionRate,
      totalStarted,
      totalCompleted,
    };
  }

  async getPresets() {
    return [
      {
        id: 'signup',
        name: 'Signup Funnel',
        steps: [
          { name: 'Landing Page', eventType: 'page_view_landing' },
          { name: 'Signup Started', eventType: 'signup_started' },
          { name: 'Email Verified', eventType: 'email_verified' },
          { name: 'Profile Completed', eventType: 'profile_completed' },
        ],
      },
      {
        id: 'purchase',
        name: 'Purchase Funnel',
        steps: [
          { name: 'Product View', eventType: 'product_view' },
          { name: 'Add to Cart', eventType: 'cart_add' },
          { name: 'Checkout Started', eventType: 'checkout_started' },
          { name: 'Purchase Complete', eventType: 'purchase' },
        ],
      },
    ];
  }
}
