package mappers

import (
	"apskel-pos-be/internal/contract"
	"apskel-pos-be/internal/entities"
	"apskel-pos-be/internal/models"
	"strings"
)

func VoucherEntityToResponse(voucher *entities.Voucher) *models.VoucherResponse {
	return &models.VoucherResponse{
		ID:           voucher.ID,
		Name:         voucher.Name,
		Email:        voucher.Email,
		PhoneNumber:  voucher.PhoneNumber,
		VoucherCode:  voucher.VoucherCode,
		WinnerNumber: voucher.WinnerNumber,
		IsWinner:     voucher.IsWinner,
	}
}

func VoucherModelToContract(voucher *models.VoucherResponse) *contract.VoucherResponse {
	return &contract.VoucherResponse{
		ID:           voucher.ID,
		Name:         voucher.Name,
		Email:        voucher.Email,
		PhoneNumber:  voucher.PhoneNumber,
		VoucherCode:  voucher.VoucherCode,
		WinnerNumber: voucher.WinnerNumber,
		IsWinner:     voucher.IsWinner,
	}
}

func VoucherEntityToSpinResponse(voucher *entities.Voucher) *models.VoucherSpinResponse {
	maskedPhone := maskPhoneNumber(&voucher.PhoneNumber)
	return &models.VoucherSpinResponse{
		VoucherCode: voucher.VoucherCode,
		Name:        voucher.Name,
		PhoneNumber: maskedPhone,
		IsWinner:    voucher.IsWinner,
	}
}

func VoucherSpinModelToContract(voucher *models.VoucherSpinResponse) *contract.VoucherSpinResponse {
	return &contract.VoucherSpinResponse{
		VoucherCode: voucher.VoucherCode,
		Name:        voucher.Name,
		PhoneNumber: voucher.PhoneNumber,
		IsWinner:    voucher.IsWinner,
	}
}

func ListVouchersForSpinRequestToModel(req *contract.ListVouchersForSpinRequest) *models.ListVouchersForSpinRequest {
	return &models.ListVouchersForSpinRequest{
		Limit: req.Limit,
	}
}

func ListVouchersForSpinResponseToContract(resp *models.ListVouchersForSpinResponse) *contract.ListVouchersForSpinResponse {
	vouchers := make([]contract.VoucherSpinResponse, len(resp.Vouchers))
	for i, voucher := range resp.Vouchers {
		vouchers[i] = *VoucherSpinModelToContract(&voucher)
	}

	return &contract.ListVouchersForSpinResponse{
		Vouchers: vouchers,
		Count:    resp.Count,
	}
}

func VoucherRowModelToContract(row *models.VoucherRow) *contract.VoucherRow {
	vouchers := make([]contract.VoucherSpinResponse, len(row.Vouchers))
	for i, voucher := range row.Vouchers {
		vouchers[i] = *VoucherSpinModelToContract(&voucher)
	}

	return &contract.VoucherRow{
		RowNumber: row.RowNumber,
		Vouchers:  vouchers,
	}
}

func ListVouchersByRowsRequestToModel(req *contract.ListVouchersByRowsRequest) *models.ListVouchersByRowsRequest {
	return &models.ListVouchersByRowsRequest{
		Rows:         req.Rows,
		WinnerNumber: req.WinnerNumber,
	}
}

func ListVouchersByRowsResponseToContract(resp *models.ListVouchersByRowsResponse) *contract.ListVouchersByRowsResponse {
	rows := make([]contract.VoucherRow, len(resp.Rows))
	for i, row := range resp.Rows {
		rows[i] = *VoucherRowModelToContract(&row)
	}

	return &contract.ListVouchersByRowsResponse{
		Rows:          rows,
		TotalRows:     resp.TotalRows,
		TotalVouchers: resp.TotalVouchers,
	}
}

// maskPhoneNumber masks phone number for privacy
func maskPhoneNumber(phone *string) string {
	if phone == nil || *phone == "" {
		return ""
	}

	phoneStr := *phone

	// Normalize: replace leading "62" with "0"
	if strings.HasPrefix(phoneStr, "62") {
		phoneStr = "0" + phoneStr[2:]
	}

	// If phone length <= 8, just mask the middle
	if len(phoneStr) <= 8 {
		return phoneStr
	}

	// Show first 4 and last 4 characters
	start := phoneStr[:4]
	end := phoneStr[len(phoneStr)-4:]
	middle := strings.Repeat("*", len(phoneStr)-8)

	return start + middle + end
}
