package service

import (
	"errors"
	"narasi-ahli-be/app/database/entity/users"
	eduMapper "narasi-ahli-be/app/module/education_history/mapper"
	eduRepo "narasi-ahli-be/app/module/education_history/repository"
	eduReq "narasi-ahli-be/app/module/education_history/request"
	researchMapper "narasi-ahli-be/app/module/research_journals/mapper"
	researchRepo "narasi-ahli-be/app/module/research_journals/repository"
	researchReq "narasi-ahli-be/app/module/research_journals/request"
	userRepo "narasi-ahli-be/app/module/users/repository"
	"narasi-ahli-be/app/module/users/request"
	"narasi-ahli-be/app/module/users/response"
	workMapper "narasi-ahli-be/app/module/work_history/mapper"
	workRepo "narasi-ahli-be/app/module/work_history/repository"
	workReq "narasi-ahli-be/app/module/work_history/request"
	"narasi-ahli-be/utils/paginator"

	"github.com/rs/zerolog"
)

type UserExpertService interface {
	All(req request.UserExpertQueryRequest) ([]*response.UserExpertResponse, error)
	Show(id uint) (*response.UserExpertResponse, error)
}


type userExpertService struct {
	UserRepo     userRepo.UserExpertRepository
	WorkRepo     workRepo.WorkHistoryRepository
	EduRepo      eduRepo.EducationHistoryRepository
	ResearchRepo researchRepo.ResearchJournalsRepository
	Log          zerolog.Logger
}

func NewUserExpertService(
	userRepo userRepo.UserExpertRepository,
	workRepo workRepo.WorkHistoryRepository,
	eduRepo eduRepo.EducationHistoryRepository,
	researchRepo researchRepo.ResearchJournalsRepository,
	log zerolog.Logger,
) UserExpertService {
	return &userExpertService{
		UserRepo:     userRepo,
		WorkRepo:     workRepo,
		EduRepo:      eduRepo,
		ResearchRepo: researchRepo,
		Log:          log,
	}
}

func (s *userExpertService) All(
	req request.UserExpertQueryRequest,
) ([]*response.UserExpertResponse, error) {

	var users []*users.Users
	var err error


if s.UserRepo == nil {
	s.Log.Error().Msg("UserRepo IS NIL")
	return nil, errors.New("internal server error")
}


	// 🔥 pakai filter jika ada
	users, err = s.UserRepo.GetExperts(req)

	if err != nil {
		return nil, err
	}

	


	var results []*response.UserExpertResponse

workReq := workReq.WorkHistoryQueryRequest{
    Pagination: &paginator.Pagination{
        Page:  1,
        Limit: 100, 
    },
}

eduReq := eduReq.EducationHistoryQueryRequest{
	Pagination: &paginator.Pagination{Page:  1,
        Limit: 100, },
}

researchReq := researchReq.ResearchJournalsQueryRequest{
	Pagination: &paginator.Pagination{Page:  1,
        Limit: 100, },
}

	for _, user := range users {

		s.Log.Info().
	Uint("user_id", user.ID).
	Msg("Fetching relations for user")
		works, _, _ := s.WorkRepo.GetAll(user.ID, workReq)
		educations, _, _ := s.EduRepo.GetAll(user.ID, eduReq)
		researches, _, _ := s.ResearchRepo.GetAll(user.ID, researchReq)

		s.Log.Info().
	Int("work_count", len(works)).
	Int("edu_count", len(educations)).
	Int("research_count", len(researches)).
	Msg("Relation result count")

		res := &response.UserExpertResponse{
			ID:         user.ID,
			Username:   user.Username,
			Email:      user.Email,
			Fullname:   user.Fullname,
			Phone:      user.PhoneNumber,
			LastJob:    user.LastJobTitle,
			IsActive:   user.IsActive,
			CreatedAt: user.CreatedAt,
		}

		for _, w := range works {
			res.WorkHistories = append(
				res.WorkHistories,
				workMapper.WorkHistoryResponseMapper(w),
			)
		}

		for _, e := range educations {
			res.EducationHistories = append(
				res.EducationHistories,
				eduMapper.EducationHistoryResponseMapper(e),
			)
		}

		for _, r := range researches {
			res.ResearchJournals = append(
				res.ResearchJournals,
				researchMapper.ResearchJournalsResponseMapper(r),
			)
		}

		results = append(results, res)
	}

	return results, nil
}

func (s *userExpertService) Show(id uint) (*response.UserExpertResponse, error) {
	user, err := s.UserRepo.FindExpertByID(id)
	if err != nil {
		return nil, errors.New("expert not found")
	}

	req := workReq.WorkHistoryQueryRequest{}
	researchReq := researchReq.ResearchJournalsQueryRequest{}
	eduReq := eduReq.EducationHistoryQueryRequest{}

	works, _, _ := s.WorkRepo.GetAll(id,req)
	educations, _, _ := s.EduRepo.GetAll(id, eduReq)
	researches, _, _ := s.ResearchRepo.GetAll(id, researchReq)

	res := &response.UserExpertResponse{
		ID:         user.ID,
		Username:   user.Username,
		Email:      user.Email,
		Fullname:   user.Fullname,
		Phone:      user.PhoneNumber,
		LastJob:    user.LastJobTitle,
		IsActive:   user.IsActive,
		CreatedAt: user.CreatedAt,
	}

	for _, w := range works {
		res.WorkHistories = append(res.WorkHistories, workMapper.WorkHistoryResponseMapper(w))
	}
	for _, e := range educations {
		res.EducationHistories = append(res.EducationHistories, eduMapper.EducationHistoryResponseMapper(e))
	}
	for _, r := range researches {
		res.ResearchJournals = append(res.ResearchJournals, researchMapper.ResearchJournalsResponseMapper(r))
	}

	return res, nil
}
