package models

import (
	"WorldEpcho/src/datasource"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/go-xorm/xorm"
	"log"
)

type School struct {
	SchoolNo      string `xorm:"school_no" `              // 学校编号
	SchoolName    string `xorm:"school_name"`             // 学校名称
	Address       string `xorm:"address" `                // 地址
	Contact       string `xorm:"contact" `                // 联系人
	ContactNumber string `xorm:"contact_number" `         // 联系方式
	SchoolLeader  int64  `xorm:"school_leader" `          // 学校负责
	AllowOb       string `xorm:"allow_ob" json:"allowOb"` //{"AllowOb":true} （允许老师查看学生报表）
}

type Class struct {
	SchoolNo     string // 学校编号
	ClassName    string // 班级名称
	ClassNo      string // 班级编号
	Leader       int64  // 负责人
	ContactInfo  string // 联系方式
	ClassGroupNo string //班级组群号
}

type SchoolWithClassNames struct {
	SchoolName    string   `json:"SchoolName"`
	Address       string   `json:"Address"`
	Contact       string   `json:"Contact"`
	ContactNumber string   `json:"ContactNumber"`
	ClassNames    []string `json:"ClassNames"`
}

//学校和班级信息
type SchoolAndClasss struct {
	SchoolInfo School  `json:"school"`
	ClassInfo  []Class `json:"classs"`
}

func InsertSchoolAndClasses(school *School, classes []*Class) error {
	session := datasource.Engine.NewSession()
	defer session.Close()

	// Start a transaction
	if err := session.Begin(); err != nil {
		return err
	}

	// Insert School
	if _, err := session.Insert(school); err != nil {
		session.Rollback()
		return err
	}

	// Insert Classes
	for _, class := range classes {
		if _, err := session.Insert(class); err != nil {
			session.Rollback()
			return err
		}
	}

	// Commit the transaction
	return session.Commit()
}

// 根据班级名称查询班级信息的函数
func GetClassBySchoolNoAndClassName(shcoolNo, className string) (*Class, bool, error) {
	class := &Class{}
	has, err := datasource.Engine.Where("school_no = ? and class_name = ?", shcoolNo, className).Get(class)
	if err != nil {
		return nil, false, err
	}
	if !has {
		// 如果没有找到对应的班级信息，可以返回一个自定义的错误或者 nil
		return nil, false, nil
	}
	return class, true, nil
}

// 插入数据
func InsertSchool(school *School) error {
	_, err := datasource.Engine.Insert(school)
	return err
}

func InsertClass(class *Class) error {
	_, err := datasource.Engine.Insert(class)
	return err
}

// 根据学校负责人id获取学校信息和班级信息
func GetClassesBySchoolLeader(engine *xorm.Engine, leaderId int64) ([]Class, error) {
	var classes []Class
	// 通过连接查询 school 和 class 表
	err := engine.Join("INNER", "school", "school.school_no = class.school_no").
		Where("school.school_leader = ?", leaderId).
		Find(&classes)
	if err != nil {
		return nil, err
	}
	return classes, nil
}

// 根据学校负责人id获取学校信息
func GetSchoolsByLeader(leaderId int64) (*School, error) {
	var school School
	has, err := datasource.Engine.Where("school_leader = ?", leaderId).Get(&school)
	if err != nil {
		return nil, err // 数据库查询错误
	}
	if !has {
		return nil, nil // 没有找到对应的学校，返回 nil
	}

	return &school, nil // 成功找到学校，返回学校的指针
}

// 删除数据
func DeleteSchool(schoolNo string) error {
	_, err := datasource.Engine.Delete(&School{SchoolNo: schoolNo})
	return err
}

func DeleteClass(classNo string) error {
	_, err := datasource.Engine.Delete(&Class{ClassNo: classNo})
	return err
}

// 更新数据
func UpdateSchool(school *School) error {
	_, err := datasource.Engine.Where("school_no = ?", school.SchoolNo).Update(school)
	return err
}

