package yb

import (
	"encoding/json"
	"fmt"
	"github.com/rdlucklib/rdluck_tools/paging"
	"hongze/hz_crm_api/controllers"
	"hongze/hz_crm_api/models"
	"hongze/hz_crm_api/models/yb"
	"hongze/hz_crm_api/services"
	"hongze/hz_crm_api/services/alarm_msg"
	"hongze/hz_crm_api/utils"
	"os"
	"path"
	"strings"
	"time"
)

// PdfController 报告PDF
type PdfController struct {
	controllers.BaseAuthController
}

// Add
// @Title 新增PDF
// @Description 新增PDF
// @Param	request	body yb.PdfAddReq true "type json string"
// @Success 200 Ret=200 操作成功
// @router /pdf/add [post]
func (this *PdfController) Add() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	var req yb.PdfAddReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}
	req.PdfName = strings.TrimSpace(req.PdfName)
	if req.PdfName == "" {
		br.Msg = "请输入PDF名称"
		return
	}
	nameRune := []rune(req.PdfName)
	if len(nameRune) > 30 {
		br.Msg = "名称不得超过30个字符"
		return
	}
	req.OriginName = strings.TrimSpace(req.OriginName)
	if req.OriginName == "" {
		br.Msg = "文件名称有误"
		return
	}

	// 重名校验
	existItem := new(yb.Pdf)
	existCond := fmt.Sprintf(` AND %s = ? `, yb.PdfColumns.PdfName)
	existPars := make([]interface{}, 0)
	existPars = append(existPars, req.PdfName)
	if e := existItem.GetItemByCondition(existCond, existPars); e != nil && e.Error() != utils.ErrNoRow() {
		br.Msg = "操作失败"
		br.ErrMsg = "获取重名PDF失败, Err: " + e.Error()
		return
	}
	if existItem != nil && existItem.PdfId > 0 {
		br.Msg = "该PDF已存在"
		return
	}

	nowTime := time.Now().Local()
	newItem := &yb.Pdf{
		PdfName:      req.PdfName,
		PdfUrl:       req.PdfUrl,
		OriginName:   req.OriginName,
		SysAdminId:   sysUser.AdminId,
		SysAdminName: sysUser.RealName,
		CreateTime:   nowTime,
		ModifyTime:   nowTime,
	}
	if e := newItem.Create(); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "新增PDF失败, Err: " + e.Error()
		return
	}

	go func() {
		var err error
		defer func() {
			if err != nil {
				fmt.Println("报告PDF-生成二维码失败: ", err.Error())
				alarm_msg.SendAlarmMsg("报告PDF-生成二维码失败: "+err.Error(), 3)
			}
		}()

		var qrcode string
		page := "pages-report/previewPDF"
		scene := fmt.Sprintf(`{"pdf_id":"%d"}`, newItem.PdfId)
		origin, e := models.GetYbPcSunCode(scene, page)
		if e != nil && e.Error() != utils.ErrNoRow() {
			err = fmt.Errorf("GetYbPcSunCode err: %s", e.Error())
			return
		}
		if origin != nil {
			qrcode = origin.SuncodeUrl
		} else {
			qrcode, e = services.PcCreateAndUploadSunCode(scene, page)
			if e != nil {
				err = fmt.Errorf("PcCreateAndUploadSunCode err: %s", e.Error())
				return
			}
		}
		newItem.ShareUrl = qrcode
		if e = newItem.Update([]string{yb.PdfColumns.ShareUrl}); e != nil {
			err = fmt.Errorf("PDF Update err: %s", e.Error())
			return
		}
	}()

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// Edit
// @Title 编辑PDF
// @Description 编辑PDF
// @Param	request	body yb.PdfEditReq true "type json string"
// @Success 200 Ret=200 操作成功
// @router /pdf/edit [post]
func (this *PdfController) Edit() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	var req yb.PdfEditReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}
	req.PdfName = strings.TrimSpace(req.PdfName)
	if req.PdfName == "" {
		br.Msg = "请输入PDF名称"
		return
	}
	nameRune := []rune(req.PdfName)
	if len(nameRune) > 30 {
		br.Msg = "名称不得超过30个字符"
		return
	}
	req.OriginName = strings.TrimSpace(req.OriginName)
	if req.OriginName == "" {
		br.Msg = "文件名称有误"
		return
	}

	item := new(yb.Pdf)
	if e := item.GetItemById(req.PdfId); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "获取PDF信息失败, Err: " + e.Error()
		return
	}
	if item.PdfId <= 0 {
		br.Msg = "PDF已被删除, 请刷新页面"
		return
	}

	// 重名校验
	existItem := new(yb.Pdf)
	existCond := fmt.Sprintf(` AND %s = ? AND %s <> ? `, yb.PdfColumns.PdfName, yb.PdfColumns.PdfId)
	existPars := make([]interface{}, 0)
	existPars = append(existPars, req.PdfName, req.PdfId)
	if e := existItem.GetItemByCondition(existCond, existPars); e != nil && e.Error() != utils.ErrNoRow() {
		br.Msg = "操作失败"
		br.ErrMsg = "获取重名PDF失败, Err: " + e.Error()
		return
	}
	if existItem != nil && existItem.PdfId > 0 {
		br.Msg = "该PDF已存在"
		return
	}

	item.PdfName = req.PdfName
	item.OriginName = req.OriginName
	item.PdfUrl = req.PdfUrl
	item.ModifyTime = time.Now().Local()
	updateCols := []string{yb.PdfColumns.PdfName, yb.PdfColumns.OriginName, yb.PdfColumns.PdfUrl, yb.PdfColumns.ModifyTime}
	if item.ShareUrl == "" {
		var qrcode string
		page := "pages-report/previewPDF"
		scene := fmt.Sprintf(`{"pdf_id":"%d"}`, item.PdfId)
		origin, e := models.GetYbPcSunCode(scene, page)
		if e != nil && e.Error() != utils.ErrNoRow() {
			br.Msg = "操作失败"
			br.ErrMsg = "获取小程序二维码失败, GetYbPcSunCode: " + e.Error()
			return
		}
		if origin != nil {
			qrcode = origin.SuncodeUrl
		} else {
			qrcode, e = services.PcCreateAndUploadSunCode(scene, page)
			if e != nil {
				br.Msg = "操作失败"
				br.ErrMsg = "生成小程序二维码失败, PcCreateAndUploadSunCode: " + e.Error()
				return
			}
		}
		item.ShareUrl = qrcode
		updateCols = append(updateCols, yb.PdfColumns.ShareUrl)
	}
	if e := item.Update(updateCols); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "PDF编辑失败, Err: " + e.Error()
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// Del
// @Title 删除PDF
// @Description 删除PDF
// @Param	request	body yb.PdfDelReq true "type json string"
// @Success 200 Ret=200 操作成功
// @router /pdf/del [post]
func (this *PdfController) Del() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	var req yb.PdfDelReq
	if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
		br.Msg = "参数解析异常!"
		br.ErrMsg = "参数解析失败,Err:" + e.Error()
		return
	}
	if req.PdfId <= 0 {
		br.Msg = "参数有误"
		return
	}

	item := new(yb.Pdf)
	e := item.GetItemById(req.PdfId)
	if e != nil {
		if e.Error() == utils.ErrNoRow() {
			br.Msg = "PDF已被删除, 请刷新页面"
			return
		}
		br.Msg = "操作失败"
		br.ErrMsg = "获取PDF信息失败, Err: " + e.Error()
		return
	}
	if item.PdfId <= 0 {
		br.Msg = "PDF已被删除, 请刷新页面"
		return
	}
	if e = item.Del(); e != nil {
		br.Msg = "操作失败"
		br.ErrMsg = "删除PDF失败, Err: " + e.Error()
		return
	}

	br.Ret = 200
	br.Success = true
	br.Msg = "操作成功"
}

