package dto

import (
	"time"

	"github.com/UpmeshLTD/urus-aio/infrastructure/common"
	"github.com/UpmeshLTD/urus-aio/infrastructure/db/entities"
)

type CreateShipmentRequest struct {
	FulfillmentID string `json:"fulfillmentId"`
}

type FailedShipmentDetail struct {
	PickupPoint  *PickupPoint  `json:"pickupPoint"`
	ReceiverInfo *ReceiverInfo `json:"receiverInfo"`
}

type ReceiverInfo struct {
	RecipientName     string                         `json:"recipientName"`
	ContactNumber     string                         `json:"contactNumber"`
	PostalCode        string                         `json:"postalCode"`
	AddressLine1      string                         `json:"addressLine1"`
	AddressLine2      string                         `json:"addressLine2"`
	UnitNumber        string                         `json:"unitNumber"`
	Instructions      string                         `json:"instructions"`
	SubLevelLocations []ReceiverInfoSubLevelLocation `json:"subLevelLocations"`
}

type ReceiverInfoSubLevelLocation struct {
	InternationalName string `json:"internationalName"`
	LocalizedName     string `json:"localizedName"`
}

type FailedShipment struct {
	Code            int                  `json:"code"`
	Message         string               `json:"message"`
	CartID          string               `json:"cartId"`
	ShippingGroupID *string              `json:"shippingGroupId"`
	ShipmentCode    *string              `json:"shipmentCode"`
	Detail          FailedShipmentDetail `json:"detail"`
}

type CreateShipmentResponse struct {
	Successes []*Shipment       `json:"successes"`
	Fails     []*FailedShipment `json:"fails"`
}

type GetShipmentRequest struct {
	ShipmentID string `uri:"id"`
}

type GetShipmentResponse struct {
	Data *Shipment `json:"data"`
}

type Shipment struct {
	ID                   string                  `json:"id"`
	CourierTrackingID    string                  `json:"courierTrackingID"`
	Status               ShipmentStatus          `json:"status"`
	CourierStatus        string                  `json:"courierStatus"`
	CourierWebhookStatus string                  `json:"courierWebhookStatus"`
	Courier              Courier                 `json:"courier"`
	DeliveryPlan         DeliveryPlan            `json:"deliveryPlan"`
	WeightDimension      ShipmentWeightDimension `json:"weightDimension"`
	Fee                  float64                 `json:"fee"`

	CancelReasonText string `json:"cancelReasonText"`
	CancelReasonCode string `json:"cancelReasonCode"`

	PickupPoint       PickupPoint `json:"pickupPoint"`
	PickupTime        *time.Time  `json:"pickupTime"`
	PickupStartTime   *time.Time  `json:"pickupStartTime"`
	PickupEndTime     *time.Time  `json:"pickupEndTime"`
	PickupInstruction string      `json:"pickupInstruction"`

	CartID          string            `json:"cartId"`
	ShippingGroupID *string           `json:"shippingGroupId"`
	ShipmentCode    *string           `json:"shipmentCode"`
	BuyerInfo       ShipmentBuyerInfo `json:"buyerInfo"`
	Items           []*ShipmentItem   `json:"items"`

	Printable bool `json:"printable"`

	CreatedAt *time.Time `json:"createdAt"`
	StateDate *time.Time `json:"stateDate"`

	ArchivedAt *time.Time `json:"archivedAt"`
}

type ShipmentBuyerInfo struct {
	RecipientName     string                         `json:"recipientName"`
	Name              string                         `json:"name"`
	Email             string                         `json:"email"`
	ContactNumber     string                         `json:"contactNumber"`
	CountryCode       string                         `json:"countryCode"`
	PostalCode        string                         `json:"postalCode"`
	City              string                         `json:"city"`
	State             string                         `json:"state"`
	UnitNumber        string                         `json:"unitNumber"`
	AddressLine1      string                         `json:"addressLine1"`
	AddressLine2      string                         `json:"addressLine2"`
	SubLevelLocations []ReceiverInfoSubLevelLocation `json:"subLevelLocations"`
	Instructions      string                         `json:"instructions"`
}

type ShipmentWeightDimension struct {
	Weight float64 `json:"weight"`
	Width  float64 `json:"width"`
	Length float64 `json:"length"`
	Height float64 `json:"height"`
}

type ShipmentItem struct {
	Code        string `json:"code"`
	Description string `json:"description"`
	Quantity    int    `json:"quantity"`
}

type ShipmentStatus string

const (
	ShipmentStatusFulfillmentRequestSent ShipmentStatus = "fulfillment_request_sent"
	ShipmentStatusCourierStaffAssigned   ShipmentStatus = "courier_staff_assigned"
	ShipmentStatusPickedUp               ShipmentStatus = "picked_up"
	ShipmentStatusOnDelivery             ShipmentStatus = "on_delivery"
	ShipmentStatusDelivered              ShipmentStatus = "delivered"
	ShipmentStatusFailedDelivery         ShipmentStatus = "failed_delivery"
	ShipmentStatusCancelled              ShipmentStatus = "cancelled"
)

