package invoices

import (
	"fmt"
	"time"

	"github.com/google/uuid"
	"github.com/shopspring/decimal"
	"go.uber.org/zap"

	"rmser/internal/domain/invoices"
	"rmser/internal/infrastructure/rms"
	"rmser/pkg/logger"
)

type Service struct {
	rmsClient rms.ClientI
	// Здесь можно добавить репозитории каталога и контрагентов для валидации,
	// но для краткости пока опустим глубокую валидацию.
}

func NewService(rmsClient rms.ClientI) *Service {
	return &Service{
		rmsClient: rmsClient,
	}
}

// CreateRequestDTO - структура входящего JSON запроса от фронта/OCR
type CreateRequestDTO struct {
	DocumentNumber string    `json:"document_number"`
	DateIncoming   string    `json:"date_incoming"` // YYYY-MM-DD
	SupplierID     uuid.UUID `json:"supplier_id"`
	StoreID        uuid.UUID `json:"store_id"`
	Items          []struct {
		ProductID uuid.UUID       `json:"product_id"`
		Amount    decimal.Decimal `json:"amount"`
		Price     decimal.Decimal `json:"price"`
	} `json:"items"`
}

// SendInvoiceToRMS валидирует DTO, собирает доменную модель и отправляет в RMS
func (s *Service) SendInvoiceToRMS(req CreateRequestDTO) (string, error) {
	// 1. Базовая валидация
	if len(req.Items) == 0 {
		return "", fmt.Errorf("список товаров пуст")
	}

	dateInc, err := time.Parse("2006-01-02", req.DateIncoming)
	if err != nil {
		return "", fmt.Errorf("неверный формат даты (ожидается YYYY-MM-DD): %v", err)
	}

	// 2. Сборка доменной модели
	inv := invoices.Invoice{
		ID:             uuid.Nil, // Новый документ
		DocumentNumber: req.DocumentNumber,
		DateIncoming:   dateInc,
		SupplierID:     req.SupplierID,
		DefaultStoreID: req.StoreID,
		Status:         "NEW",
		Items:          make([]invoices.InvoiceItem, 0, len(req.Items)),
	}

	for _, itemDTO := range req.Items {
		sum := itemDTO.Amount.Mul(itemDTO.Price) // Пересчитываем сумму

		inv.Items = append(inv.Items, invoices.InvoiceItem{
			ProductID: itemDTO.ProductID,
			Amount:    itemDTO.Amount,
			Price:     itemDTO.Price,
			Sum:       sum,
		})
	}

	// 3. Отправка через клиент
	logger.Log.Info("Отправка накладной в RMS",
		zap.String("supplier", req.SupplierID.String()),
		zap.Int("items_count", len(inv.Items)))

	docNum, err := s.rmsClient.CreateIncomingInvoice(inv)
	if err != nil {
		return "", err
	}

	return docNum, nil
}
