package course

import (
	"spaceofcheng/services/models"
	"spaceofcheng/services/models/cases"
	"spaceofcheng/services/models/course"
	"spaceofcheng/services/models/customer"
	"spaceofcheng/services/models/model"
	"spaceofcheng/services/models/system"
	"spaceofcheng/services/service"
	"spaceofcheng/services/utils"
	"strings"

	"github.com/astaxie/beego"
)

// CourseServ 系统处理
type CourseServ struct {
	ctx     *utils.Context
	dao     *course.CourseDAO
	casedao *cases.CaseDAO
	custDAO *customer.CustomerDAO
	userDAO *system.UserDAO
}

// NewCourseServ 初始化
func NewCourseServ(ctx *utils.Context) *CourseServ {
	return &CourseServ{
		ctx:     ctx,
		dao:     course.NewCourseDAO(ctx),
		casedao: cases.NewCaseDAO(ctx),
		custDAO: customer.NewCustomerDAO(ctx),
		userDAO: system.NewUserDAO(ctx),
	}
}

// GetCourseList 获取课程列表
func (s *CourseServ) GetCourseList(caseids, name, typeid string, page, pageSize int) (map[string]interface{}, error) {
	if pageSize == 0 {
		pageSize = service.PAGENUM
	}
	if page == 0 {
		page = 1
	}
	list, err := s.dao.GetCourseList(caseids, name, typeid, page, pageSize)
	if err != nil {
		beego.Error(err)
		return nil, err
	}
	total, err := s.dao.GetCourseCount(caseids, name, typeid)
	if err != nil {
		beego.Error(err)
		return nil, err
	}

	return map[string]interface{}{
		"list":     list,
		"pagesize": pageSize,
		"pagenum":  total,
		"page":     page,
	}, err
}

// GetCourseByID 获取课程明细
func (s *CourseServ) GetCourseByID(courseid string) (*course.CourseDetail, error) {
	if courseid == "" {
		return nil, utils.LogError("不存在课程信息！")
	}
	info, err := s.dao.GetCourseInfo(courseid)
	if err != nil {
		return nil, err
	}
	if info == nil {
		return nil, utils.LogError("不存在课程信息！")
	}
	if info.Status == models.STATUS_DEL {
		return nil, utils.LogError("课程已被删除！")
	}

	tags, err := s.dao.GetCourseTag(courseid)
	if err != nil {
		return nil, err
	}
	info.CourseTags = tags
	details, err := s.dao.GetCourseDetail(courseid)
	if err != nil {
		return nil, err
	}
	info.CourseDetail = details
	imgs, err := s.dao.GetCourseImgs(courseid)
	if err != nil {
		return nil, err
	}
	info.CourseImgs = imgs
	caseinfo, err := s.casedao.GetCaseByID(info.CaseId)
	if err != nil {
		return nil, err
	}
	info.CaseInfo = caseinfo
	return info, nil
}

// SaveCourse 保存课程信息
func (s *CourseServ) SaveCourse(course model.TaCourse, tagids string) (*model.TaCourse, error) {
	var newInfo *model.TaCourse
	var err error
	if course.CourseName == "" {
		return nil, utils.LogError("课程名称不允许为空！")
	}
	if course.CourseImg == "" {
		return nil, utils.LogError("课程主图不允许为空！")
	}
	if course.LocationId == "" {
		return nil, utils.LogError("课程类型不允许为空！")
	}
	if course.CaseId == "" {
		return nil, utils.LogError("课程案场不允许为空！")
	}
	if course.Price == "" || course.Price == "0" {
		return nil, utils.LogError("课程价格不允许为0！")
	}
	if course.MinNum == 0 {
		return nil, utils.LogError("最小开课人数不允许为0！")
	}
	if course.MaxNum == 0 {
		return nil, utils.LogError("上课人数不允许为0！")
	}
	if course.MaxNum < course.MinNum {
		return nil, utils.LogError("上课人数不允许小于最小开课人数！")
	}
	if course.CourseNum == 0 {
		return nil, utils.LogError("课时数不允许为0！")
	}
	if course.BeginDate.IsZero() || course.EndDate.IsZero() {
		return nil, utils.LogError("课程时间不允许为空！")
	}
	if course.EndDate.After(course.BeginDate) {
		return nil, utils.LogError("截止时间必须大于开始时间！")
	}
	if tagids == "" {
		return nil, utils.LogError("请选择课程标签！")
	}
	if course.CourseId == "" {
		newInfo, err = s.dao.AddCourse(course)
		if err != nil {
			return nil, err
		}
	} else {
		err = s.dao.UpdateCourse(course)
		if err != nil {
			return nil, err
		}
		newInfo = &course
		err = s.dao.DelCourseTag(course.CourseId)
		if err != nil {
			return nil, err
		}
	}

	tags := strings.Split(tagids, ",")
	var courseTags []model.TaCourseTag
	for _, tag := range tags {
		arr := strings.Split(tag, ":")
		var tagid = ""
		if len(arr) > 1 {
			tagid = arr[1]
		} else {
			var taginfo = model.TdCourseTag{
				TagName: arr[0],
				OrgId:   course.OrgId,
			}
			newtag, err := s.dao.AddCourseTag(taginfo)
			if err != nil {
				return nil, err
			}
			tagid = newtag.TagId
		}
		var coursetag = model.TaCourseTag{
			CourseId: course.CourseId,
			TagId:    tagid,
		}
		courseTags = append(courseTags, coursetag)
	}

	if len(courseTags) > 0 {
		err = s.dao.SaveCourseTag(courseTags)
		return nil, err
	}
	return newInfo, nil
}

