package defaultservice

import (
	"encoding/json"
	"time"

	"github.com/apache/incubator-milagro-dta/libs/cryptowallet"
	"github.com/apache/incubator-milagro-dta/libs/documents"
	"github.com/apache/incubator-milagro-dta/pkg/api"
	"github.com/apache/incubator-milagro-dta/pkg/common"
	"github.com/pkg/errors"
)

// GetOrder retreives an order
func (s *Service) GetOrder(req *api.GetOrderRequest) (*api.GetOrderResponse, error) {
	orderReference := req.OrderReference

	var cid string
	if err := s.Store.Get("order", orderReference, &cid); err != nil {
		return nil, err
	}

	localIDDoc, err := common.RetrieveIDDocFromIPFS(s.Ipfs, s.NodeID())
	if err != nil {
		return nil, err
	}

	_, _, _, sikeSK, err := common.RetrieveIdentitySecrets(s.Store, s.NodeID())
	if err != nil {
		return nil, err
	}

	order, err := common.RetrieveOrderFromIPFS(s.Ipfs, cid, sikeSK, s.NodeID(), localIDDoc.BLSPublicKey)
	if err != nil {
		return nil, err
	}

	orderByte, err := json.Marshal(order)
	if err != nil {
		return nil, err
	}
	return &api.GetOrderResponse{
		OrderCID: cid,
		Order:    string(orderByte),
	}, nil
}

// OrderList retrieves the list of orders
func (s *Service) OrderList(req *api.OrderListRequest) (*api.OrderListResponse, error) {
	page := req.Page
	perPage := req.PerPage
	sortBy := req.SortBy

	orderref, err := s.Store.ListKeys("order", "time", page*perPage, perPage, sortBy != "dateCreatedAsc")
	if err != nil {
		return nil, err
	}

	//Pagnination - Show everything by default
	start := 0
	stop := len(orderref)

	if perPage != 0 && page < len(orderref)/perPage && page*perPage < len(orderref) {
		start = page
		stop = perPage
	}

	return &api.OrderListResponse{
		OrderReference: orderref[start:stop],
	}, nil
}

// ValidateOrderRequest returns error if the request values are invalid
func (s *Service) ValidateOrderRequest(req *api.OrderRequest) error {
	return nil
}

// PrepareOrderPart1 is called before the order is send
func (s *Service) PrepareOrderPart1(order *documents.OrderDoc, reqExtension map[string]string) (fulfillExtension map[string]string, err error) {
	return nil, nil
}

// PrepareOrderResponse gets the updated order and returns the commitment and extension
func (s *Service) PrepareOrderResponse(orderPart2 *documents.OrderDoc, reqExtension, fulfillExtension map[string]string) (commitment string, extension map[string]string, err error) {
	return orderPart2.OrderPart2.CommitmentPublicKey, nil, nil
}

// Order -
func (s *Service) Order(req *api.OrderRequest) (*api.OrderResponse, error) {
	if err := s.Plugin.ValidateOrderRequest(req); err != nil {
		return nil, err
	}

	//Initialise values from Request object
	beneficiaryIDDocumentCID := req.BeneficiaryIDDocumentCID
	iDDocID := s.NodeID()
	recipientList, err := common.BuildRecipientList(s.Ipfs, iDDocID, s.MasterFiduciaryNodeID())
	if err != nil {
		return nil, err
	}

	remoteIDDoc, err := common.RetrieveIDDocFromIPFS(s.Ipfs, s.MasterFiduciaryNodeID())
	if err != nil {
		return nil, err
	}

	//Create Order
	order, err := common.CreateNewDepositOrder(beneficiaryIDDocumentCID, iDDocID)
	if err != nil {
		return nil, err
	}

	fulfillExtension, err := s.Plugin.PrepareOrderPart1(order, req.Extension)
	if err != nil {
		return nil, err
	}

	//Write Order to IPFS
	orderPart1CID, err := common.WriteOrderToIPFS(iDDocID, s.Ipfs, s.Store, iDDocID, order, recipientList)
	if err != nil {
		return nil, err
	}

	//Fullfill the order on the remote Server
	request := &api.FulfillOrderRequest{
		DocumentCID:   iDDocID,
		OrderPart1CID: orderPart1CID,
		Extension:     fulfillExtension,
	}
	response, err := s.MasterFiduciaryServer.FulfillOrder(request)
	if err != nil {
		return nil, errors.Wrap(err, "Contacting Fiduciary")
	}

	//Get the updated order out of IPFS
	_, _, _, sikeSK, err := common.RetrieveIdentitySecrets(s.Store, iDDocID)
	if err != nil {
		return nil, err
	}
	updatedOrder, err := common.RetrieveOrderFromIPFS(s.Ipfs, response.OrderPart2CID, sikeSK, iDDocID, remoteIDDoc.BLSPublicKey)
	if err != nil {
		return nil, errors.Wrap(err, "Fail to retrieve Order from IPFS")
	}

	commitment, extension, err := s.Plugin.PrepareOrderResponse(updatedOrder, req.Extension, response.Extension)
	if err != nil {
		return nil, errors.Wrap(err, "Generating Final Public Key")
	}

	return &api.OrderResponse{
		OrderReference: order.Reference,
		Commitment:     commitment,
		CreatedAt:      time.Now().Unix(),
		Extension:      extension,
	}, nil
}

