package service

import (
	"errors"
	"fmt"
	"strings"
	"time"

	"github.com/tidbcloud/aisupport/services/oncall/db"
	"github.com/tidbcloud/aisupport/services/oncall/models"
)

func (s *ScheduleService) resolveEngineerByIdentifier(teamID uint, ident string) (*models.Engineer, error) {
	ident = strings.TrimSpace(ident)
	if ident == "" {
		return nil, errors.New("engineer identifier is required")
	}
	mail := normalizeEmail(ident)
	if strings.Contains(mail, "@") {
		var eng models.Engineer
		if err := db.DB.Where("email = ?", mail).First(&eng).Error; err != nil {
			return nil, fmt.Errorf("engineer %s not found", ident)
		}
		return &eng, nil
	}

	var links []models.EngineerTeam
	if err := db.DB.Preload("Engineer").Where("team_id = ?", teamID).Find(&links).Error; err != nil {
		return nil, err
	}
	for _, link := range links {
		if normalizeEmail(link.Engineer.Name) == mail || normalizeEmail(link.Engineer.EnName) == mail {
			eng := link.Engineer
			return &eng, nil
		}
	}

	return nil, fmt.Errorf("engineer identifier %s not found in team %d", ident, teamID)
}

func (s *ScheduleService) nextOverlayForRange(teamID uint, startTime, endTime int64, isBackup bool) (int, error) {
	if teamID == 0 {
		return 0, errors.New("missing team_id")
	}
	if startTime <= 0 || endTime <= startTime {
		return 0, errors.New("invalid time range")
	}
	var maxOverlay int
	if err := db.DB.Model(&models.ShiftInterval{}).
		Where("team_id = ? AND is_backup = ? AND end_time > ? AND start_time < ?", teamID, isBackup, startTime, endTime).
		Select("COALESCE(MAX(overlay), 0)").
		Scan(&maxOverlay).Error; err != nil {
		return 0, err
	}
	if maxOverlay < 0 {
		maxOverlay = 0
	}
	return maxOverlay + 1, nil
}

func (s *ScheduleService) PreviewManualSegmentChange(teamID uint, startTime, endTime int64, engineerIdent string, isBackup bool) (map[string]interface{}, error) {
	if teamID == 0 {
		return nil, errors.New("missing team_id")
	}
	if startTime <= 0 || endTime <= startTime {
		return nil, errors.New("invalid time range")
	}
	if endTime <= time.Now().Unix() {
		return nil, errors.New("only current/future segments are allowed for direct manual edit")
	}
	eng, err := s.resolveEngineerByIdentifier(teamID, engineerIdent)
	if err != nil {
		return nil, err
	}
	overlay, err := s.nextOverlayForRange(teamID, startTime, endTime, isBackup)
	if err != nil {
		return nil, err
	}
	before, err := s.GetEffectiveScheduleV2([]uint{teamID}, startTime, endTime, isBackup, false)
	if err != nil {
		return nil, err
	}
	return map[string]interface{}{
		"dry_run":          true,
		"type":             "manual_segment_change",
		"team_id":          teamID,
		"start_time":       startTime,
		"end_time":         endTime,
		"new_engineer_id":  eng.ID,
		"new_engineer":     eng.Name,
		"new_email":        eng.Email,
		"new_overlay":      overlay,
		"is_backup":        isBackup,
		"effective_before": before,
	}, nil
}