type GetShipmentsRequest struct {
	common.Pagination
	Status        string `form:"status"`
	SearchKeyword string `form:"searchKeyword"`
}

type GetShipmentsResponse struct {
	Data  []*Shipment `json:"data"`
	Total int64       `json:"total"`
}

type TrackingUrl struct {
	ShipmentID      string  `json:"shipmentId"`
	CartID          string  `json:"cartId"`
	ShippingGroupID *string `json:"shippingGroupId"`
	TrackingUrl     string  `json:"trackingUrl"`
}

type GetTrackingUrlsRequest struct {
	CartIDs []string `json:"cartIds"`
}

type GetTrackingUrlsResponse struct {
	Data []*TrackingUrl `json:"data"`
}

type GetShipmentLabelsRequest struct {
	ShipmentIDs []string `json:"ids"`
}

type GetShipmentLabelsResponse struct {
	Data []*GetShipmentLabelData `json:"data"`
}

type GetShipmentLabelData struct {
	ShipmentID string `json:"id"`
	URL        string `json:"url"`
	Error      string `json:"error"`
}

type GetShipmentStatusRequest struct {
	ShipmentID string `uri:"id"`
}

type GetShipmentStatusItemResponse struct {
	Status        string    `json:"status"`
	CourierStatus string    `json:"courierStatus"`
	StateText     string    `json:"stateText"`
	StateDate     time.Time `json:"stateDate"`
	CreatedAt     time.Time `json:"createdAt"`
}

type GetShipmentStatusResponse struct {
	ID                string                           `json:"id"`
	CourierTrackingID string                           `json:"courierTrackingId"`
	StatusHistory     []*GetShipmentStatusItemResponse `json:"statusHistory"`
}

type DevUpdateShipmentRequest struct {
	CourierTrackingID    string `json:"courierTrackingId"`
	CourierStatus        string `json:"courierStatus"`
	CancelReasonCode     string `json:"cancelReasonCode"`
	CancelReasonText     string `json:"cancelReasonText"`
	CourierWebhookStatus string `json:"courierWebhookStatus"`
}

type UpdateShipmentRequest struct {
	ID              string     `uri:"id" swaggerignore:"true"`
	PickupTime      *time.Time `json:"pickupTime"`
	PickupStartTime *time.Time `json:"pickupStartTime"`
	PickupEndTime   *time.Time `json:"pickupEndTime"`
}

type CancelShipmentRequest struct {
	ID     string `uri:"id"`
	Reason string `json:"reason"`
}

type NotifyPickupRequest struct {
	ShipmentID string `uri:"id"`
}

type NotifyPickupInBatchRequest struct {
	IDs []string `json:"ids"`
}

type GenerateShipmentLabelsRequest struct {
	Language    string   `json:"language"`
	ShipmentIDs []string `json:"ids"`
}

type GenerateShipmentLabelsResponse struct {
	Data *GenerateShipmentLabelsResponseData `json:"data"`
}

type GenerateShipmentLabelsResponseData struct {
	URL             string                                              `json:"url"`
	Error           string                                              `json:"error"`
	FailedShipments []*GenerateShipmentLabelsResponseDataFailedShipment `json:"failedShipments"`
}

type GenerateShipmentLabelsResponseDataFailedShipment struct {
	ID    string `json:"id"`
	Error string `json:"error"`
}

type ArchiveShipmentRequest struct {
	ID string `uri:"id"`
}

type GetArchivedShipmentsRequest struct {
	Search  string           `form:"search"`
	SortBy  entities.SortBy  `form:"sortBy,default=archived_at"`
	OrderBy entities.OrderBy `form:"orderBy,default=desc"`
	Limit   int              `form:"limit" json:"limit"`
	Page    int              `form:"page" json:"page"`
}

type GetShipmentOrdersStatusRequest struct {
	CartIDs []string `json:"cartIds"`
}

type ShipmentOrderStatus struct {
	CartID            string    `json:"cartId"`
	ShippingGroupID   *string   `json:"shippingGroupId"`
	Status            string    `json:"status"`
	StatusAt          time.Time `json:"statusAt"`
	CourierID         int64     `json:"courierId"`
	CourierTrackingID *string   `json:"courierTrackingId"`
	CancelReason      string    `json:"cancelReason"`
}

type GetShipmentOrdersStatusResponse struct {
	Data []ShipmentOrderStatus `json:"data"`
}

type ReArrangeShipmentRequest struct {
	ID string `uri:"id"`
}

type ReArrangeShipmentsRequest struct {
	IDs []string `json:"ids"`
}

type ReArrangeShipmentsResponse struct {
	FulfillmentID string `json:"fulfillmentId"`
}
