package main

import (
	"fmt"
	"time"

	"github.com/robfig/cron/v3"
)

func main() {
	// Create a new cron scheduler
	c := cron.New()

	// Add jobs with cron expressions
	// Format: second minute hour day-of-month month day-of-week

	// Run every minute
	c.AddFunc("* * * * *", func() {
		fmt.Println("Every minute:", time.Now().Format("15:04:05"))
	})

	// Run every 5 minutes
	c.AddFunc("*/5 * * * *", func() {
		fmt.Println("Every 5 minutes")
	})

	// Run at specific times
	c.AddFunc("0 9 * * *", func() {
		fmt.Println("Daily at 9:00 AM")
	})

	// Run on weekdays at 8:30 AM
	c.AddFunc("30 8 * * 1-5", func() {
		fmt.Println("Weekdays at 8:30 AM")
	})

	// Run on the 1st and 15th of each month
	c.AddFunc("0 0 1,15 * *", func() {
		fmt.Println("1st and 15th of month")
	})

	// With seconds precision (requires WithSeconds option)
	cWithSeconds := cron.New(cron.WithSeconds())
	cWithSeconds.AddFunc("*/10 * * * * *", func() {
		fmt.Println("Every 10 seconds:", time.Now().Format("15:04:05"))
	})

	// Get entry ID for later reference
	entryID, _ := c.AddFunc("* * * * *", func() {
		fmt.Println("Job with ID")
	})
	fmt.Println("Entry ID:", entryID)

	// Remove a job by ID
	c.Remove(entryID)

	// Use AddJob for more control
	c.AddJob("@every 2s", cron.FuncJob(func() {
		fmt.Println("Every 2 seconds via AddJob")
	}))

	// Predefined schedules
	c.AddFunc("@yearly", func() { fmt.Println("Once a year") })   // Jan 1, 00:00
	c.AddFunc("@monthly", func() { fmt.Println("Once a month") }) // 1st of month, 00:00
	c.AddFunc("@weekly", func() { fmt.Println("Once a week") })   // Sunday, 00:00
	c.AddFunc("@daily", func() { fmt.Println("Once a day") })     // 00:00
	c.AddFunc("@hourly", func() { fmt.Println("Every hour") })    // XX:00

	// Every interval
	c.AddFunc("@every 1h30m", func() {
		fmt.Println("Every 1 hour 30 minutes")
	})

	// Start the scheduler
	c.Start()

	// List all entries
	fmt.Println("\nScheduled entries:")
	for _, entry := range c.Entries() {
		fmt.Printf("  ID: %d, Next: %s\n", entry.ID, entry.Next.Format("15:04:05"))
	}

	// Run for a while
	time.Sleep(5 * time.Second)

	// Stop gracefully (waits for running jobs)
	ctx := c.Stop()
	<-ctx.Done()
	fmt.Println("Scheduler stopped")

	// With options
	_ = cron.New(
		cron.WithSeconds(),                          // 6-field expression with seconds
		cron.WithLocation(time.UTC),                 // Use UTC timezone
		cron.WithLogger(cron.DefaultLogger),         // Custom logger
		cron.WithChain(                              // Job wrappers
			cron.Recover(cron.DefaultLogger),        // Recover from panics
			cron.SkipIfStillRunning(cron.DefaultLogger), // Skip if previous still running
		),
	)

	// Custom job type
	type EmailJob struct {
		To      string
		Subject string
	}

	// Implement cron.Job interface
	// func (e EmailJob) Run() {
	//     sendEmail(e.To, e.Subject)
	// }
}
