package course

import (
	"errors"
	"spaceofcheng/services/models"
	"spaceofcheng/services/models/model"
	"spaceofcheng/services/utils"
	"strconv"
	"strings"
	"time"

	"github.com/yl10/kit/guid"

	"github.com/go-xorm/xorm"
)

// CourseDAO 当前数据库操作对象
type CourseDAO struct {
	ctx *utils.Context
	db  *xorm.Session
}

// NewCourseDAO New Inst
func NewCourseDAO(ctx *utils.Context) *CourseDAO {
	return &CourseDAO{
		ctx: ctx,
		db:  ctx.DB,
	}
}

const (
	STATUS_UNPUBLISH = 0
	IS_SELECT        = 1
)

// CourseInfo 课程
type CourseInfo struct {
	model.TaCourse `xorm:"extends"`
	CourseType     string
}

// GetCourseList 获取课程列表
func (m *CourseDAO) GetCourseList(caseids, name, typeid string, page, pageSize int) ([]CourseInfo, error) {
	var courses []CourseInfo
	sql := `select a.*,b.location_name from ta_course a left join td_cms_image_location b on a.location_id = b.location_id where a.case_id in ('` +
		strings.Replace(caseids, ",", "','", -1) + `') and a.status>` + strconv.Itoa(models.STATUS_DEL)

	if name != "" {
		sql += ` and a.course_name like '%` + name + `%'`
	}

	if typeid != "" {
		sql += ` and a.location_id='` + typeid + `'`
	}

	sql += ` order by create_date desc limit ` + strconv.Itoa((page-1)*pageSize) + `, ` + strconv.Itoa(page*pageSize)
	err := m.db.Sql(sql).Find(&courses)
	return courses, err
}

// GetCourseCount 获取课程总数
func (m *CourseDAO) GetCourseCount(caseids, name, typeid string) (int, error) {
	var course []model.TaCourse
	dao := m.db.Where("case_id in ('" + strings.Replace(caseids, ",", "','", -1) + "')").And("status>" + strconv.Itoa(models.STATUS_DEL))

	if name != "" {
		dao.And("course_name like '%" + name + "%'")
	}

	if typeid != "" {
		dao.And("location_id=?", typeid)
	}
	err := dao.Find(&course)
	if err != nil {
		return 0, err
	}
	if len(course) > 0 {
		return len(course), nil
	}
	return 0, nil
}

// GetCourseByID 根据ID获取课程
func (m *CourseDAO) GetCourseByID(courseid string) (*model.TaCourse, error) {
	var course []model.TaCourse
	err := m.db.Where("course_id=?", courseid).Find(&course)
	if err != nil {
		return nil, err
	}
	if len(course) > 0 {
		return &course[0], nil
	}
	return nil, nil
}

// AddCourse 新增课程信息
func (m *CourseDAO) AddCourse(course model.TaCourse) (*model.TaCourse, error) {
	course.CourseId = utils.GetGUID()
	course.CreateDate = time.Now()
	course.Status = STATUS_UNPUBLISH
	user := m.ctx.Get("user").(model.SysUser)
	course.CreateUser = user.UserId
	_, err := m.db.Insert(course)
	return &course, err
}

// UpdateCourse 修改课程信息
func (m *CourseDAO) UpdateCourse(course model.TaCourse) error {
	var cols = []string{
		"course_name",
		"price",
		"case_id",
		"location_id",
		"course_num",
		"max_num",
		"min_num",
		"begin_date",
		"end_date",
		"course_img",
		"course_desc",
		"remark",
		"is_select",
	}
	_, err := m.db.Cols(cols...).Where("course_id=?", course.CourseId).Update(course)
	return err
}

// DelCourse 删除课程信息
func (m *CourseDAO) DelCourse(courseid string) error {
	var info = model.TaCourse{
		CourseId: courseid,
		Status:   models.STATUS_DEL,
	}
	var cols = []string{
		"status",
	}
	_, err := m.db.Cols(cols...).Where("course_id=?", courseid).Update(info)
	return err
}

// CoursePublic 课程发布
func (m *CourseDAO) CoursePublic(courseid string) error {
	var info = model.TaCourse{
		CourseId: courseid,
		Status:   models.STATUS_NORMAL,
	}
	var cols = []string{
		"status",
	}
	_, err := m.db.Cols(cols...).Where("course_id=?", courseid).Update(info)
	return err
}

// CourseUnPublic 取消课程发布
func (m *CourseDAO) CourseUnPublic(courseid string) error {
	var info = model.TaCourse{
		CourseId: courseid,
		Status:   STATUS_UNPUBLISH,
	}
	var cols = []string{
		"status",
	}
	_, err := m.db.Cols(cols...).Where("course_id=?", courseid).Update(info)
	return err
}

