package httpserver

import (
	"context"
	"time"

	"log"

	// "time"

	"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
	eventsvc "github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
	oddssvc "github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
	resultsvc "github.com/SamuelTariku/FortuneBet-Backend/internal/services/result"
	"github.com/SamuelTariku/FortuneBet-Backend/internal/services/ticket"
	"github.com/SamuelTariku/FortuneBet-Backend/internal/web_server/worker"
	"github.com/go-co-op/gocron"
	"github.com/robfig/cron/v3"
)

func SetupReportCronJob(reportWorker *worker.ReportWorker) {
	s := gocron.NewScheduler(time.UTC)

	// Daily at midnight
	_, _ = s.Every(1).Day().At("00:00").Do(func() {
		_ = reportWorker.GenerateAndExport(domain.Daily)
	})

	// Weekly on Sunday at 00:05
	_, _ = s.Every(1).Week().Sunday().At("00:05").Do(func() {
		_ = reportWorker.GenerateAndExport(domain.Weekly)
	})

	// Monthly on 1st at 00:10
	_, _ = s.Every(1).Month(1).At("00:10").Do(func() {
		_ = reportWorker.GenerateAndExport(domain.Monthly)
	})

	s.StartAsync()
}

func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.ServiceImpl, resultService *resultsvc.Service) {
	c := cron.New(cron.WithSeconds())

	schedule := []struct {
		spec string
		task func()
	}{
		// {
		// 	spec: "0 0 * * * *", // Every 1 hour
		// 	task: func() {
		// 		if err := eventService.FetchUpcomingEvents(context.Background()); err != nil {
		// 			log.Printf("FetchUpcomingEvents error: %v", err)
		// 		}
		// 	},
		// },
		// {
		// 	spec: "0 0 * * * *", // Every 15 minutes
		// 	task: func() {
		// 		if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil {
		// 			log.Printf("FetchNonLiveOdds error: %v", err)
		// 		}
		// 	},
		// },
		{
			spec: "0 */5 * * * *", // Every 5 Minutes
			task: func() {
				log.Println("Updating expired events status...")

				if _, err := resultService.CheckAndUpdateExpiredEvents(context.Background()); err != nil {
					log.Printf("Failed to update events: %v", err)
				} else {
					log.Printf("Successfully updated expired events")
				}
			},
		},
		{
			spec: "0 */15 * * * *", // Every 15 Minutes
			task: func() {
				log.Println("Fetching results for upcoming events...")

				if err := resultService.FetchAndProcessResults(context.Background()); err != nil {
					log.Printf("Failed to process result: %v", err)
				} else {
					log.Printf("Successfully processed all outcomes")
				}
			},
		},
	}

	for _, job := range schedule {
		job.task()
		if _, err := c.AddFunc(job.spec, job.task); err != nil {
			log.Fatalf("Failed to schedule cron job: %v", err)
		}
	}

	c.Start()
	log.Println("Cron jobs started for event and odds services")
}

func StartTicketCrons(ticketService ticket.Service) {
	c := cron.New(cron.WithSeconds())

	schedule := []struct {
		spec string
		task func()
	}{
		{
			spec: "0 0 * * * *", // Every hour
			task: func() {
				log.Println("Deleting old tickets...")
				if err := ticketService.DeleteOldTickets(context.Background()); err != nil {
					log.Printf("Failed to remove old ticket: %v", err)
				} else {
					log.Printf("Successfully deleted old tickets")
				}
			},
		},
	}

	for _, job := range schedule {
		if _, err := c.AddFunc(job.spec, job.task); err != nil {
			log.Fatalf("Failed to schedule cron job: %v", err)
		}
	}

	c.Start()
	log.Println("Cron jobs started for ticket service")
}
