package dao

import (
	"errors"
	"micro-bundle/internal/model"
	"micro-bundle/pb/bundle"
	"micro-bundle/pkg/app"
	"micro-bundle/pkg/utils"
	"strconv"
	"time"

	"github.com/duke-git/lancet/v2/datetime"

	"gorm.io/gorm"
)

func AddBundleExtendRecord(data model.BundleExtensionRecords) error {
	return app.ModuleClients.BundleDB.Transaction(func(tx *gorm.DB) error {
		if err := tx.Create(&data).Error; err != nil {
			return err
		}
		if data.AvailableDurationAdditional != 0 && data.TimeUnit != 0 {
			record := model.BundleOrderRecords{}
			if err := tx.Model(&model.BundleOrderRecords{}).Where(&model.BundleOrderRecords{CustomerID: strconv.Itoa(data.UserId)}).First(&record).Error; err != nil {
				return err
			}

			expireTime, err := time.Parse(time.DateOnly, record.ExpirationTime)
			if err != nil {
				return err
			}
			switch data.TimeUnit {
			case 1:
				expireTime = datetime.AddDay(expireTime, int64(data.AvailableDurationAdditional))
			case 2:
				expireTime = datetime.AddMonth(expireTime, int64(data.AvailableDurationAdditional))
			case 3:
				expireTime = datetime.AddYear(expireTime, int64(data.AvailableDurationAdditional))
			default:
				return errors.New("时间单位有误")
			}
			record.ExpirationTime = expireTime.Format(time.DateOnly)
			err = tx.Model(&model.BundleOrderRecords{}).Save(&record).Error
			return err
		}
		return nil
	})
}

func GetBundleExtendRecordList(req *bundle.BundleExtendRecordsListRequest) (data []model.BundleExtendRecordItemPo, total int64, err error) {
	session := app.ModuleClients.BundleDB.Table("fiee_bundle.bundle_extension_records AS ber").
		Select(`
			ber.*,
			u.nickname as user_name,
			u.tel_num as user_phone_number
	`).Joins("LEFT JOIN `micro-account`.`user` u on u.id = user_id")
	if req.User != "" {
		if utils.IsPhoneNumber(req.User) {
			session = session.Where("u.tel_num = ?", req.User)
		} else {
			session = session.Where("u.nickname like ?", req.User)
		}
	}
	if req.Operator != "" {
		if utils.IsPhoneNumber(req.Operator) {
			session = session.Where("ber.operator_phone_number = ?", req.Operator)
		} else {
			session = session.Where("ber.operator_name like ?", req.Operator)
		}
	}
	if req.Type != 0 {
		session = session.Where("ber.`type` = ?", req.Type)
	}
	if req.AssociatedOrderNumber != "" {
		session = session.Where("ber.associated_order_number like ?", "%"+req.AssociatedOrderNumber+"%")
	}
	if err = session.Count(&total).Error; err != nil {
		return
	}

	if req.Page != 0 && req.PageSize != 0 {
		session = session.Limit(int(req.PageSize)).Offset(int(req.Page-1) * int(req.PageSize))
	}
	err = session.Find(&data).Error
	return
}

func GetBundleBalanceList(req *bundle.GetBundleBalanceListReq) (data []model.BundleBalancePo, total int64, err error) {
	session := app.ModuleClients.BundleDB.Table("fiee_bundle.bundle_balance AS bb").
		Select(`
		bb .*,
		bor.expiration_time as expired_time,
		bor.bundle_name,
		bor.status,
		bor.uuid as order_uuid,
		u.nickname as user_name,
		u.tel_num as user_phone_number
	`).
		Joins("LEFT JOIN bundle_order_records bor on bor.customer_id = bb .user_id").
		Joins("LEFT JOIN `micro-account`.`user` u on u.id = bb.user_id")
	if req.UserName != "" {
		session = session.Where("u.nickname like ?", "%"+req.UserName+"%")
	}
	if req.Status != 0 {
		session = session.Where("bor.status = ?", req.Status)
	}
	if req.ExpiredTimeEnd != 0 {
		session = session.Where("bor.expiration_time <= ?", time.UnixMilli(req.ExpiredTimeEnd))
	}
	if req.ExpiredTimeStart != 0 {
		session = session.Where("bor.expiration_time >= ?", time.UnixMilli(req.ExpiredTimeStart))
	}
	err = session.Count(&total).Error
	if err != nil {
		return
	}
	if req.Page != 0 && req.PageSize != 0 {
		session = session.Limit(int(req.PageSize)).Offset(int(req.Page-1) * int(req.PageSize))
	}
	err = session.Find(&data).Error
	return
}

