package service

import (
	"encoding/json"
	"fmt"
	"iot_manager_service/app/multimedia/dao"
	"iot_manager_service/app/multimedia/model"
	"iot_manager_service/app/system/service"
	"iot_manager_service/util/common"
	"iot_manager_service/util/logger"
	"strconv"
	"strings"
	"time"
)

var PublishLibrariesService = new(publishLibrariesService)

type publishLibrariesService struct{}

/**
TODO: 此接口都未对接边缘端
*/

func (s *publishLibrariesService) List(tenantId string, searchValue string, current, size int, sysType int) ([]dao.PublishLibraries, int64,
	*common.Errors) {
	program := &dao.PublishLibraries{
		TenantId: tenantId,
		SysType:  sysType,
	}
	offset := (current - 1) * size
	limit := size
	if searchValue != "" {
		program.Name = searchValue
	}
	list, total, err := program.GetList(offset, limit)
	if err != nil {
		return nil, 0, common.FailResponse(err.Error(), nil)
	}
	return list, total, nil
}

// Audit 素材发布
func (s *publishLibrariesService) Audit(req model.ReqProgramAudit) error {
	if !common.MultimediaEfficacyTime(req.StartTime, req.EndTime, req.KsTime) {
		panic("任务时间已过，请重新定义时间。")
	}
	program := dao.Program{ID: req.ProgramLibrariesId}
	err := program.Get()
	if err != nil {
		return err
	}
	update := PublishLibrariesService.Create(&program, req)
	fmt.Printf("update = %v", update)

	return nil
}

// SaveOrUpdate 保存
func (s *publishLibrariesService) Create(program *dao.Program, req model.ReqProgramAudit) *common.Errors {
	fmt.Printf("program = %v", program)
	remarks := "多媒体系统"
	if program.SysType == 1 {
		remarks = "广播系统"
	}
	infoIds := req.InfoId
	infoIds = strings.Trim(infoIds, ",")
	infoIds = strings.ReplaceAll(infoIds, "-1", "")
	infoIds = strings.ReplaceAll(infoIds, ",-1", "") //新id
	libraries := &dao.PublishLibraries{
		Name:             program.Name,
		Resolution:       program.Resolution,
		Duration:         program.Duration,
		FileSize:         program.FileSize,
		InfoId:           infoIds,
		ImgDuration:      program.ImgDuration,
		StartTime:        req.StartTime,
		EndTime:          req.EndTime,
		NotificationType: "0",
		CreateTime:       time.Now(),
		CreateUser:       program.CreateUser,
		CreateName:       "",
		UpdateTime:       time.Now(),
		UpdateUser:       "",
		IsDeleted:        0,
		Status:           1,
		TenantId:         program.TenantId,
		Remarks:          remarks,
		SysType:          program.SysType,
		KsTime:           req.KsTime,
		JsTime:           req.JsTime,
		FileId:           program.ID,
		PlayTime:         req.PlayTime,
		PlayInterval:     req.PlayInterval,
	}
	libraries.CreateTime = time.Now()
	if err := libraries.Create(); err != nil {
		logger.Logger.Errorf("Create err = %s \n", err.Error())
		return common.FailResponse(err.Error(), nil)
	}
	fmt.Printf("libraries = %v", libraries)
	//TODO: 日志保存
	return common.SuccessResponse(common.Succeeded, nil)
}

// GetProgram 取节目
func (s *publishLibrariesService) GetProgram(id int) (int, error) {
	libraries := dao.PublishLibraries{ID: int64(id)}
	program, err := libraries.GetProgram()
	return program, err
}

func (s *publishLibrariesService) putPublishLibraries(programId int, publishLibraries dao.PublishLibraries) {

}

// UpdateStatus 状态变更
func (s *publishLibrariesService) UpdateStatus(tenantId string, id int, status int, name string) (bool, error) {
	update := &dao.PublishLibraries{
		TenantId: tenantId,
		ID:       int64(id),
		Status:   status,
		Name:     name,
	}
	err := update.Update()
	if err != nil {
		return false, err
	}
	return true, nil
}

func (s *publishLibrariesService) Remove(userId int64, tenantId string, id int) *common.Errors {
	// 创建查询实例
	device := &dao.PublishLibraries{
		ID:         int64(id),
		IsDeleted:  1,
		UpdateUser: strconv.Itoa(int(userId)),
		UpdateTime: time.Now(),
	}
	err := device.Delete()
	if err != nil {
		return common.FailResponse(err.Error(), nil)
	}
	service.OperationHisService.Save(userId, tenantId, common.OperationRemove, common.DeviceTypeInfoBoard,
		common.DeviceTypeBridge, common.GetDeviceObject(int(device.ID), device.Name), common.OperationSuccess)
	return nil
}

