package db

import (
	"strconv"
	"strings"
	"time"

	"server/internal/models"

	"gorm.io/gorm"
)

func scheduleDayIndex(t time.Time) int {
	wd := t.Weekday()
	if wd == time.Sunday {
		return 6
	}
	return int(wd) - 1
}

func parseTimeMinutes(tStr string) int {
	parts := strings.Split(tStr, ":")
	if len(parts) != 2 {
		return 0
	}
	hours, _ := strconv.Atoi(parts[0])
	mins, _ := strconv.Atoi(parts[1])
	return hours*60 + mins
}

func studentClassIDs(db *gorm.DB, studentRkID int64) []int64 {
	var classRkIDs []int64
	_ = db.Model(&models.ClassStudent{}).
		Where("student_rk_id = ?", studentRkID).
		Pluck("class_rk_id", &classRkIDs).Error
	return classRkIDs
}

// FindActiveClassAndPeriodForStudent trả về lớp + ca đang trong khung giờ học.
func FindActiveClassAndPeriodForStudent(db *gorm.DB, studentRkID int64) (int64, int) {
	classRkIDs := studentClassIDs(db, studentRkID)
	if len(classRkIDs) == 0 {
		return 0, 0
	}

	var schedules []models.ClassSchedule
	if err := db.Where("class_rk_id IN ? AND is_active = ?", classRkIDs, true).Find(&schedules).Error; err != nil || len(schedules) == 0 {
		return classRkIDs[0], 1
	}

	now := time.Now()
	day := scheduleDayIndex(now)
	currMin := now.Hour()*60 + now.Minute()

	for _, s := range schedules {
		if s.DayOfWeek != day {
			continue
		}
		startMin := parseTimeMinutes(s.StartTime)
		endMin := parseTimeMinutes(s.EndTime)
		if currMin >= startMin && currMin <= endMin {
			period := s.Period
			if period < 1 {
				period = 1
			}
			return s.ClassRkID, period
		}
	}

	return classRkIDs[0], 1
}

func FindActiveClassForStudent(db *gorm.DB, studentRkID int64) int64 {
	classID, _ := FindActiveClassAndPeriodForStudent(db, studentRkID)
	return classID
}

// ResolveSessionPeriodForDate lấy ca theo ngày (dùng khi xem nhật ký quá khứ).
func ResolveSessionPeriodForDate(db *gorm.DB, classRkID int64, date string, period int) int {
	if period > 0 {
		return period
	}
	day, err := time.Parse("2006-01-02", date)
	if err != nil {
		return 1
	}
	var slots []models.ClassSchedule
	if err := db.Where("class_rk_id = ? AND day_of_week = ? AND is_active = ?", classRkID, scheduleDayIndex(day), true).
		Order("period asc, start_time asc").Find(&slots).Error; err != nil || len(slots) == 0 {
		return 1
	}
	if slots[0].Period > 0 {
		return slots[0].Period
	}
	return 1
}