// GetCourseImgs 获取课程图片
func (m *CourseDAO) GetCourseImgs(courseid string) ([]model.TaCourseImg, error) {
	var imgs []model.TaCourseImg
	err := m.db.Where("course_id=?", courseid).Find(&imgs)
	return imgs, err
}

// AddCourseImg 新增课程图片
func (m *CourseDAO) AddCourseImg(courseimg model.TaCourseImg) (*model.TaCourseImg, error) {
	courseimg.ImgId = utils.GetGUID()
	_, err := m.db.Insert(courseimg)
	return &courseimg, err
}

// UpdateCourseImg 修改课程图片
func (m *CourseDAO) UpdateCourseImg(courseimg model.TaCourseImg) error {
	var cols = []string{
		"sort",
	}
	_, err := m.db.Cols(cols...).Where("img_id=?", courseimg.ImgId).Update(courseimg)
	return err
}

// DelCourseImg 删除课程图片
func (m *CourseDAO) DelCourseImg(imgid string) error {
	sql := `delete from ta_course_img where img_id='` + imgid + `'`
	_, err := m.db.Exec(sql)
	return err
}

// CourseDetail 课程详情
type CourseDetail struct {
	model.TaCourse `xorm:"extends"`
	CourseTags     []model.TaCourseTag
	CourseImgs     []model.TaCourseImg
	CourseDetail   []model.TaCourseDetail
	CaseInfo       *model.SysCase
}

// GetCourseInfo 获取课程详情
func (m *CourseDAO) GetCourseInfo(courseid string) (*CourseDetail, error) {
	var courses []CourseDetail
	sql := `select * from ta_course where course_id='` + courseid + `'`
	err := m.db.Sql(sql).Find(&courses)
	if err != nil {
		return nil, err
	}
	if len(courses) > 0 {
		return &courses[0], nil
	}
	return nil, nil
}

// GetCourseDetail 获取课程明细
func (m *CourseDAO) GetCourseDetail(courseid string) ([]model.TaCourseDetail, error) {
	var details []model.TaCourseDetail
	err := m.db.Where("course_id=?", courseid).And("status>" + strconv.Itoa(models.STATUS_DEL)).Find(&details)
	return details, err
}

// GetDetails 获取所有的排课记录
func (m *CourseDAO) GetDetails(caseid, date string) ([]model.TaCourseDetail, error) {
	var details []model.TaCourseDetail
	err := m.db.Where("status>"+strconv.Itoa(models.STATUS_DEL)).And("DATE_FORMAT(begin_date,'%Y-%m') = ?", date).Find(&details)
	return details, err
}

// GetCourseSchedule 获取需要排课的记录
func (m *CourseDAO) GetCourseSchedule(name, caseids, date string, page, pageSize int) ([]model.TaCourse, error) {
	var courses []model.TaCourse
	dao := m.db.Where("status=?", STATUS_UNPUBLISH).And("schedule_num<course_num").And(date + " BETWEEN begin_date and end_date")
	if name != "" {
		dao.And("course_name like '%" + name + "%'")
	}
	if caseids != "" {
		dao.And("caseids in ('" + strings.Replace(caseids, ",", "','", -1) + "')")
	}
	err := dao.OrderBy("create_date").Limit(pageSize, (page-1)*pageSize).Find(&courses)
	return courses, err
}

// GetCourseScheduleCount 获取排课记录数
func (m *CourseDAO) GetCourseScheduleCount(name, caseids, date string) (int, error) {
	var courses []model.TaCourse
	dao := m.db.Where("status=?", STATUS_UNPUBLISH).And("schedule_num<course_num").And(date + " BETWEEN begin_date and end_date")
	if name != "" {
		dao.And("course_name like '%" + name + "%'")
	}
	if caseids != "" {
		dao.And("caseids in ('" + strings.Replace(caseids, ",", "','", -1) + "')")
	}
	err := dao.Find(&courses)
	return len(courses), err
}

// GetDetailByID 获取排课明细
func (m *CourseDAO) GetDetailByID(detailid string) (*model.TaCourseDetail, error) {
	var details []model.TaCourseDetail
	err := m.db.Where("detail_id=?", detailid).And("status>" + strconv.Itoa(models.STATUS_DEL)).Find(&details)
	if err != nil {
		return nil, err
	}
	if len(details) > 0 {
		return &details[0], nil
	}
	return nil, nil
}

// AddCourseDetail 新增明细
func (m *CourseDAO) AddCourseDetail(detail model.TaCourseDetail) (*model.TaCourseDetail, error) {
	detail.CreateDate = time.Now()
	detail.Status = models.STATUS_NORMAL
	detail.DetailId = utils.GetGUID()
	_, err := m.db.Insert(detail)
	return &detail, err
}

// UpdateCourseDetail 修改明细
func (m *CourseDAO) UpdateCourseDetail(detail model.TaCourseDetail) error {
	var cols = []string{
		"detail_name",
		"begin_date",
		"end_date",
	}
	_, err := m.db.Cols(cols...).Where("detail_id=?", detail.DetailId).Update(detail)
	return err
}

