package db

import (
	context "context"
	"encoding/json"
	"fmt"
	"time"
	"youngee_b_api/consts"
	"youngee_b_api/model/gorm_model"
	"youngee_b_api/model/http_model"
	"youngee_b_api/util"

	"github.com/issue9/conv"
	"github.com/sirupsen/logrus"
)

func AddReceiveAddress(ctx context.Context, enterpriseId string, req *http_model.AddReceiveAddressRequest) error {
	db := GetReadDB(ctx)
	return db.Debug().Model(gorm_model.YounggeeInvoiceAddress{}).Create(&gorm_model.YounggeeInvoiceAddress{
		EnterpriseID: enterpriseId,
		Name:         req.ReceiveName,
		RegionCode:   req.RegionCode,
		Address:      req.ReceiveAddress,
		Phone:        req.ReceivePhone,
		UpdateAt:     time.Now(),
	}).Error
}

func AddReceiveInfo(ctx context.Context, enterpriseId string, req *http_model.AddReceiveInfoRequest) error {
	db := GetReadDB(ctx)
	return db.Debug().Model(gorm_model.YounggeeInvoiceInfo{}).Create(&gorm_model.YounggeeInvoiceInfo{
		EnterpriseID:      enterpriseId,
		HeadType:          consts.GetHeadType(req.HeadType),
		InvoiceHeader:     req.InvoiceHead,
		InvoiceType:       consts.GetInvoiceType(req.InvoiceType),
		TaxCode:           req.TaxNum,
		Bank:              req.BaseBank,
		BankCardNumber:    req.BaseBankCardNum,
		RegisteredAddress: req.EnterpriseAddress,
		RegisteredPhone:   req.EnterprisePhone,
		UpdateAt:          time.Now(),
	}).Error
}

func GetReceiveAddress(ctx context.Context, enterpriseId string) (*http_model.ReceiveAddressData, error) {
	db := GetReadDB(ctx)
	var InvoiceAddress []*gorm_model.YounggeeInvoiceAddress
	db = db.Debug().Model(gorm_model.YounggeeInvoiceAddress{}).Where(
		"enterprise_id = ?",
		enterpriseId,
	)
	db = db.Order("update_at desc").Find(&InvoiceAddress)
	var receiveAddress http_model.ReceiveAddressData
	for _, v := range InvoiceAddress {
		ReceiveAddressPreview := new(http_model.ReceiveAddressPreview)
		ReceiveAddressPreview.AddressID = v.AddressID
		ReceiveAddressPreview.ReceiveName = v.Name
		ReceiveAddressPreview.AddressPhone = v.Phone
		ReceiveAddressPreview.Address = v.Address
		ReceiveAddressPreview.RegionCode = v.RegionCode
		receiveAddress.ReceiveAddressPreview = append(receiveAddress.ReceiveAddressPreview, ReceiveAddressPreview)
	}
	return &receiveAddress, nil
}

func GetReceiveInfo(ctx context.Context, enterpriseId string) (*http_model.ReceiveInfoData, error) {
	db := GetReadDB(ctx)
	var InvoiceInfo []*gorm_model.YounggeeInvoiceInfo
	db = db.Debug().Model(gorm_model.YounggeeInvoiceInfo{}).Where(
		"enterprise_id = ?",
		enterpriseId,
	)
	db = db.Order("update_at desc").Find(&InvoiceInfo)
	var ReceiveInfoData http_model.ReceiveInfoData
	for _, v := range InvoiceInfo {
		ReceiveInfoPreview := new(http_model.ReceiveInfoPreview)
		ReceiveInfoPreview.InvoiceHead = v.InvoiceHeader
		ReceiveInfoPreview.InvoiceID = v.InvoiceID
		ReceiveInfoPreview.HeadType = v.HeadType
		ReceiveInfoPreview.InvoiceType = v.InvoiceType
		ReceiveInfoPreview.EnterprisePhone = v.RegisteredPhone
		ReceiveInfoPreview.TaxNum = v.TaxCode
		ReceiveInfoPreview.BaseBank = v.Bank
		ReceiveInfoPreview.BaseBankCardNum = v.BankCardNumber
		ReceiveInfoPreview.EnterpriseAddress = v.RegisteredAddress
		ReceiveInfoData.ReceiveInfoPreview = append(ReceiveInfoData.ReceiveInfoPreview, ReceiveInfoPreview)
	}
	return &ReceiveInfoData, nil
}