// ProduceBeneficiaryEncryptedData -
func (s *Service) ProduceBeneficiaryEncryptedData(blsSK []byte, order *documents.OrderDoc, req *api.OrderSecretRequest) (encrypted []byte, extension map[string]string, err error) {
	return nil, nil, nil
}

// ProduceFinalSecret -
func (s *Service) ProduceFinalSecret(seed, sikeSK []byte, order, orderPart4 *documents.OrderDoc, req *api.OrderSecretRequest, fulfillSecretRespomse *api.FulfillOrderSecretResponse) (secret, commitment string, extension map[string]string, err error) {
	finalPrivateKey := orderPart4.OrderDocument.OrderPart4.Secret
	//Derive the Public key from the supplied Private Key
	finalPublicKey, _, err := cryptowallet.PublicKeyFromPrivate(finalPrivateKey)
	return finalPrivateKey, finalPublicKey, nil, err
}

// OrderSecret -
func (s *Service) OrderSecret(req *api.OrderSecretRequest) (*api.OrderSecretResponse, error) {
	orderReference := req.OrderReference
	var orderPart2CID string
	if err := s.Store.Get("order", orderReference, &orderPart2CID); err != nil {
		return nil, err
	}

	nodeID := s.NodeID()
	recipientList, err := common.BuildRecipientList(s.Ipfs, nodeID, s.MasterFiduciaryNodeID())
	if err != nil {
		return nil, err
	}
	remoteIDDoc, err := common.RetrieveIDDocFromIPFS(s.Ipfs, s.MasterFiduciaryNodeID())
	if err != nil {
		return nil, err
	}

	_, seed, blsSK, sikeSK, err := common.RetrieveIdentitySecrets(s.Store, nodeID)
	if err != nil {
		return nil, err
	}

	//Retrieve the order from IPFS
	order, err := common.RetrieveOrderFromIPFS(s.Ipfs, orderPart2CID, sikeSK, nodeID, remoteIDDoc.BLSPublicKey)
	if err != nil {
		return nil, errors.Wrap(err, "Fail to retrieve Order from IPFS")
	}

	beneficiaryEncryptedData, extension, err := s.Plugin.ProduceBeneficiaryEncryptedData(blsSK, order, req)
	if err != nil {
		return nil, err
	}

	//Create a request Object in IPFS
	orderPart3CID, err := common.CreateAndStorePart3(s.Ipfs, s.Store, order, orderPart2CID, nodeID, beneficiaryEncryptedData, recipientList)
	if err != nil {
		return nil, err
	}

	//Post the address of the updated doc to the custody node
	request := &api.FulfillOrderSecretRequest{
		SenderDocumentCID: nodeID,
		OrderPart3CID:     orderPart3CID,
		Extension:         extension,
	}
	response, err := s.MasterFiduciaryServer.FulfillOrderSecret(request)
	if err != nil {
		return nil, err
	}

	//Retrieve the response Order from IPFS
	orderPart4, err := common.RetrieveOrderFromIPFS(s.Ipfs, response.OrderPart4CID, sikeSK, nodeID, remoteIDDoc.BLSPublicKey)
	if err != nil {
		return nil, err
	}

	finalPrivateKey, finalPublicKey, ext, err := s.Plugin.ProduceFinalSecret(seed, sikeSK, order, orderPart4, req, response)
	if err != nil {
		return nil, err
	}

	return &api.OrderSecretResponse{
		Secret:         finalPrivateKey,
		Commitment:     finalPublicKey,
		OrderReference: order.Reference,
		Extension:      ext,
	}, nil
}
