package orm

import (
	"errors"

	"github.com/jinzhu/gorm"
)

var (
	selectClassActivities = "SELECT * FROM activities WHERE class_id=?"

	selectUniqueClassTeachers = `
SELECT teachers.* FROM activities
INNER JOIN teachers on teachers.id=activities.teacher_id
WHERE class_id=?
`
)

type Class struct {
	gorm.Model
	Name          string
	CoordinatorID uint `schema:"coordinator_id"`
	MinuterID     uint `schema:"minuter_id"`
	Coordinator   Teacher
	Minuter       Teacher
	Teachers      []*Teacher
	Activities    []*Activity
	Students      []*Student
}

func GetClasses() ([]*Class, error) {
	var classes []*Class
	if err := DB().Order("name").Find(&classes).Error; err != nil {
		return nil, err
	}
	return classes, nil
}

func (c *Class) GetTeachers() ([]*Teacher, error) {
	if err := DB().Raw(selectUniqueClassTeachers, c.ID).Scan(&c.Teachers).Error; err != nil {
		return nil, err
	}
	return c.Teachers, nil
}

func GetClassesAll() ([]*Class, error) {
	var classes []*Class
	if err := DB().Order("name").Find(&classes).Error; err != nil {
		return nil, err
	}
	for _, class := range classes {
		class.GetTeachers()
	}
	return classes, nil
}

func GetClass(id string) (*Class, error) {
	var class Class

	if err := DB().First(&class, id).Error; err != nil {
		return nil, err
	}

	if err := DB().Raw(selectUniqueClassTeachers, id).Scan(&class.Teachers).Error; err != nil {
		return nil, err
	}
	if err := DB().Preload("Teacher").Preload("Class").Preload("Subject").Where("class_id=?", id).Find(&class.Activities).Error; err != nil {
		return nil, err
	}

	if class.CoordinatorID != 0 {
		if !DB().First(&class.Coordinator, class.CoordinatorID).RecordNotFound() {
			if err := DB().First(&class.Coordinator, class.CoordinatorID).Error; err != nil {
				return nil, err
			}
		}
	}

	if class.MinuterID != 0 {
		if !DB().First(&class.Minuter, class.MinuterID).RecordNotFound() {
			if err := DB().First(&class.Minuter, class.MinuterID).Error; err != nil {
				return nil, err
			}
		}
	}

	return &class, nil
}

func (t *Class) Create(db *gorm.DB, record map[string]interface{}) error {
	result := new(Class)

	if name := record["name"]; name == nil {
		return errors.New("Error in creating class: field name is empty")
	} else {
		result.Name = name.(string)
	}

	db.Create(result)

	return nil
}
