// Package mapper 数据访问层
package mapper

import (
	"server/config"
	"server/modules/yx/dto"
	"server/modules/yx/entity"

	"gorm.io/gorm/clause"
)

type YxSchoolMajorMapper struct{}

func NewYxSchoolMajorMapper() *YxSchoolMajorMapper {
	return &YxSchoolMajorMapper{}
}

func (m *YxSchoolMajorMapper) FindAll(page, size int) ([]entity.YxSchoolMajor, int64, error) {
	var items []entity.YxSchoolMajor
	var total int64
	config.DB.Model(&entity.YxSchoolMajor{}).Count(&total)
	err := config.DB.Offset((page - 1) * size).Limit(size).Find(&items).Error
	return items, total, err
}

func (m *YxSchoolMajorMapper) FindByID(id string) (*entity.YxSchoolMajor, error) {
	var item entity.YxSchoolMajor
	err := config.DB.First(&item, "id = ?", id).Error
	return &item, err
}

func (m *YxSchoolMajorMapper) Create(item *entity.YxSchoolMajor) error {
	return config.DB.Create(item).Error
}

func (m *YxSchoolMajorMapper) Update(item *entity.YxSchoolMajor) error {
	return config.DB.Save(item).Error
}

func (m *YxSchoolMajorMapper) UpdateFields(id string, fields map[string]interface{}) error {
	return config.DB.Model(&entity.YxSchoolMajor{}).Where("id = ?", id).Updates(fields).Error
}

func (m *YxSchoolMajorMapper) Delete(id string) error {
	return config.DB.Delete(&entity.YxSchoolMajor{}, "id = ?", id).Error
}

func (m *YxSchoolMajorMapper) BatchCreate(items []entity.YxSchoolMajor, batchSize int) error {
	return config.DB.CreateInBatches(items, batchSize).Error
}

func (m *YxSchoolMajorMapper) BatchUpdate(items []entity.YxSchoolMajor) error {
	return config.DB.Save(items).Error
}

func (m *YxSchoolMajorMapper) BatchUpsert(items []entity.YxSchoolMajor, updateColumns []string) error {
	return config.DB.Clauses(clause.OnConflict{
		Columns:   []clause.Column{{Name: "id"}},
		DoUpdates: clause.AssignmentColumns(updateColumns),
	}).CreateInBatches(items, 100).Error
}

func (m *YxSchoolMajorMapper) BatchDelete(ids []string) error {
	return config.DB.Delete(&entity.YxSchoolMajor{}, "id IN ?", ids).Error
}

// func (m *YxSchoolMajorMapper) SelectSchoolMajor(query dto.SchoolMajorQuery) ([]dto.SchoolMajorDTO, error) {
// 	var items []dto.SchoolMajorDTO

// 	sql := `
// 		SELECT
// 			sm.school_code,
// 			sc.school_name,
// 			sm.major_code,
// 			sm.major_name,
// 			sm.major_type,
// 			sm.major_type_child,
// 			sm.plan_num,
// 			sm.main_subjects,
// 			sm.limitation,
// 			sm.chinese_score_limitation,
// 			sm.english_score_limitation,
// 			sm.cultural_score_limitation,
// 			sm.professional_score_limitation,
// 			sm.enrollment_code,
// 			sm.tuition,
// 			sm.detail,
// 			sm.category,
// 			sm.batch,
// 			sm.rules_enroll_probability,
// 			sm.probability_operator,
// 			sm.private_rules_enroll_probability,
// 			sm.private_probability_operator,
// 			sm.rules_enroll_probability_sx,
// 			sm.kslx,
// 			sm.state
// 		FROM yx_school_major sm
// 		LEFT JOIN (SELECT school_id,school_name,school_code FROM yx_school_child group by school_code) sc ON sc.school_code = sm.school_code
// 		LEFT JOIN yx_school s ON s.id = sc.school_id
// 		WHERE 1=1 AND sm.state > 0
// 	`
// 	params := []interface{}{}

// 	if query.MajorType != "" {
// 		sql += " AND sm.major_type = ?"
// 		params = append(params, query.MajorType)
// 	}
// 	if query.Category != "" {
// 		sql += " AND sm.category = ?"
// 		params = append(params, query.Category)
// 	}
// 	if len(query.MajorTypeChildren) > 0 {
// 		sql += " AND sm.major_type_child IN ?"
// 		params = append(params, query.MajorTypeChildren)
// 	}
// 	if query.MainSubjects != "" {
// 		sql += " AND sm.main_subjects = ?"
// 		params = append(params, query.MainSubjects)
// 	}

// 	err := config.DB.Raw(sql, params...).Scan(&items).Error
// 	return items, err
// }

func (m *YxSchoolMajorMapper) SelectSchoolMajor(query dto.SchoolMajorQuery) ([]dto.SchoolMajorDTO, error) {
	var items []dto.SchoolMajorDTO

	queryBuilder := config.DB.Table("yx_school_major sm").
		Select(`
			sm.school_code,
			sc.school_name,
			sm.major_code,
			sm.major_name,
			sm.major_type,
			sm.major_type_child,
			sm.plan_num,
			sm.main_subjects,
			sm.limitation,
			sm.chinese_score_limitation,
			sm.english_score_limitation,
			sm.cultural_score_limitation,
			sm.professional_score_limitation,
			sm.enrollment_code,
			sm.tuition,
			sm.detail,
			sm.category,
			sm.batch,
			sm.rules_enroll_probability,
			sm.probability_operator,
			sm.private_rules_enroll_probability,
			sm.private_probability_operator,
			sm.rules_enroll_probability_sx,
			sm.kslx,
			sm.state
		`).
		Joins("LEFT JOIN (SELECT school_id,school_name,school_code FROM yx_school_child group by school_code) sc ON sc.school_code = sm.school_code").
		Joins("LEFT JOIN yx_school s ON s.id = sc.school_id").
		Where("sm.state > 0")

	if query.MajorType != "" {
		queryBuilder = queryBuilder.Where("sm.major_type = ?", query.MajorType)
	}
	if query.Category != "" {
		queryBuilder = queryBuilder.Where("sm.category = ?", query.Category)
	}
	if len(query.MajorTypeChildren) > 0 {
		queryBuilder = queryBuilder.Where("sm.major_type_child IN ?", query.MajorTypeChildren)
	}
	if query.MainSubjects != "" {
		queryBuilder = queryBuilder.Where("sm.main_subjects = ?", query.MainSubjects)
	}

	err := queryBuilder.Scan(&items).Error
	return items, err
}
