package repository

import (
	"context"
	"time"

	"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
)

type ReportRepository interface {
	GenerateReport(timeFrame domain.TimeFrame, start, end time.Time) (*domain.Report, error)
	SaveReport(report *domain.Report) error
	FindReportsByTimeFrame(timeFrame domain.TimeFrame, limit int) ([]*domain.Report, error)
}

type ReportRepo struct {
	store *Store
}

func NewReportRepo(store *Store) ReportRepository {
	return &ReportRepo{store: store}
}

func (r *ReportRepo) GenerateReport(timeFrame domain.TimeFrame, start, end time.Time) (*domain.Report, error) {
	// Implement SQL queries to calculate metrics
	var report domain.Report

	// Total Bets
	err := r.store.conn.QueryRow(
		context.Background(),
		`SELECT COUNT(*) FROM bets 
		WHERE created_at BETWEEN $1 AND $2`, start, end).Scan(&report.TotalBets)
	if err != nil {
		return nil, err
	}

	// Total Cash In
	err = r.store.conn.QueryRow(
		context.Background(),
		`SELECT COALESCE(SUM(amount), 0) FROM transactions 
		WHERE type = 'stake' AND created_at BETWEEN $1 AND $2`, start, end).Scan(&report.TotalCashIn)
	if err != nil {
		return nil, err
	}

	// Similar queries for Cash Out and Cash Back...

	report.TimeFrame = timeFrame
	report.PeriodStart = start
	report.PeriodEnd = end
	report.GeneratedAt = time.Now()

	return &report, nil
}

func (r *ReportRepo) SaveReport(report *domain.Report) error {
	_, err := r.store.conn.Exec(
		context.Background(),
		`INSERT INTO reports 
		(id, time_frame, period_start, period_end, total_bets, total_cash_in, total_cash_out, total_cash_back, generated_at)
		VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
		report.ID, report.TimeFrame, report.PeriodStart, report.PeriodEnd,
		report.TotalBets, report.TotalCashIn, report.TotalCashOut, report.TotalCashBack, report.GeneratedAt)
	return err
}

func (r *ReportRepo) FindReportsByTimeFrame(timeFrame domain.TimeFrame, limit int) ([]*domain.Report, error) {
	rows, err := r.store.conn.Query(
		context.Background(),
		`SELECT id, time_frame, period_start, period_end, total_bets, 
		total_cash_in, total_cash_out, total_cash_back, generated_at
		FROM reports 
		WHERE time_frame = $1
		ORDER BY generated_at DESC
		LIMIT $2`,
		timeFrame, limit)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var reports []*domain.Report
	for rows.Next() {
		var report domain.Report
		err := rows.Scan(
			&report.ID,
			&report.TimeFrame,
			&report.PeriodStart,
			&report.PeriodEnd,
			&report.TotalBets,
			&report.TotalCashIn,
			&report.TotalCashOut,
			&report.TotalCashBack,
			&report.GeneratedAt,
		)
		if err != nil {
			return nil, err
		}
		reports = append(reports, &report)
	}

	if err := rows.Err(); err != nil {
		return nil, err
	}

	return reports, nil
}
