package controllers

import (
	"encoding/json"
	"fmt"
	"io"
	"merchant/internal/config"
	"merchant/internal/models/merchant"
	"merchant/internal/models/order"
	"merchant/internal/service"
	"merchant/internal/sys/enum"
	"strconv"
	"strings"
	"time"

	"github.com/beego/beego/v2/core/logs"
	"github.com/duke-git/lancet/v2/convertor"
	"github.com/duke-git/lancet/v2/slice"
	"github.com/duke-git/lancet/v2/strutil"
	"github.com/rs/xid"
	"github.com/xuri/excelize/v2"
)

type GenLink struct {
	KeepSession
}

func (c *GenLink) ShowGenLinkUI() {
	c.TplName = "gen_link.html"
}

func (c *GenLink) GenShopLink() {
	showMMValue, err := c.GetFloat("showMMValue")
	if err != nil {
		c.Data["errorMsg"] = "获取面额出错！"
		c.TplName = "error.html"
		return
	}
	productCode := strings.TrimSpace(c.GetString("productCode"))

	us := c.GetSession(enum.UserSession)
	u := us.(merchant.MerchantInfo)

	createOrderResponse, err := service.CreateOrder(c.Ctx.Request.Context(), &order.CreatedOrder{
		PayKey:      u.MerchantKey,
		OrderNo:     xid.New().String(),
		OrderPrice:  showMMValue,
		OrderPeriod: 24,
		NotifyUrl:   fmt.Sprintf("%s/shop/notify", config.GetShopAddr()),
		Timestamp:   time.Now().Unix(),
		ProductCode: productCode,
	}, u.MerchantSecret)

	if err != nil {
		logs.Info("生成订单失败", err)
		c.Data["errorMsg"] = "生成订单失败！"
		c.TplName = "error.html"
		return
	}
	c.Redirect(createOrderResponse.PayUrl, 302)
}

// ShowQueryOrderUI 生成查询订单页面
func (c *GenLink) ShowQueryOrderUI() {
	c.Data["portalAddr"] = config.GetPortalAddr()
	c.TplName = "query_order.html"
}

func (c *GenLink) UploadFile() {
	// // 解析上传的文件
	file, _, err := c.GetFile("file")
	if err != nil {
		c.Data["errorMsg"] = "获取文件失败！"
		c.TplName = "error.html"
		return
	}
	defer file.Close()

	roadCode := c.GetString("mm-select-road")
	mmValue := c.GetString("mm-road-select")

	us := c.GetSession(enum.UserSession)
	u := us.(merchant.MerchantInfo)
	content, err := io.ReadAll(file)
	if err != nil {
		c.Data["errorMsg"] = "读取文件失败！"
		c.TplName = "error.html"
		return
	}

	// 结果生成xlsx 文件以供下载
	excelFile := excelize.NewFile()
	sheetName, _ := excelFile.NewSheet("Sheet1")
	excelFile.SetActiveSheet(sheetName)

	_ = excelFile.SetCellValue("Sheet1", "A1", "订单号")
	_ = excelFile.SetCellValue("Sheet1", "B1", "价格")
	_ = excelFile.SetCellValue("Sheet1", "C1", "卡号")
	_ = excelFile.SetCellValue("Sheet1", "D1", "卡密")
	_ = excelFile.SetCellValue("Sheet1", "E1", "状态")
	_ = excelFile.SetCellValue("Sheet1", "F1", "创建时间")

	lines := strings.Split(strutil.Trim(convertor.ToString(content)), "\n")

	slice.ForEachConcurrent(lines, func(i int, line string) {
		i += 1
		line = strings.TrimSpace(line)
		var parts []string
		if strings.Contains(line, "\t") {
			parts = strings.Split(line, "\t")
		}
		if strings.Contains(line, " ") {
			parts = strings.Split(line, " ")
		}

		if len(parts) < 2 {
			_ = excelFile.SetCellValue("Sheet1", fmt.Sprintf("A%d", i+1), "上传卡数据错误")
			logs.Error("卡密数据错误", line)
			return
		}
		//price := strutil.Trim(parts[0])
		cardNo := strutil.Trim(strings.TrimSpace(parts[0]))
		cardPasswd := strutil.Trim(strings.TrimSpace(parts[1]))

		orderNo := xid.New().String() + "-" + fmt.Sprintf("%04d", i)
		_ = excelFile.SetCellValue("Sheet1", fmt.Sprintf("A%d", i+1), orderNo)
		_ = excelFile.SetCellValue("Sheet1", fmt.Sprintf("B%d", i+1), mmValue)
		_ = excelFile.SetCellValue("Sheet1", fmt.Sprintf("C%d", i+1), cardNo)
		_ = excelFile.SetCellValue("Sheet1", fmt.Sprintf("D%d", i+1), cardPasswd)

		_, err = strconv.ParseFloat(mmValue, 64)
		if err != nil {
			_ = excelFile.SetCellValue("Sheet1", fmt.Sprintf("E%d", i+1), "价格转换失败")
			logs.Info("价格转换失败", err)
			return
		}

		pp := map[string]string{
			"data":   cardPasswd,
			"cardNo": cardNo,
		}

		marshal, err2 := json.Marshal(&pp)
		if err2 != nil {
			_ = excelFile.SetCellValue("Sheet1", fmt.Sprintf("E%d", i+1), "卡密数据解析错误")
			logs.Error("卡密数据解析错误", err)
			return
		}

		err = service.SubmitOrderBackendTask(c.Ctx.Request.Context(), &order.SubmitOrder{
			PayKey:      u.MerchantKey,
			OrderNo:     orderNo,
			OrderPrice:  mmValue,
			OrderPeriod: 24,
			NotifyUrl:   "http://kami_shop:12305/shop/notify",
			ProductCode: roadCode,
			ExValue:     string(marshal),
			Ip:          c.Ctx.Input.IP(),
			PaySecret:   u.MerchantSecret,
		})
		if err != nil {
			_ = excelFile.SetCellValue("Sheet1", fmt.Sprintf("E%d", i+1), "提交订单失败")
			logs.Error("提交订单失败", err)
			return
		}
		_ = excelFile.SetCellValue("Sheet1", fmt.Sprintf("F%d", i+1), time.Now().Format("2006-01-02 15:04:05"))
		_ = excelFile.SetCellValue("Sheet1", fmt.Sprintf("E%d", i+1), "提交成功")
	}, len(lines)/10)
	c.Ctx.ResponseWriter.Header().Set("Content-Type", "application/octet-stream")
	c.Ctx.ResponseWriter.Header().Set("Content-Disposition", "attachment; filename=卡密.xlsx")
	_ = excelFile.Write(c.Ctx.ResponseWriter)
	c.StopRun()
}