// DelCourseDetail 刪除明细
func (m *CourseDAO) DelCourseDetail(detailid string) error {
	var info = model.TaCourseDetail{
		DetailId: detailid,
		Status:   models.STATUS_DEL,
	}
	var cols = []string{
		"status",
	}
	_, err := m.db.Cols(cols...).Where("detail_id=?", detailid).Update(info)
	return err
}

// DelCourseTag 删除课程对应标签
func (m *CourseDAO) DelCourseTag(courseid string) error {
	sql := `delete from ta_course_tag where course_id='` + courseid + `'`
	_, err := m.db.Exec(sql)
	return err
}

// SaveCourseTag 保存课程对应标签
func (m *CourseDAO) SaveCourseTag(coursetags []model.TaCourseTag) error {
	_, err := m.db.Insert(coursetags)
	return err
}

// GetCourseTag 获取课程对应标签
func (m *CourseDAO) GetCourseTag(courseid string) ([]model.TaCourseTag, error) {
	var coursetags []model.TaCourseTag
	err := m.db.Where("course_id=?", courseid).Find(&coursetags)
	return coursetags, err
}

// CourseTagSave 保存课程对应标签
func (m *CourseDAO) CourseTagSave(courseid, tagids string) error {
	sql := `insert into ta_course_tag(course_id,tag_id) select '` + courseid + `',tag_id from td_course_tag where tag_id in ('` + strings.Replace(tagids, ",", "','", -1) + `') and status>` + strconv.Itoa(models.STATUS_DEL)
	_, err := m.db.Exec(sql)
	return err
}

// GetCourseDetailCount 获取已排课数量
func (m *CourseDAO) GetCourseDetailCount(courseid string) (int, error) {
	var details []model.TaCourseDetail
	err := m.db.Where("course_id=?", courseid).And("status>" + strconv.Itoa(models.STATUS_DEL)).Find(&details)
	if err != nil {
		return 0, err
	}
	return len(details), nil
}

// UpdateCourseScheduleNum 更新课程已排课数量
func (m *CourseDAO) UpdateCourseScheduleNum(courseid string, num int) error {
	var info = model.TaCourse{
		CourseId:    courseid,
		ScheduleNum: num,
	}
	var cols = []string{
		"schedule_num",
	}
	_, err := m.db.Cols(cols...).Where("course_id=?", courseid).Update(info)
	return err
}

// DeleteScheduleByCourse 删除排课记录
func (m *CourseDAO) DeleteScheduleByCourse(courseid string) error {
	sql := `update ta_course_detail set status=` + strconv.Itoa(models.STATUS_DEL) + ` where course_id='` + courseid + `'`
	_, err := m.db.Exec(sql)
	return err
}

// GetSelectCourseList 获取精选课程
func (m *CourseDAO) GetSelectCourseList(orgid string) ([]CourseDetail, error) {
	var courses []CourseDetail
	sql := `select * from ta_course where is_select=` + strconv.Itoa(IS_SELECT) + ` and status=` + strconv.Itoa(models.STATUS_NORMAL) + ` and org_id='` + orgid + `'`
	err := m.db.Sql(sql).Find(&courses)
	return courses, err
}

// GetCourseByLocation 根据位置获取课程信息
func (m *CourseDAO) GetCourseByLocation(orgid, locationid string) ([]CourseDetail, error) {
	var courses []CourseDetail
	sql := `select * from ta_course where status=` + strconv.Itoa(models.STATUS_NORMAL) + ` and org_id='` + orgid + `' and location_id ='` + locationid + `'`
	err := m.db.Sql(sql).Find(&courses)
	return courses, err
}

// GetCourseOfCustomer 获取客户课程
func (m *CourseDAO) GetCourseOfCustomer(custID, courseID string) (*model.TaCustomerCourse, error) {
	course := new(model.TaCustomerCourse)

	if _, err := m.db.Where("course_id=?", courseID).And("customer_id=?", custID).Get(course); err != nil {
		return nil, err
	}

	return course, nil
}

// SaveCourseOfCustomer 保存我的课程
func (m *CourseDAO) SaveCourseOfCustomer(course *model.TaCustomerCourse, details []model.TaCustomerCourseDetail) error {
	if course == nil || details == nil || len(details) == 0 {
		return errors.New("没有有效的我的课程信息")
	}

	course.CustomerCourseId = guid.NewGUIDString()
	course.Status = models.STATUS_NORMAL

	for i, d := range details {
		d.CustomerDetailId = guid.NewGUIDString()
		d.CustomerCourseId = course.CustomerCourseId
		d.Status = models.STATUS_NORMAL

		details[i] = d
	}

	if _, err := m.db.Insert(&details); err != nil {
		return err
	}

	if _, err := m.db.Insert(course); err != nil {
		return err
	}

	return nil
}
