package transformer

import (
	"apskel-pos-be/internal/appcontext"
	"apskel-pos-be/internal/constants"
	"apskel-pos-be/internal/contract"
	"apskel-pos-be/internal/models"
	"strconv"

	"github.com/google/uuid"
)

type TableTransformer struct{}

func NewTableTransformer() *TableTransformer {
	return &TableTransformer{}
}

func (t *TableTransformer) ToContract(model models.TableResponse) *contract.TableResponse {
	response := &contract.TableResponse{
		ID:             model.ID,
		OrganizationID: model.OrganizationID,
		OutletID:       model.OutletID,
		TableName:      model.TableName,
		StartTime:      model.StartTime,
		Status:         string(model.Status),
		OrderID:        model.OrderID,
		PaymentAmount:  model.PaymentAmount,
		PositionX:      model.PositionX,
		PositionY:      model.PositionY,
		Capacity:       model.Capacity,
		IsActive:       model.IsActive,
		Metadata:       model.Metadata,
		CreatedAt:      model.CreatedAt,
		UpdatedAt:      model.UpdatedAt,
	}

	if model.Order != nil {
		response.Order = &contract.OrderResponse{
			ID:             model.Order.ID,
			OutletID:       model.Order.OutletID,
			UserID:         model.Order.UserID,
			OrderNumber:    model.Order.OrderNumber,
			TableNumber:    model.Order.TableNumber,
			OrderType:      string(model.Order.OrderType),
			Status:         string(model.Order.Status),
			Subtotal:       model.Order.Subtotal,
			TaxAmount:      model.Order.TaxAmount,
			DiscountAmount: model.Order.DiscountAmount,
			TotalAmount:    model.Order.TotalAmount,
			Metadata:       model.Order.Metadata,
			CreatedAt:      model.Order.CreatedAt,
			UpdatedAt:      model.Order.UpdatedAt,
		}
	}

	return response
}

func CreateTableRequestToModel(apctx *appcontext.ContextInfo, req *contract.CreateTableRequest) models.CreateTableRequest {
	return models.CreateTableRequest{
		OutletID:  req.OutletID,
		TableName: req.TableName,
		PositionX: req.PositionX,
		PositionY: req.PositionY,
		Capacity:  req.Capacity,
		Metadata:  req.Metadata,
	}
}

func UpdateTableRequestToModel(req *contract.UpdateTableRequest) models.UpdateTableRequest {
	modelReq := models.UpdateTableRequest{
		TableName: req.TableName,
		PositionX: req.PositionX,
		PositionY: req.PositionY,
		Capacity:  req.Capacity,
		IsActive:  req.IsActive,
		Metadata:  req.Metadata,
	}

	if req.Status != nil {
		status := constants.TableStatus(*req.Status)
		modelReq.Status = &status
	}

	return modelReq
}

func OccupyTableRequestToModel(req *contract.OccupyTableRequest) models.OccupyTableRequest {
	return models.OccupyTableRequest{
		OrderID:   req.OrderID,
		StartTime: req.StartTime,
	}
}

func ReleaseTableRequestToModel(req *contract.ReleaseTableRequest) models.ReleaseTableRequest {
	return models.ReleaseTableRequest{
		PaymentAmount: req.PaymentAmount,
	}
}

func ListTablesQueryToModel(req *contract.ListTablesQuery) models.ListTablesRequest {
	modelReq := models.ListTablesRequest{
		Page:   req.Page,
		Limit:  req.Limit,
		Search: req.Search,
	}

	if req.OrganizationID != "" {
		if orgID, err := uuid.Parse(req.OrganizationID); err == nil {
			modelReq.OrganizationID = &orgID
		}
	}

	if req.OutletID != "" {
		if outletID, err := uuid.Parse(req.OutletID); err == nil {
			modelReq.OutletID = &outletID
		}
	}

	if req.Status != "" {
		status := constants.TableStatus(req.Status)
		modelReq.Status = &status
	}

	if req.IsActive != "" {
		if isActive, err := strconv.ParseBool(req.IsActive); err == nil {
			modelReq.IsActive = &isActive
		}
	}

	return modelReq
}
