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

export interface TrendDataPoint {
  timestamp: Date;
  value: number;
  count: number;
}

export interface TrendsResult {
  metric: string;
  granularity: string;
  data: TrendDataPoint[];
  summary: {
    total: number;
    average: number;
    min: number;
    max: number;
  };
}

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

  async getTrends(query: TrendsQueryDto): Promise<TrendsResult> {
    const { metric, startDate, endDate, granularity = 'day' } = query;

    const data = await this.metricsRepository.find({
      where: {
        metricType: metric as MetricType,
        granularity: granularity as TimeGranularity,
        timestamp: Between(new Date(startDate), new Date(endDate)),
        dimension: undefined,
      },
      order: { timestamp: 'ASC' },
    });

    const values = data.map((d) => Number(d.value));
    const total = values.reduce((sum, v) => sum + v, 0);

    return {
      metric,
      granularity,
      data: data.map((d) => ({
        timestamp: d.timestamp,
        value: Number(d.value),
        count: Number(d.count),
      })),
      summary: {
        total,
        average: values.length > 0 ? total / values.length : 0,
        min: values.length > 0 ? Math.min(...values) : 0,
        max: values.length > 0 ? Math.max(...values) : 0,
      },
    };
  }

  async compareTrends(
    query: TrendsQueryDto,
    compareStartDate: string,
    compareEndDate: string,
  ): Promise<{ current: TrendsResult; previous: TrendsResult; change: number }> {
    const current = await this.getTrends(query);
    const previous = await this.getTrends({
      ...query,
      startDate: compareStartDate,
      endDate: compareEndDate,
    });

    const currentTotal = current.summary.total;
    const previousTotal = previous.summary.total;
    const change =
      previousTotal > 0 ? ((currentTotal - previousTotal) / previousTotal) * 100 : 0;

    return { current, previous, change };
  }
}
