package controllers

import (
	"context"
	"sparrow/pkg/models"
	"sparrow/pkg/rpcs"
	"sparrow/pkg/server"
	"sparrow/services/knowoapi/services"
	"strings"

	"github.com/kataras/iris/v12"
	opentracing "github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/ext"
)

// ProductController 产品API
type ProductController struct {
	Ctx     iris.Context
	Service services.ProductService
	Token   Token
}

// Post /product 添加产品
func (a *ProductController) Post() {
	product := new(models.Product)
	if err := parseBody(a.Ctx, product); err != nil {
		badRequest(a.Ctx, err)
		return
	}
	product.VendorID = a.Token.getVendorID(a.Ctx)

	// if upload a image file
	if product.ProductImage != "" {
		//move image
		args := &rpcs.ArgsMoveFile{
			Source: product.ProductImage,
			Target: "product",
		}
		reply := &rpcs.ReplyMoveFile{}

		span, ctx := opentracing.StartSpanFromContext(context.Background(), a.Ctx.Path())
		defer span.Finish()
		ext.SpanKindRPCClient.Set(span)
		ext.HTTPMethod.Set(span, a.Ctx.Method())
		err := server.RPCCallByName(ctx, "fileaccess", "FileAccess.MoveFile", args, reply)
		if err != nil {
			server.Log.Error(err)
			product.ProductImage = ""
		} else {
			product.ProductImage = reply.FilePath
		}
	}
	err := a.Service.Create(product)
	if err != nil {
		responseError(a.Ctx, ErrDatabase, err.Error())
		return
	}
	done(a.Ctx, product)
}

// Delete /product 删除
func (a *ProductController) Delete() {
	product := new(models.Product)
	if err := parseBody(a.Ctx, product); err != nil {
		badRequest(a.Ctx, err)
		return
	}
	if product.VendorID != a.Token.getVendorID(a.Ctx) {
		responseError(a.Ctx, ErrNormal, "非法操作")
		return
	}
	err := a.Service.Delete(product)
	if err != nil {
		responseError(a.Ctx, ErrDatabase, err.Error())
		return
	}
	done(a.Ctx, "删除成功")
}

// Put /produdct 更新产品信息
func (a *ProductController) Put() {
	product := new(models.Product)
	if err := parseBody(a.Ctx, product); err != nil {
		badRequest(a.Ctx, err)
		return
	}
	if product.VendorID != a.Token.getVendorID(a.Ctx) {
		responseError(a.Ctx, ErrNormal, "非法操作")
		return
	}
	// check update image
	if strings.Contains(product.ProductImage, "tmp") {
		//move image
		args := &rpcs.ArgsMoveFile{
			Source: product.ProductImage,
			Target: "product",
		}
		reply := &rpcs.ReplyMoveFile{}
		err := server.RPCCallByName(nil, "fileaccess", "FileAccess.MoveFile", args, reply)
		if err != nil {
			server.Log.Error(err)
			product.ProductImage = ""
		} else {
			product.ProductImage = reply.FilePath
		}

	}
	if product.ProductImage == "" {
		old, _ := a.Service.QueryOne(a.Token.getVendorID(a.Ctx), product.ProductKey)
		arg := &rpcs.ArgsDeleteFile{
			FileName: old.ProductImage,
		}
		reply := &rpcs.ReplyEmptyResult{}
		server.RPCCallByName(nil, "fileaccess", "FileAccess.DeleteFile", arg, reply)
	}
	pro, err := a.Service.Update(product)
	if err != nil {
		responseError(a.Ctx, ErrDatabase, err.Error())
		return
	}
	done(a.Ctx, pro)
}

// Get /product 查询我的产品
func (a *ProductController) Get() {
	pi, err := a.Ctx.URLParamInt("pi")
	if err != nil {
		badRequest(a.Ctx, err)
		return
	}
	ps, err := a.Ctx.URLParamInt("ps")
	if err != nil {
		badRequest(a.Ctx, err)
		return
	}
	name := a.Ctx.URLParam("name")
	ds, total, err := a.Service.GetVendorProducts(a.Token.getVendorID(a.Ctx),
		pi,
		ps,
		name)
	if err != nil {
		responseError(a.Ctx, ErrDatabase, err.Error())
		return
	}
	done(a.Ctx, map[string]interface{}{
		"list":  ds,
		"total": total,
	})
}

// GetBy 获取产品信息
// GET /product/{key}
func (a *ProductController) GetBy(key string) {
	pro, err := a.Service.QueryOne(a.Token.getVendorID(a.Ctx), key)
	if err != nil {
		responseError(a.Ctx, ErrDatabase, err.Error())
		return
	}
	done(a.Ctx, pro)
}