// PageList
// @Title PDF列表
// @Description PDF列表
// @Param   Keyword  query  string  false  "关键词"
// @Success 200 Ret=200 获取成功
// @router /pdf/page_list [get]
func (this *PdfController) PageList() {
	br := new(models.BaseResponse).Init()
	defer func() {
		if br.ErrMsg == "" {
			br.IsSendEmail = false
		}
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	keyword := this.GetString("Keyword", "")
	startTime := this.GetString("StartTime", "")
	endTime := this.GetString("EndTime", "")
	cond := ``
	pars := make([]interface{}, 0)
	if keyword != "" {
		kw := "%" + keyword + "%"
		cond += fmt.Sprintf(` AND %s LIKE ?`, yb.PdfColumns.PdfName)
		pars = append(pars, kw)
	}
	if startTime != "" && endTime != "" {
		_, e := time.ParseInLocation(utils.FormatDate, startTime, time.Local)
		if e != nil {
			br.Msg = "开始日期格式有误, 格式2006-01-02"
			return
		}
		_, e = time.ParseInLocation(utils.FormatDate, endTime, time.Local)
		if e != nil {
			br.Msg = "结束日期格式有误, 格式2006-01-02"
			return
		}
		st := fmt.Sprint(startTime, " 00:00:00")
		et := fmt.Sprint(endTime, " 23:59:59")
		cond += fmt.Sprintf(` AND (%s BETWEEN ? AND ?)`, yb.PdfColumns.ModifyTime)
		pars = append(pars, st, et)
	}

	var startSize int
	pageSize, _ := this.GetInt("PageSize")
	currentIndex, _ := this.GetInt("CurrentIndex")
	if pageSize <= 0 {
		pageSize = utils.PageSize20
	}
	if currentIndex <= 0 {
		currentIndex = 1
	}
	startSize = paging.StartIndex(currentIndex, pageSize)

	pdfOB := new(yb.Pdf)
	total, list, e := pdfOB.GetPageItemsByCondition(startSize, pageSize, cond, pars, []string{}, "modify_time DESC")
	if e != nil {
		br.Msg = "获取失败"
		br.ErrMsg = "获取PDF列表失败, Err: " + e.Error()
		return
	}

	respList := make([]*yb.PdfItem, 0)
	for i := range list {
		respList = append(respList, &yb.PdfItem{
			PdfId:        list[i].PdfId,
			PdfName:      list[i].PdfName,
			OriginName:   list[i].OriginName,
			PdfUrl:       list[i].PdfUrl,
			ShareUrl:     list[i].ShareUrl,
			SysAdminId:   list[i].SysAdminId,
			SysAdminName: list[i].SysAdminName,
			CreateTime:   list[i].CreateTime.Format(utils.FormatDateTime),
			ModifyTime:   list[i].ModifyTime.Format(utils.FormatDateTime),
		})
	}

	page := paging.GetPaging(currentIndex, pageSize, total)
	resp := &yb.PdfPageListResp{
		Paging: page,
		List:   respList,
	}
	br.Ret = 200
	br.Success = true
	br.Msg = "获取成功"
	br.Data = resp
}

// Upload
// @Title 上传PDF
// @Description 上传PDF
// @Param   File	query  file  true  "PDF文件"
// @Success 200 Ret=200 操作成功
// @router /pdf/upload [post]
func (this *PdfController) Upload() {
	br := new(models.BaseResponse).Init()
	defer func() {
		this.Data["json"] = br
		this.ServeJSON()
	}()
	sysUser := this.SysUser
	if sysUser == nil {
		br.Msg = "请登录"
		br.ErrMsg = "请登录,SysUser Is Empty"
		br.Ret = 408
		return
	}

	f, h, e := this.GetFile("file")
	if e != nil {
		br.Msg = "获取资源信息失败"
		br.ErrMsg = "获取资源信息失败, Err:" + e.Error()
		return
	}
	defer func() {
		_ = f.Close()
	}()
	ext := path.Ext(h.Filename)
	if ext != ".pdf" {
		br.Msg = "请上传pdf文件"
		return
	}

	uploadDir := utils.STATIC_DIR + "hongze/" + time.Now().Format("20060102")
	if e = os.MkdirAll(uploadDir, 766); e != nil {
		br.Msg = "存储目录创建失败"
		br.ErrMsg = "存储目录创建失败, Err:" + e.Error()
		return
	}
	fileName := utils.GetRandStringNoSpecialChar(28) + ext
	filePath := uploadDir + "/" + fileName
	if e = this.SaveToFile("file", filePath); e != nil {
		br.Msg = "文件保存失败"
		br.ErrMsg = "文件保存失败, Err:" + e.Error()
		return
	}
	defer func() {
		_ = os.Remove(filePath)
	}()

	// 上传到阿里云
	ossDir := "static/yb/pdf/"
	pdfUrl, e := services.UploadAliyunToDir(fileName, filePath, ossDir, fmt.Sprint(utils.RunMode, "/"))
	if e != nil {
		br.Msg = "文件上传失败"
		br.ErrMsg = "文件上传失败, Err:" + e.Error()
		return
	}

	br.Msg = "上传成功"
	br.Ret = 200
	br.Success = true
	br.Data = pdfUrl
}