type CltLedLibraries struct {
	Type      string    `json:"type"`      //文件类型 2:图片3:视频5:文本27:网页
	Name      string    `json:"name"`      //节目名字
	Imageinfo Imageinfo `json:"imageinfo"` //图片或视频信息
}
type InEffect struct {
	Type string `json:"Type"` //翻页类型 2
	Time string `json:"Time"` ///翻页花费时间 1000为1秒
}
type Imageinfo struct {
	Urls     []string `json:"urls"`
	Duration string   `json:"duration"`
	InEffect InEffect `json:"inEffect"`
}

// LedPaying 组装当前led屏要播放的节目json
func (s *publishLibrariesService) LedPaying(ledId int, playing string) string {
	libraries := dao.PublishLibraries{}
	librarie, err := libraries.GetProgramByLedId(ledId)
	if err != nil {
		logger.Logger.Errorf("LedPaying err = %v \n", err)
		return ""
	}
	if librarie.ID < 1 {
		//没有新节目不更新
		return ""
	}

	//fmt.Printf("librarie = %v \n", librarie)
	program, _ := s.GetProgram(int(librarie.ID))
	relation := &dao.ProgramRelation{
		ProgramId: program,
		TenantId:  librarie.TenantId,
	}
	relations, err := relation.GetByProgram()
	if err != nil {
		logger.Logger.Errorf("LedPaying err = %s \n", err.Error())
		return ""
	}
	var libraryIds []int
	for _, relation := range relations {
		libraryIds = append(libraryIds, relation.LibraryId)
	}
	//fmt.Printf("libraryIds = %v \n", libraryIds)
	library := &dao.Library{TenantId: librarie.TenantId}
	getLibrariesByIds, _ := library.GetLibrariesByIds(libraryIds)
	if len(getLibrariesByIds) < 1 {
		logger.Logger.Errorf("无素材")
		return ""
	}
	var cltLedLibraries CltLedLibraries
	cltLedLibraries.Name = fmt.Sprintf("%v-%v", librarie.Name, librarie.ID)
	if strings.EqualFold(cltLedLibraries.Name, strings.ReplaceAll(playing, ".vsn", "")) {
		logger.Logger.Errorf("节目相同无需要更新")
		return ""
	}
	cltLedLibraries.Type = "2"
	if strings.Contains(getLibrariesByIds[0].MaterialAddress, "mp4") {
		cltLedLibraries.Type = "3"
	}
	var urls []string
	for _, getLibrariesById := range getLibrariesByIds {
		urls = append(urls, getLibrariesById.MaterialAddress)
	}
	cltLedLibraries.Imageinfo.Duration = strconv.Itoa(int(librarie.Duration))
	cltLedLibraries.Imageinfo.Urls = urls
	cltLedLibraries.Imageinfo.InEffect.Type = "2"
	//cltLedLibraries.Imageinfo.InEffect.Time = strconv.Itoa(relations[0].Duration)
	cltLedLibraries.Imageinfo.InEffect.Time = "1500"
	fmt.Printf("cltLedLibraries = %v \n", cltLedLibraries)
	marshal, err := json.Marshal(cltLedLibraries)
	if err != nil {
		fmt.Printf("LedPaying err = %v \n", err)
		return ""
	}
	fmt.Printf("cltLedLibraries = %v \n", string(marshal))

	str := string(marshal)
	//fmt.Printf("str = %v \n", str)
	return str
}

type iPCastPayingMp3Info struct {
	Type      int   `json:"Type"`
	PlayTimes int   `json:"PlayTimes"`
	FileIds   []int `json:"FileIds"`
	TermIds   []int `json:"TermIds"`
}

type iPCastPayingContentInfo struct {
	Content    string `json:"Content"`
	Playtime   int    `json:"Playtime"`
	TermIds    []int  `json:"TermIds"`
	PlayVol    int    `json:"PlayVol"`
	PromptTone int    `json:"PromptTone"`
}