func OperateReceiveInfo(ctx context.Context, enterpriseId string, req *http_model.OperateReceiveInfoRequest) error {
	db := GetReadDB(ctx)
	if req.OperateType == 2 {
		return db.Debug().Delete(&gorm_model.YounggeeInvoiceInfo{}, req.InvoiceId).Error
	}
	return db.Debug().Model(gorm_model.YounggeeInvoiceInfo{}).Where("enterprise_id = ? AND invoice_id = ?", enterpriseId, req.InvoiceId).Updates(
		&gorm_model.YounggeeInvoiceInfo{
			HeadType:          consts.GetHeadType(req.HeadType),
			InvoiceHeader:     req.InvoiceHead,
			InvoiceType:       consts.GetInvoiceType(req.InvoiceType),
			TaxCode:           req.TaxNum,
			Bank:              req.BaseBank,
			BankCardNumber:    req.BaseBankCardNum,
			RegisteredAddress: req.EnterpriseAddress,
			RegisteredPhone:   req.EnterprisePhone,
			UpdateAt:          time.Now(),
		}).Error
}

func OperateReceiveAddress(ctx context.Context, enterpriseId string, req *http_model.OperateReceiveAddressRequest) error {
	db := GetReadDB(ctx)
	if req.OperateType == 2 {
		return db.Debug().Delete(&gorm_model.YounggeeInvoiceAddress{}, req.AddressID).Error
	}
	return db.Debug().Model(gorm_model.YounggeeInvoiceAddress{}).Where("enterprise_id = ? AND address_id = ?", enterpriseId, req.AddressID).Updates(
		&gorm_model.YounggeeInvoiceAddress{
			Name:       req.ReceiveName,
			RegionCode: req.RegionCode,
			Address:    req.ReceiveAddress,
			Phone:      req.ReceivePhone,
			UpdateAt:   time.Now(),
		}).Error
}

func AddInvoiceRecord(ctx context.Context, enterpriseId string, req *http_model.AddInvoiceRecordRequest) error {
	invoiceInfo := gorm_model.YounggeeInvoiceInfo{}
	//fmt.Println("req:", req)
	//fmt.Println("invoice_id", req.InvoiceID)
	db1 := GetReadDB(ctx)
	db1.Debug().Model(gorm_model.YounggeeInvoiceInfo{}).Where("invoice_id = ?", req.InvoiceID).First(&invoiceInfo)
	invoiceInfoToJson, _ := json.Marshal(invoiceInfo)
	addressInfo := gorm_model.YounggeeInvoiceAddress{}
	db2 := GetReadDB(ctx)
	db2.Debug().Model(gorm_model.YounggeeInvoiceAddress{}).Where("address_id = ?", req.AddressID).First(&addressInfo)
	addressInfoToJson, _ := json.Marshal(addressInfo)

	req.RechargeIds = util.RemoveStrRepByMap(req.RechargeIds)
	for _, rechargeId := range req.RechargeIds {
		rechargeId1 := rechargeId
		rechargeInfo := gorm_model.YounggeeRechargeRecord{}
		fmt.Println("rechargeId1:", rechargeId1)
		db3 := GetReadDB(ctx)
		db3.Model(gorm_model.YounggeeRechargeRecord{}).Where("recharge_id = ?", rechargeId1).Find(&rechargeInfo)
		db := GetReadDB(ctx)
		err := db.Debug().Model(gorm_model.YounggeeInvoiceRecord{}).Create(&gorm_model.YounggeeInvoiceRecord{
			BillingID:     GetBillingId(ctx, enterpriseId),
			EnterpriseID:  enterpriseId,
			InvoiceAmount: rechargeInfo.RechargeAmount,
			InvoiceSnap:   string(invoiceInfoToJson),
			AddressSnap:   string(addressInfoToJson),
			Status:        1,
			InvoiceType:   invoiceInfo.InvoiceType,
			Phone:         invoiceInfo.RegisteredPhone,
			SubmitAt:      time.Now(),
		}).Error
		if err != nil {
			return err
		}
	}
	db3 := GetReadDB(ctx)
	return db3.Debug().Model(gorm_model.YounggeeRechargeRecord{}).Where("recharge_id IN ?", req.RechargeIds).Updates(gorm_model.YounggeeRechargeRecord{
		InvoiceStatus: 3,
	}).Error
}

