package service

import (
	"apskel-pos-be/internal/contract"
	"apskel-pos-be/internal/mappers"
	"apskel-pos-be/internal/processor"
	"context"
)

type VoucherService interface {
	GetRandomVouchersForSpin(ctx context.Context, req *contract.ListVouchersForSpinRequest) (*contract.ListVouchersForSpinResponse, error)
	GetRandomVouchersByRows(ctx context.Context, req *contract.ListVouchersByRowsRequest) (*contract.ListVouchersByRowsResponse, error)
	GetVoucherByID(ctx context.Context, voucherID int64) (*contract.VoucherResponse, error)
	GetVoucherByCode(ctx context.Context, voucherCode string) (*contract.VoucherResponse, error)
	ListVouchers(ctx context.Context, page, limit int) (*contract.PaginatedVoucherResponse, error)
}

type VoucherServiceImpl struct {
	voucherProcessor *processor.VoucherProcessor
}

func NewVoucherService(voucherProcessor *processor.VoucherProcessor) *VoucherServiceImpl {
	return &VoucherServiceImpl{
		voucherProcessor: voucherProcessor,
	}
}

func (s *VoucherServiceImpl) GetRandomVouchersForSpin(ctx context.Context, req *contract.ListVouchersForSpinRequest) (*contract.ListVouchersForSpinResponse, error) {
	modelReq := mappers.ListVouchersForSpinRequestToModel(req)

	response, err := s.voucherProcessor.GetRandomVouchersForSpin(ctx, modelReq)
	if err != nil {
		return nil, err
	}

	contractResponse := mappers.ListVouchersForSpinResponseToContract(response)
	return contractResponse, nil
}

func (s *VoucherServiceImpl) GetRandomVouchersByRows(ctx context.Context, req *contract.ListVouchersByRowsRequest) (*contract.ListVouchersByRowsResponse, error) {
	modelReq := mappers.ListVouchersByRowsRequestToModel(req)

	response, err := s.voucherProcessor.GetRandomVouchersByRows(ctx, modelReq)
	if err != nil {
		return nil, err
	}

	contractResponse := mappers.ListVouchersByRowsResponseToContract(response)
	return contractResponse, nil
}

func (s *VoucherServiceImpl) GetVoucherByID(ctx context.Context, voucherID int64) (*contract.VoucherResponse, error) {
	response, err := s.voucherProcessor.GetVoucherByID(ctx, voucherID)
	if err != nil {
		return nil, err
	}

	contractResponse := mappers.VoucherModelToContract(response)
	return contractResponse, nil
}

func (s *VoucherServiceImpl) GetVoucherByCode(ctx context.Context, voucherCode string) (*contract.VoucherResponse, error) {
	response, err := s.voucherProcessor.GetVoucherByCode(ctx, voucherCode)
	if err != nil {
		return nil, err
	}

	contractResponse := mappers.VoucherModelToContract(response)
	return contractResponse, nil
}

func (s *VoucherServiceImpl) ListVouchers(ctx context.Context, page, limit int) (*contract.PaginatedVoucherResponse, error) {
	response, err := s.voucherProcessor.ListVouchers(ctx, page, limit)
	if err != nil {
		return nil, err
	}

	// Convert to contract response
	vouchers := make([]contract.VoucherResponse, len(response.Data))
	for i, voucher := range response.Data {
		vouchers[i] = *mappers.VoucherModelToContract(&voucher)
	}

	contractResponse := &contract.PaginatedVoucherResponse{
		Data:       vouchers,
		TotalCount: response.TotalCount,
		Page:       response.Page,
		Limit:      response.Limit,
		TotalPages: response.TotalPages,
	}

	return contractResponse, nil
}