func (s *publishLibrariesService) IPCastPaying(id int) (string, int) {
	publishLibraries := dao.PublishLibraries{}
	libraries, err := publishLibraries.GetProgramByIpCastId(id)
	if err != nil {
		logger.Logger.Errorf("IPCastPaying err = %v \n", err)
		return "", 0
	}
	if len(libraries) < 1 {
		//没有新节目不更新
		return "", 0
	}
	//fmt.Printf("libraries = %v \n", libraries)
	var librarie dao.PublishLibraries
	//判断当前到底要放哪个节目
	for _, library := range libraries {
		library.Ptype = 1
		if library.JsTime == "" {
			library.Ptype = 0
		}
		if library.Ptype == 1 && library.JsTime != "" {
			currTime := time.Now()
			parse, err := time.Parse("2006-01-02 15:04", fmt.Sprintf("%v %v", time.Now().Format("2006-01-02"), library.JsTime))
			if err != nil {
				fmt.Printf("IPCastPaying parse err = %v \n", err)
				logger.Logger.Errorf("IPCastPaying parse err = %v \n", err)
				continue
			}
			if parse.Before(currTime) {
				continue
			}

		} else {
			cTime := time.Now()
			kTime, err := time.Parse("2006-01-02 15:04", fmt.Sprintf("%v %v", time.Now().Format("2006-01-02"), library.KsTime))
			if err != nil {
				fmt.Printf("IPCastPaying kTime err = %v \n", err)
				logger.Logger.Errorf("IPCastPaying kTime err = %v \n", err)
			}
			//这里要作限制 ，只有是当前时分 才操作
			if cTime.Minute() != kTime.Minute() || cTime.Hour() == kTime.Hour() {
				continue
			}
		}
		librarie = library
	}
	//fmt.Printf("librarie = %v \n", librarie)
	program, _ := s.GetProgram(int(librarie.ID))
	relation := &dao.ProgramRelation{
		ProgramId: program,
		TenantId:  librarie.TenantId,
	}
	relations, err := relation.GetByProgram()
	if err != nil {
		logger.Logger.Errorf("IPCastPaying err = %s \n", err)
		return "", 0
	}
	var libraryIds []int
	for _, relation := range relations {
		libraryIds = append(libraryIds, relation.LibraryId)
	}
	library := &dao.Library{TenantId: librarie.TenantId}
	getLibrariesByIds, _ := library.GetLibrariesByIds(libraryIds)
	if len(getLibrariesByIds) < 1 {
		logger.Logger.Errorf("无素材")
		return "", 0
	}
	//fmt.Printf("getLibrariesByIds = %v \n", getLibrariesByIds)
	// 音频播放
	if librarie.Ptype == 1 {
		paytime := diffTime(librarie.KsTime, librarie.JsTime)
		if paytime < 0 {
			//logger.Logger.Errorf("过了播放结束时间啦 ")
			return "", 0
		}
		fileIds := []int{}
		for _, libs := range getLibrariesByIds {
			fid, _ := strconv.Atoi(libs.FileId)
			fileIds = append(fileIds, fid)
		}
		info := iPCastPayingMp3Info{
			Type:      1,
			PlayTimes: paytime,
			FileIds:   fileIds,
			TermIds:   []int{1, 2, 3, 4, 5, 6, 7, 8},
		}
		marshal, err := json.Marshal(info)
		if err != nil {
			logger.Logger.Errorf("IPCastPaying iPCastPayingMp3Info err = %v \n", err)
			return "", 0
		}
		return string(marshal), librarie.Ptype
		//文字播放
	} else {
		contentInfo := iPCastPayingContentInfo{
			Content:    getLibrariesByIds[0].MaterialAddress,
			Playtime:   librarie.PlayTime,
			TermIds:    []int{1, 2, 3, 4, 5, 6, 7, 8},
			PlayVol:    50,
			PromptTone: librarie.PlayInterval,
		}
		marshal, err := json.Marshal(contentInfo)
		if err != nil {
			logger.Logger.Errorf("IPCastPaying contentInfo err = %v \n", err)
			return "", 0
		}
		return string(marshal), librarie.Ptype
	}
}

// 计算还有多久结束
func diffTime(stime, etime string) int {
	//stimeT, err := time.Parse("2006-01-02 15:04", fmt.Sprintf("%v %v", time.Now().Format("2006-01-02"), stime))
	stimeT, err := time.Parse("2006-01-02 15:04", fmt.Sprintf("%v", time.Now().Format("2006-01-02 15:04")))
	if err != nil {
		return -1
	}
	etimeT, err2 := time.Parse("2006-01-02 15:04", fmt.Sprintf("%v %v", time.Now().Format("2006-01-02"), etime))
	if err2 != nil {
		return -1
	}
	diff := int(etimeT.Sub(stimeT).Seconds())
	return diff
}