// 更新学校信息数据
func UpdateSchool_Tx(session *xorm.Session, school *School) error {
	_, err := session.Where("school_no = ?", school.SchoolNo).Update(school)
	return err
}

func UpdateClass(class *Class) error {
	_, err := datasource.Engine.Where("class_no = ?", class.ClassNo).Update(class)
	return err
}

// 获取所有学校信息
func GetAllSchools() ([]School, error) {
	var schools []School

	err := datasource.Engine.Find(&schools)
	if err != nil {
		log.Printf("查询所有学校信息出错")
		return nil, err

	}
	return schools, nil
}

// 查询数据
func GetSchoolByNo(schoolNo string) (bool, *School, error) {
	school := new(School)
	has, err := datasource.Engine.Where("school_no = ?", schoolNo).Get(school)
	if err != nil {
		return false, nil, err
	}
	if !has {
		return false, nil, nil
	}
	return true, school, nil
}

// 根据学校编号查询学校信息
func GetSchoolByNo_Tx(session *xorm.Session, schoolNo string) (bool, *School, error) {
	school := new(School)
	has, err := session.Where("school_no = ?", schoolNo).Get(school)
	if err != nil {
		return false, nil, err
	}
	if !has {
		return false, nil, errors.New("School not found")
	}
	return true, school, nil
}

func GetClassByNo(classNo string) (*Class, error) {
	class := new(Class)
	has, err := datasource.Engine.Where("class_no = ?", classNo).Get(class)
	if err != nil {
		return nil, err
	}
	if !has {
		return nil, nil
	}
	return class, nil
}

func GetClassByNo_Tx(session *xorm.Session, classNo string) (*Class, error) {
	class := new(Class)
	has, err := session.Where("class_no = ?", classNo).Get(class)
	if err != nil {
		return nil, err
	}
	if !has {
		return nil, nil
	}
	return class, nil
}

//更新班级信息
func UpdateClassLeader(session *xorm.Session, class *Class) error {
	// 首先查询要更新的班级是否存在
	exist, err := session.Where("school_no = ? AND class_no = ?", class.SchoolNo, class.ClassNo).Get(&class)
	if err != nil {
		// 查询出错，返回错误
		return fmt.Errorf("查询班级信息出错: %v", err)
	}

	if !exist {
		// 班级信息不存在，无法更新，返回错误
		return fmt.Errorf("未找到对应的班级信息")
	}

	// 班级存在，执行更新负责人操作
	_, err = session.Table(Class{}).
		Where("school_no = ? AND class_no = ?", class.SchoolNo, class.ClassNo).
		Update(map[string]interface{}{
			"leader": class.Leader,
		})
	if err != nil {
		// 更新操作出错，返回错误
		return fmt.Errorf("更新班级负责人信息失败: %v", err)
	}

	// 更新成功
	return nil
}

// 更新班级信息
func UpdateClassInfo(session *xorm.Session, class *Class) error {
	// 首先查询要更新的班级是否存在
	exist, err := session.Where("school_no = ? AND class_no = ?", class.SchoolNo, class.ClassNo).Get(&Class{})
	if err != nil {
		// 查询出错，返回错误
		return fmt.Errorf("查询班级信息出错: %v", err)
	}

	if !exist {
		// 班级信息不存在，无法更新，返回错误
		return fmt.Errorf("未找到对应的班级信息")
	}

	// 班级存在，执行更新操作
	_, err = session.Table(Class{}).Where("school_no = ? AND class_no = ?", class.SchoolNo, class.ClassNo).Update(class)
	if err != nil {
		// 更新操作出错，返回错误
		return fmt.Errorf("更新班级信息失败: %v", err)
	}

	// 更新成功
	return nil
}

// GetAllClassesBySchoolNo 根据学校编号查询班级信息
func GetAllClassesBySchoolNo(schoolNo string) ([]Class, error) {
	var classes []Class
	err := datasource.Engine.Where("school_no = ?", schoolNo).Find(&classes)
	if err != nil {
		return nil, err
	}
	return classes, nil
}