// DelCourse 刪除课程信息
func (s *CourseServ) DelCourse(courseid string) error {
	if courseid == "" {
		return utils.LogError("没有对应的课程！")
	}
	courseinfo, err := s.dao.GetCourseByID(courseid)
	if err != nil {
		return err
	}
	if courseinfo.Status != course.STATUS_UNPUBLISH {
		return utils.LogError("课程状态异常！不允许删除！")
	}
	err = s.dao.DelCourse(courseid)
	if err != nil {
		return err
	}
	err = s.dao.DeleteScheduleByCourse(courseid)
	return err
}

// CoursePublic 课程发布
func (s *CourseServ) CoursePublic(courseid string) error {
	if courseid == "" {
		return utils.LogError("没有对应的课程！")
	}
	info, err := s.dao.GetCourseByID(courseid)
	if err != nil {
		return err
	}
	if info.Status != course.STATUS_UNPUBLISH {
		return utils.LogError("当前课程状态异常！请刷新后重试！")
	}
	err = s.dao.CoursePublic(courseid)
	return err
}

// CourseUnPublic 课程取消发布
func (s *CourseServ) CourseUnPublic(courseid string) error {
	if courseid == "" {
		return utils.LogError("没有对应的课程！")
	}
	info, err := s.dao.GetCourseByID(courseid)
	if err != nil {
		return err
	}
	if info.Status != models.STATUS_NORMAL {
		return utils.LogError("当前课程状态异常！请刷新后重试！")
	}
	err = s.dao.CourseUnPublic(courseid)
	return err
}

// GetCourseImgs 获取课程图片
func (s *CourseServ) GetCourseImgs(courseid string) ([]model.TaCourseImg, error) {
	if courseid == "" {
		return nil, utils.LogError("没有对应的课程！")
	}
	imgs, err := s.dao.GetCourseImgs(courseid)
	return imgs, err
}

// SaveCourseImg 保存课程图片
func (s *CourseServ) SaveCourseImg(img model.TaCourseImg) (*model.TaCourseImg, error) {
	var newinfo *model.TaCourseImg
	var err error
	if img.ImgUrl == "" {
		return nil, utils.LogError("请先上传图片！")
	}
	if img.ImgId == "" {
		newinfo, err = s.dao.AddCourseImg(img)
	} else {
		newinfo = &img
		err = s.dao.UpdateCourseImg(img)
	}
	return newinfo, err
}

// DelCourseImg 刪除课程图片
func (s *CourseServ) DelCourseImg(imgid string) error {
	if imgid == "" {
		return utils.LogError("没有需要删除的内容！")
	}
	err := s.dao.DelCourseImg(imgid)
	return err
}

// GetCourseSchedule 获取课程排期
func (s *CourseServ) GetCourseSchedule(name, caseids, date string, page, pageSize int) (map[string]interface{}, error) {
	if pageSize == 0 {
		pageSize = service.PAGENUM
	}
	if page == 0 {
		page = 1
	}
	if date == "" {
		return nil, utils.LogError("请先选择需要排课的日期！")
	}
	list, err := s.dao.GetCourseSchedule(name, caseids, date, page, pageSize)
	if err != nil {
		beego.Error(err)
		return nil, err
	}
	total, err := s.dao.GetCourseScheduleCount(name, caseids, date)
	if err != nil {
		beego.Error(err)
		return nil, err
	}

	return map[string]interface{}{
		"list":     list,
		"pagesize": pageSize,
		"pagenum":  total,
		"page":     page,
	}, err
}