func AddBundleBalanceByUserId(data model.BundleBalance) error {
	return app.ModuleClients.BundleDB.Transaction(func(tx *gorm.DB) error {
		oldData := model.BundleBalance{}
		if err := tx.Model(&model.BundleBalance{}).Where("user_id = ?", data.UserId).Order("created_at desc").First(&oldData).Error; err != nil {
			return errors.New("用户还没有套餐信息")
		}
		newData := model.BundleBalance{
			Model: gorm.Model{
				ID: data.Model.ID,
			},
			UserId:                        oldData.UserId,
			OrderUUID:                     oldData.OrderUUID,
			AccountNumber:                 oldData.AccountNumber + data.AccountNumber,
			AccountConsumptionNumber:      oldData.AccountConsumptionNumber + data.AccountConsumptionNumber,
			VideoNumber:                   oldData.VideoNumber + data.VideoNumber,
			VideoConsumptionNumber:        oldData.VideoConsumptionNumber + data.VideoConsumptionNumber,
			ImageNumber:                   oldData.ImageNumber + data.ImageNumber,
			ImageConsumptionNumber:        oldData.ImageConsumptionNumber + data.ImageConsumptionNumber,
			DataAnalysisNumber:            oldData.DataAnalysisNumber + data.DataAnalysisNumber,
			DataAnalysisConsumptionNumber: oldData.DataAnalysisConsumptionNumber + data.DataAnalysisConsumptionNumber,
			ExpansionPacksNumber:          oldData.ExpansionPacksNumber + data.ExpansionPacksNumber,
		}

		if newData.AccountConsumptionNumber > newData.AccountNumber ||
			newData.VideoConsumptionNumber > newData.VideoNumber ||
			newData.ImageConsumptionNumber > newData.ImageNumber ||
			newData.DataAnalysisConsumptionNumber > newData.DataAnalysisNumber {
			return errors.New("套餐余量不足")
		}
		return tx.Model(&model.BundleBalance{}).Where("id = ?", oldData.ID).Updates(&newData).Error
	})
}

func CreateBundleBalance(data model.BundleBalance) error {
	return app.ModuleClients.BundleDB.Create(&data).Error
}

func GetUsedRecord(req *bundle.GetUsedRecordListReq) (data []model.CostLog, total int64, err error) {
	session := app.ModuleClients.BundleDB.Model(&model.CostLog{})
	if req.Title != "" {
		session = session.Where("title = ?", req.Title)
	}
	if req.Platform != 0 {
		session = session.Where("JSON_CONTAINS(platform_ids,?)", req.Platform)
	}
	if req.Account != 0 {
		session = session.Where("JSON_CONTAINS(media_names,?)", req.Account)
	}
	if req.SubmitTimeEnd != 0 {
		session = session.Where("submit_time <= ?", time.UnixMilli(req.SubmitTimeEnd))
	}
	if req.SubmitTimeStart != 0 {
		session = session.Where("submit_time >= ?", time.UnixMilli(req.SubmitTimeStart))
	}
	if req.User != "" {
		if utils.IsPhoneNumber(req.User) {
			session = session.Where("artist_phone = ?", req.User)
		} else {
			session = session.Where("artist_name like ?", "%"+req.User+"%")
		}
	}
	if req.Operator != "" {
		if utils.IsPhoneNumber(req.Operator) {
			session = session.Where("operator_phone = ?", req.Operator)
		} else {
			session = session.Where("operator_name like ?", "%"+req.Operator+"%")
		}
	}
	if req.Type != 0 {
		session = session.Where("work_category = ?", req.Type)
	}
	if err = session.Count(&total).Error; err != nil {
		return
	}
	if req.Page != 0 && req.PageSize != 0 {
		session = session.Offset(int(req.Page-1) * int(req.PageSize)).Limit(int(req.PageSize))
	}
	err = session.Find(&data).Error
	return
}

func GetImageWorkDetail(req *bundle.GetImageWorkDetailReq) (data model.CastWorkImage, err error) {
	err = app.ModuleClients.BundleDB.Where(&model.CastWorkImage{WorkUuid: req.WorkId}).First(&data).Error
	return
}

func GetVedioWorkDetail(req *bundle.GetVedioWorkDetailReq) (data model.CastWorkVideo, err error) {
	err = app.ModuleClients.BundleDB.Where(&model.CastWorkVideo{WorkUuid: req.WorkId}).First(&data).Error
	return
}

// func ToBeComfirmedWorks(req *bundle.ToBeComfirmedWorksReq) (data []model.CastWork, err error) {
// 	// app.ModuleClients.BundleDB.Where(&model.CastWork{
// 	// 	ArtistUuid: req.ArtistUuid,
// 	// })
// }