func DoesAppGroupExist(session *xorm.Session, groupName string) (bool, *AppGroup, error) {
	var group AppGroup
	has, err := session.Where("group_name = ?", groupName).Get(&group)
	if err != nil {
		return false, nil, err
	}
	if has {
		return true, &group, nil // 存在返回true和对象
	}
	return false, nil, nil // 不存在返回false和nil
}

// QuerySchoolByName 函数，根据学校名称查询学校信息
func QuerySchoolByName(schoolName string) (*School, bool, error) {
	var school School
	has, err := datasource.Engine.Where("school_name = ?", schoolName).Get(&school)
	if err != nil {
		return nil, false, err
	}
	if !has {
		return nil, false, nil // 如果没有找到学校，返回nil
	}
	return &school, true, nil
}

// 查询班级对象函数
func QueryClassByLeaderAndSchoolNo(session *xorm.Session, leaderID int64, schoolNo string) (*Class, bool, error) {
	var class Class

	// 使用 SQL 查询
	has, err := session.Table("class").Where("leader = ?", leaderID).And("school_no = ?", schoolNo).Get(&class)
	if err != nil {
		return nil, false, err
	}
	if !has {
		//return nil, fmt.Errorf("未找到符合条件的班级")
		return nil, false, nil
	}

	return &class, true, nil

}

// 查询班级对象函数
func QueryClassByLeaderAndSchoolNo2(session *xorm.Session, leaderID int64, schoolNo string) ([]*Class, bool, error) {
	var classs []*Class

	// 使用 SQL 查询
	err := session.Table("class").Where("leader = ?", leaderID).And("school_no = ?", schoolNo).Find(&classs)
	if err != nil {
		return nil, false, err
	}
	/*
		   if !has {
				//return nil, fmt.Errorf("未找到符合条件的班级")
				return nil, false, nil
			}
	*/
	return classs, true, nil

}

// 查询班级对象函数
func QueryClassByLeader(session *xorm.Session, leaderID int64) ([]Class, bool, error) {
	var classs []Class

	// 使用 SQL 查询
	err := session.Table("class").Where("leader = ?", leaderID).Find(&classs)
	if err != nil {
		return nil, false, err
	}

	return classs, true, nil

}

func QueryClassByLeader2(leaderID int64) ([]Class, bool, error) {
	var classs []Class

	// 使用 SQL 查询
	err := datasource.Engine.Table("class").Where("leader = ?", leaderID).Find(&classs)
	if err != nil {
		return nil, false, err
	}

	return classs, true, nil

}

// 根据学校编号删除班级信息
func DeleteSchoolAndClasses(schoolNo string) error {
	// 开启事务
	session := datasource.Engine.NewSession()
	defer session.Close()
	if err := session.Begin(); err != nil {
		return err
	}

	// 删除班级信息
	if _, err := session.Where("school_no = ?", schoolNo).Delete(&Class{}); err != nil {
		session.Rollback()
		return err
	}

	// 删除学校信息
	if _, err := session.Where("school_no = ?", schoolNo).Delete(&School{}); err != nil {
		session.Rollback()
		return err
	}

	// 提交事务
	if err := session.Commit(); err != nil {
		return err
	}

	return nil
}

// 判断学校是否允许查看MHT测量结果
func IsAllowOb(schoolNo string) (bool, error) {
	var school School
	has, err := datasource.Engine.Where("school_no = ?", schoolNo).Get(&school)
	if err != nil {
		return false, err
	}
	if !has {
		return false, fmt.Errorf("school not found with schoolNo: %s", schoolNo)
	}

	if school.AllowOb == "" {
		// 如果字段为空，默认不允许查看
		return false, nil
	}

	var allowObMap map[string]bool
	err = json.Unmarshal([]byte(school.AllowOb), &allowObMap)
	if err != nil {
		// 如果无法解析JSON，默认不允许查看
		return false, nil
	}

	return allowObMap["AllowOb"], nil
}