// GetDetails 获取所有排课
func (s *CourseServ) GetDetails(caseid, date string) ([]model.TaCourseDetail, error) {
	if caseid == "" {
		return nil, utils.LogError("请先选择案场！")
	}
	if date == "" {
		return nil, utils.LogError("请选择需要查看的月份！")
	}
	details, err := s.dao.GetDetails(caseid, date)
	return details, err
}

// GetDetailByID 获取单个排课信息
func (s *CourseServ) GetDetailByID(detailid string) (*model.TaCourseDetail, error) {
	if detailid == "" {
		return nil, utils.LogError("没有对应的排课信息！")
	}
	detail, err := s.dao.GetDetailByID(detailid)
	return detail, err
}

// SaveDetail 保存排课信息
func (s *CourseServ) SaveDetail(detail model.TaCourseDetail) (*model.TaCourseDetail, error) {
	var newinfo *model.TaCourseDetail
	if detail.CourseId == "" {
		return nil, utils.LogError("没有对应的课程信息！")
	}
	if detail.DetailName == "" {
		return nil, utils.LogError("课程名称不能为空！")
	}
	if detail.BeginDate.IsZero() || detail.EndDate.IsZero() {
		return nil, utils.LogError("课程时间不能为空！")
	}
	if detail.BeginDate.After(detail.EndDate) {
		return nil, utils.LogError("课程截止时间必须大于开始时间！")
	}
	courseinfo, err := s.dao.GetCourseByID(detail.CourseId)
	if err != nil {
		return nil, err
	}
	if courseinfo.Status != course.STATUS_UNPUBLISH {
		return nil, utils.LogError("课程状态异常！不允许排课！请刷新后重试！")
	}
	if detail.DetailId == "" {
		detail.OrgId = courseinfo.OrgId
		detail.CaseId = courseinfo.CaseId
		newinfo, err = s.dao.AddCourseDetail(detail)
		if err != nil {
			return nil, err
		}
		num, err := s.dao.GetCourseDetailCount(courseinfo.CourseId)
		if err != nil {
			return nil, err
		}
		err = s.dao.UpdateCourseScheduleNum(courseinfo.CourseId, num)
		if err != nil {
			return nil, err
		}
	} else {
		err := s.dao.UpdateCourseDetail(detail)
		if err != nil {
			return nil, err
		}
		newinfo = &detail
	}
	return newinfo, nil
}

// DelCourseDetail 删除课程明细
func (s *CourseServ) DelCourseDetail(detailid string) error {
	if detailid == "" {
		return utils.LogError("没有对应的排课信息！")
	}
	detail, err := s.dao.GetDetailByID(detailid)
	if err != nil {
		return err
	}
	courseinfo, err := s.dao.GetCourseByID(detail.CourseId)
	if err != nil {
		return err
	}
	if courseinfo.Status != course.STATUS_UNPUBLISH {
		return utils.LogError("课程状态异常！不允许删除！")
	}
	err = s.dao.DelCourseDetail(detailid)
	if err != nil {
		return err
	}
	num, err := s.dao.GetCourseDetailCount(courseinfo.CourseId)
	if err != nil {
		return err
	}
	err = s.dao.UpdateCourseScheduleNum(courseinfo.CourseId, num)
	if err != nil {
		return err
	}
	return nil
}

// GetCourseBySelect 获取精选课程
func (s *CourseServ) GetSelectCourseList(orgid string) ([]course.CourseDetail, error) {
	if orgid == "" {
		return nil, utils.LogError("参数错误！")
	}
	list, err := s.dao.GetSelectCourseList(orgid)
	if err != nil {
		return nil, err
	}
	for i, v := range list {
		caseinfo, err := s.casedao.GetCaseByID(v.CaseId)
		if err != nil {
			return nil, err
		}
		list[i].CaseInfo = caseinfo
	}
	return list, err
}

// GetCourseByLocation 根据位置获取课程
func (s *CourseServ) GetCourseByLocation(orgid, locationid string) ([]course.CourseDetail, error) {
	if orgid == "" || locationid == "" {
		return nil, utils.LogError("参数错误！")
	}
	list, err := s.dao.GetCourseByLocation(orgid, locationid)
	if err != nil {
		return nil, err
	}
	for i, v := range list {
		caseinfo, err := s.casedao.GetCaseByID(v.CaseId)
		if err != nil {
			return nil, err
		}
		list[i].CaseInfo = caseinfo
	}
	return list, err
}
