package service

import (
	"context"
	"time"

	"erp-mvp/core-service/internal/models"
	"erp-mvp/core-service/internal/repository"

	"github.com/google/uuid"
	"github.com/sirupsen/logrus"
)

type ItemService interface {
	CreateItem(ctx context.Context, orgID uuid.UUID, req *models.CreateItemRequest) (*models.Item, error)
	GetItem(ctx context.Context, id uuid.UUID, orgID uuid.UUID) (*models.Item, error)
	GetItems(ctx context.Context, orgID uuid.UUID) ([]*models.Item, error)
	UpdateItem(ctx context.Context, id uuid.UUID, orgID uuid.UUID, req *models.CreateItemRequest) (*models.Item, error)
	DeleteItem(ctx context.Context, id uuid.UUID, orgID uuid.UUID) error
	SearchItems(ctx context.Context, orgID uuid.UUID, query string, category string) ([]*models.Item, error)
}

type itemService struct {
	itemRepo repository.ItemRepository
	logger   *logrus.Logger
}

func NewItemService(itemRepo repository.ItemRepository) ItemService {
	return &itemService{
		itemRepo: itemRepo,
		logger:   logrus.New(),
	}
}

func (s *itemService) CreateItem(ctx context.Context, orgID uuid.UUID, req *models.CreateItemRequest) (*models.Item, error) {
	s.logger.Info("Creating item for organization: ", orgID)

	item := &models.Item{
		ID:             uuid.New(),
		OrganizationID: orgID,
		Name:           req.Name,
		Description:    req.Description,
		Category:       req.Category,
		CreatedAt:      time.Now(),
	}

	if err := s.itemRepo.Create(ctx, item); err != nil {
		s.logger.Error("Failed to create item: ", err)
		return nil, err
	}

	s.logger.Info("Item created successfully: ", item.ID)
	return item, nil
}

func (s *itemService) GetItem(ctx context.Context, id uuid.UUID, orgID uuid.UUID) (*models.Item, error) {
	s.logger.Info("Getting item: ", id, " for organization: ", orgID)

	item, err := s.itemRepo.GetByID(ctx, id, orgID)
	if err != nil {
		s.logger.Error("Failed to get item: ", err)
		return nil, err
	}

	return item, nil
}

func (s *itemService) GetItems(ctx context.Context, orgID uuid.UUID) ([]*models.Item, error) {
	s.logger.Info("Getting all items for organization: ", orgID)

	items, err := s.itemRepo.GetByOrganization(ctx, orgID)
	if err != nil {
		s.logger.Error("Failed to get items: ", err)
		return nil, err
	}

	return items, nil
}

func (s *itemService) UpdateItem(ctx context.Context, id uuid.UUID, orgID uuid.UUID, req *models.CreateItemRequest) (*models.Item, error) {
	s.logger.Info("Updating item: ", id, " for organization: ", orgID)

	// Сначала получаем существующий товар
	item, err := s.itemRepo.GetByID(ctx, id, orgID)
	if err != nil {
		s.logger.Error("Failed to get item for update: ", err)
		return nil, err
	}

	// Обновляем поля
	item.Name = req.Name
	item.Description = req.Description
	item.Category = req.Category

	if err := s.itemRepo.Update(ctx, item); err != nil {
		s.logger.Error("Failed to update item: ", err)
		return nil, err
	}

	s.logger.Info("Item updated successfully: ", item.ID)
	return item, nil
}

func (s *itemService) DeleteItem(ctx context.Context, id uuid.UUID, orgID uuid.UUID) error {
	s.logger.Info("Deleting item: ", id, " for organization: ", orgID)

	if err := s.itemRepo.Delete(ctx, id, orgID); err != nil {
		s.logger.Error("Failed to delete item: ", err)
		return err
	}

	s.logger.Info("Item deleted successfully: ", id)
	return nil
}

func (s *itemService) SearchItems(ctx context.Context, orgID uuid.UUID, query string, category string) ([]*models.Item, error) {
	s.logger.Info("Searching items for organization: ", orgID, " query: ", query, " category: ", category)

	items, err := s.itemRepo.Search(ctx, orgID, query, category)
	if err != nil {
		s.logger.Error("Failed to search items: ", err)
		return nil, err
	}

	return items, nil
}