func GetBillingId(ctx context.Context, enterpriseId string) string {
	db := GetReadDB(ctx)
	// 1、年月日
	year := time.Now().Year()
	month := time.Now().Month()
	day := time.Now().Day()
	yearData, _ := util.GetDayNum("year", year)
	monthData, _ := util.GetDayNum("month", int(month))
	dayData, _ := util.GetDayNum("day", day)
	sum := 0
	sum += dayData + monthData
	leap := 0
	if (yearData%400 == 0) || ((yearData%4 == 0) && (yearData%100 != 0)) {
		leap = 1
	}
	if (leap == 1) && (monthData > 2) {
		sum += 1
	}
	last := ""
	billingIdPrefix := "9" + conv.MustString(enterpriseId)[len(conv.MustString(enterpriseId))-2:] + conv.MustString(sum)
	var billingIdLast string
	err := db.Model(gorm_model.YounggeeInvoiceRecord{}).Select("billing_id").Where("billing_id like ?", billingIdPrefix+"%").
		Last(&billingIdLast).Error
	if err != nil {
		last = "0"
	} else {
		last = billingIdLast[len(billingIdLast)-2:]
	}
	var lastInt int
	lastInt = conv.MustInt(last)
	if lastInt+1 < 10 {
		last = "0" + conv.MustString(conv.MustInt(last)+1)
	} else {
		last = conv.MustString(conv.MustInt(last) + 1)
	}
	return billingIdPrefix + last
}
func GetInvoiceRecords(ctx context.Context, req *http_model.GetInvoiceRecordRequest, enterpriseID string) (*http_model.InvoiceRecordsData, error) {
	db := GetReadDB(ctx)
	var invoiceRecords []*gorm_model.YounggeeInvoiceRecord
	db = db.Debug().Model(gorm_model.YounggeeInvoiceRecord{}).Where("status = 2 and enterprise_id = ?", enterpriseID)
	if req.BillingAt != "" {
		db = db.Where("billing_at like ?", req.BillingAt+"%")
	}
	err := db.Order("billing_at desc").Find(&invoiceRecords).Error
	if err != nil {
		logrus.WithContext(ctx).Errorf("[GetInvoiceRecords] error query mysql limit, err:%+v", err)
		return nil, err
	}
	// var enterpriseIds []string
	// for _, invoiceRecord := range invoiceRecords {
	// 	enterpriseIds = append(enterpriseIds, invoiceRecord.EnterpriseID)
	// }
	// util.RemoveStrRepByMap(enterpriseIds)
	// enterpriseIdToUserInfoMap := make(map[string]gorm_model.Enterprise)
	// db1 := GetReadDB(ctx)
	// for _, v := range enterpriseIds {
	// 	enterpriseInfo := gorm_model.Enterprise{}
	// 	db1.Model(gorm_model.Enterprise{}).Where("enterprise_id = ?", v).Find(&enterpriseInfo)
	// 	enterpriseIdToUserInfoMap[v] = enterpriseInfo
	// }
	var InvoiceRecords []*http_model.InvoiceRecordsPreviews
	for _, invoiceRecord := range invoiceRecords {
		InvoiceRecord := new(http_model.InvoiceRecordsPreviews)
		InvoiceRecord.BillingId = invoiceRecord.BillingID
		InvoiceRecord.InvoiceInfo = invoiceRecord.InvoiceSnap
		InvoiceRecord.AddressInfo = invoiceRecord.AddressSnap
		InvoiceRecord.InvoiceType = invoiceRecord.InvoiceType
		InvoiceRecord.Amount = invoiceRecord.InvoiceAmount
		InvoiceRecord.ShipmentNumber = invoiceRecord.ShipmentNumber
		InvoiceRecord.BillingAt = conv.MustString(invoiceRecord.BillingAt, "")[:19]
		InvoiceRecords = append(InvoiceRecords, InvoiceRecord)
	}
	var InvoiceRecordsData http_model.InvoiceRecordsData
	InvoiceRecordsData.InvoiceRecordsPreviews = InvoiceRecords
	return &InvoiceRecordsData, nil
}
