package service

import (
	"apskel-pos-be/internal/constants"
	"apskel-pos-be/internal/contract"
	"apskel-pos-be/internal/processor"
	"apskel-pos-be/internal/transformer"
	"context"

	"github.com/google/uuid"
)

type OutletService interface {
	ListOutlets(ctx context.Context, req *contract.ListOutletsRequest) *contract.Response
	GetOutletByID(ctx context.Context, organizationID, outletID uuid.UUID) *contract.Response
	CreateOutlet(ctx context.Context, req *contract.CreateOutletRequest) *contract.Response
	UpdateOutlet(ctx context.Context, outletID uuid.UUID, req *contract.UpdateOutletRequest) *contract.Response
	DeleteOutlet(ctx context.Context, outletID uuid.UUID) *contract.Response
}

type OutletServiceImpl struct {
	outletProcessor processor.OutletProcessor
}

func NewOutletService(outletProcessor processor.OutletProcessor) *OutletServiceImpl {
	return &OutletServiceImpl{
		outletProcessor: outletProcessor,
	}
}

func (s *OutletServiceImpl) ListOutlets(ctx context.Context, req *contract.ListOutletsRequest) *contract.Response {
	if req.Page < 1 {
		req.Page = 1
	}
	if req.Limit < 1 {
		req.Limit = 10
	}
	if req.Limit > 100 {
		req.Limit = 100
	}

	outlets, total, err := s.outletProcessor.ListOutletsByOrganization(ctx, req.OrganizationID, req.Page, req.Limit)
	if err != nil {
		errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.OutletServiceEntity, err.Error())
		return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
	}

	contractOutlets := make([]contract.OutletResponse, len(outlets))
	for i, outlet := range outlets {
		contractOutlets[i] = transformer.OutletModelResponseToResponse(outlet)
	}

	response := transformer.CreateListOutletsResponse(contractOutlets, int(total), req.Page, req.Limit)
	return contract.BuildSuccessResponse(response)
}

func (s *OutletServiceImpl) GetOutletByID(ctx context.Context, organizationID, outletID uuid.UUID) *contract.Response {
	outlet, err := s.outletProcessor.GetOutletByID(ctx, organizationID, outletID)
	if err != nil {
		errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.OutletServiceEntity, err.Error())
		return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
	}

	contractResponse := transformer.OutletModelResponseToResponse(outlet)
	return contract.BuildSuccessResponse(contractResponse)
}

func (s *OutletServiceImpl) CreateOutlet(ctx context.Context, req *contract.CreateOutletRequest) *contract.Response {
	modelReq := transformer.CreateOutletRequestToModel(req)

	outlet, err := s.outletProcessor.CreateOutlet(ctx, modelReq)
	if err != nil {
		errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.OutletServiceEntity, err.Error())
		return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
	}

	contractResponse := transformer.OutletModelResponseToResponse(outlet)
	return contract.BuildSuccessResponse(contractResponse)
}

func (s *OutletServiceImpl) UpdateOutlet(ctx context.Context, outletID uuid.UUID, req *contract.UpdateOutletRequest) *contract.Response {
	modelReq := transformer.UpdateOutletRequestToModel(req)

	outlet, err := s.outletProcessor.UpdateOutlet(ctx, outletID, modelReq)
	if err != nil {
		errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.OutletServiceEntity, err.Error())
		return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
	}

	contractResponse := transformer.OutletModelResponseToResponse(outlet)
	return contract.BuildSuccessResponse(contractResponse)
}

func (s *OutletServiceImpl) DeleteOutlet(ctx context.Context, outletID uuid.UUID) *contract.Response {
	err := s.outletProcessor.DeleteOutlet(ctx, outletID)
	if err != nil {
		errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.OutletServiceEntity, err.Error())
		return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
	}

	return contract.BuildSuccessResponse(map[string]interface{}{
		"message": "Outlet deleted successfully",
	})
}
