package service

import (
	"errors"
	"narasi-ahli-be/app/module/agent/mapper"
	"narasi-ahli-be/app/module/agent/repository"
	"narasi-ahli-be/app/module/agent/request"
	"narasi-ahli-be/app/module/agent/response"

	"github.com/rs/zerolog"
)

type agentService struct {
	Repo repository.AgentRepository
	Log  zerolog.Logger
}

type AgentService interface {
	All(req request.AgentQueryRequest) ([]*response.AgentResponse, error)
	Show(id uint) (*response.AgentResponse, error)
	Save(req request.AgentCreateRequest) (*response.AgentResponse, error)
	Update(id uint, req request.AgentUpdateRequest) error
	Delete(id uint) error
	FindByAgentId(id string) (*response.AgentResponse, error)

}

func NewAgentService(repo repository.AgentRepository, log zerolog.Logger) AgentService {
	return &agentService{Repo: repo, Log: log}
}

func (_i *agentService) All(req request.AgentQueryRequest) (agents []*response.AgentResponse, err error) {
	results, err := _i.Repo.GetAll(req)
	if err != nil {
		return
	}

	for _, result := range results {
		agents = append(agents, mapper.AgentResponseMapper(result))
	}
	return
}

func (_i *agentService) Show(id uint) (*response.AgentResponse, error) {
	result, err := _i.Repo.FindById(id)
	if err != nil {
		return nil, errors.New("agent not found")
	}
	return mapper.AgentResponseMapper(result), nil
}

func (_i *agentService) FindByAgentId(agentId string) (*response.AgentResponse, error) {
	result, err := _i.Repo.FindByAgentId(agentId)
	if err != nil {
		return nil, errors.New("agent not found")
	}
	return mapper.AgentResponseMapper(result), nil
}

func (_i *agentService) Save(req request.AgentCreateRequest) (*response.AgentResponse, error) {
	entity := req.ToEntity()
	result, err := _i.Repo.Create(entity)
	if err != nil {
		return nil, err
	}
	return mapper.AgentResponseMapper(result), nil
}

func (_i *agentService) Update(id uint, req request.AgentUpdateRequest) error {
	_, err := _i.Repo.FindById(id)
	if err != nil {
		return errors.New("agent not found")
	}
	return _i.Repo.Update(id, req.ToMap())
}

func (_i *agentService) Delete(id uint) error {
	_, err := _i.Repo.FindById(id)
	if err != nil {
		return errors.New("agent not found")
	}
	return _i.Repo.Delete(id)
}
