package transform

import (
	"context"
	"strings"

	"github.com/UpmeshLTD/urus-aio/infrastructure/common"
	"github.com/UpmeshLTD/urus-aio/infrastructure/db/entities"
	"github.com/UpmeshLTD/urus-aio/infrastructure/errors"
	"github.com/UpmeshLTD/urus-aio/infrastructure/errors/messages"
	"github.com/UpmeshLTD/urus-aio/paid-order/service/dto"
)

func GetPaidOrdersRequestDTOToParamsEntities(req *dto.GetPaidOrdersRequest, workspaceID string) *entities.GetPaidOrdersParams {
	return &entities.GetPaidOrdersParams{
		WorkspaceID: &workspaceID,
		OnlyDraft:   req.Draft,
		Pagination: &common.Pagination{
			Limit: req.Limit,
			Page:  req.Page,
			Sort:  req.Sort,
		},
	}
}

func PaidOrderEntityToDTO(ctx context.Context, e *entities.PaidOrder) *dto.PaidOrder {
	mapping := map[string]messages.MessageCode{
		entities.IncorrectDeliveryAddress:     messages.RecipientAddressInvalid,
		entities.IncorrectDeliveryPhoneNumber: messages.RecipientPhoneInvalid,
		entities.IncorrectPickupAddress:       messages.PickupAddressInvalid,
	}
	incorrectInformation := make([]string, 0)
	for _, v := range e.IncorrectInformation {
		if msgCode, ok := mapping[v]; ok {
			incorrectInformation = append(incorrectInformation, errors.NewMessage(ctx, msgCode))
		} else {
			incorrectInformation = append(incorrectInformation, v)
		}
	}

	// Remove the last dot in the last message
	if len(incorrectInformation) > 0 {
		i := len(incorrectInformation) - 1
		incorrectInformation[i] = strings.TrimRight(incorrectInformation[i], ".")
		incorrectInformation[i] = strings.TrimRight(incorrectInformation[i], "。")
	}

	return &dto.PaidOrder{
		ID:                   e.ID,
		CartID:               e.CartID,
		ShippingGroupID:      e.ShippingGroupID,
		Status:               e.Status,
		IncorrectInformation: incorrectInformation,
		IsArrangedShip:       *e.IsArrangedShip,
		IsFulfilled:          *e.IsFulfilled,
		FulfillmentID:        e.FulfillmentID,
		ShipmentID:           e.ShipmentID,
	}
}

func PaidOrderEntitiesToDTOs(ctx context.Context, es []*entities.PaidOrder) []*dto.PaidOrder {
	results := make([]*dto.PaidOrder, len(es))
	for i, v := range es {
		results[i] = PaidOrderEntityToDTO(ctx, v)
	}
	return results
}

func CreatePaidOrdersRequestToEntities(req *dto.CreatePaidOrdersRequest, workspaceID string) []*entities.PaidOrder {
	var paidOrders = make([]*entities.PaidOrder, 0)
	var isArrangedShip = true
	var isFulfilled = false

	for _, v := range req.PaidOrders {
		paidOrders = append(paidOrders, &entities.PaidOrder{
			WorkspaceID:     workspaceID,
			CartID:          v.CartID,
			ShippingGroupID: v.ShippingGroupID,
			Status:          entities.OrderStatusPaid,
			IsArrangedShip:  &isArrangedShip,
			IsFulfilled:     &isFulfilled,
		})
	}
	return paidOrders
}

func GetArrangedShipPaidOrdersRequestToParamsEntity(req *dto.GetArrangedShipPaidOrdersRequest) *entities.GetArrangedPaidOrdersParams {
	poParams := make([]entities.PaidOrderParams, 0)
	for _, v := range req.PaidOrders {
		poParams = append(poParams, entities.PaidOrderParams{
			CartID:          v.CartID,
			ShippingGroupID: v.ShippingGroupID,
		})
	}
	return &entities.GetArrangedPaidOrdersParams{
		PaidOrders: poParams,
	}
}

func ArrangedShipPaidOrdersToDTO(paidOrders []*entities.PaidOrder) *dto.GetArrangedShipPaidOrdersResponse {
	data := make([]*dto.ArrangedShipPaidOrder, 0)
	for _, v := range paidOrders {
		data = append(data, &dto.ArrangedShipPaidOrder{
			ID:              v.ID,
			CartID:          v.CartID,
			ShippingGroupID: v.ShippingGroupID,
			FulfillmentID:   v.FulfillmentID,
			ShipmentID:      v.ShipmentID,
		})
	}
	return &dto.GetArrangedShipPaidOrdersResponse{
		Data: data,
	}
}
