package service

import (
	"bpmsapi/dto"
	"bpmsapi/entity"
	"bpmsapi/repository"
	"database/sql"
	"fmt"
	"log"
	"strings"
)

type UserActions interface {
	FetchUser(mobno string) entity.CustomResponse
	InitConfig(userid int, apartmentid int, languagecode int) entity.CustomResponse
	FetchProblemCategory(input entity.FetchProblemCategoryInput) entity.CustomResponse
	GetAllUsers(input entity.GetAllUsersInput) entity.CustomResponse
	UpdateProfileService(User_Id int, User_Name string, User_Mobno int64, User_Emailid string, Alternate_No int64) entity.CustomResponse
}

type UserService struct {
	userRepository    *repository.UserRepository
	configRepository  *repository.ConfigRepository
	serviceRepository *repository.ServiceRepository
	srqRepository     *repository.ServiceRequestRepository
	promoRepository   *repository.PromoRepository
}

// auth-jwt
func UserServiceInit(userRepository *repository.UserRepository, configRepository *repository.ConfigRepository, serviceRepository *repository.ServiceRepository, srqRepository *repository.ServiceRequestRepository, promoRepository *repository.PromoRepository) *UserService {
	return &UserService{
		userRepository:    userRepository,
		configRepository:  configRepository,
		serviceRepository: serviceRepository,
		srqRepository:     srqRepository,
		promoRepository:   promoRepository,
	}
}


func (useServ *UserService) FetchUser(mobno string, languagecode int) (response entity.CustomResponse) {

	userResponse, merr := useServ.userRepository.FetchUserbyMobno(mobno)
	if merr != nil {
		if merr == sql.ErrNoRows {
			response.Resultcode = 1
			response.Message = "No user found. Please check mobile number or complete signup"
		} else {
			response.Message = dto.ErrorMessageforAuthenticateCustomer + merr.Error()
			response.Resultcode = 1
		}
	} else {
		if userResponse.Mapped_Apartments != nil {
			//log.Println(fmt.Sprint("(", *userResponse.Mapped_Apartments, ")"))
			//log.Println(useServ.configRepository)
			if *userResponse.Apartment_Id != "" {
				*userResponse.Mapped_Apartments = fmt.Sprint("(", *userResponse.Apartment_Id, ",", *userResponse.Mapped_Apartments, ")")
			} else {
				*userResponse.Mapped_Apartments = fmt.Sprint("(", *userResponse.Mapped_Apartments, ")")
			}

			userResponse.Mapped_Apartment_list, _ = useServ.configRepository.FetchApartmentsById(*userResponse.Mapped_Apartments, 1,mobno)
			

		} else {
			if userResponse.Apartment_Id != nil {
				apartments := fmt.Sprint("(", *userResponse.Apartment_Id, ")")
				userResponse.Mapped_Apartments = &apartments
				userResponse.Mapped_Apartment_list, _ = useServ.configRepository.FetchApartmentsById(*userResponse.Mapped_Apartments, 1, mobno)
			}
		}
		response.Resultcode = 0
		response.Message = "User details fetched successfully"
		response.Payload = userResponse
	}
	return response
}

func (useServ *UserService) InitConfig(userid int, apartmentid int, languagecode int) (response entity.CustomResponse) {
	var errMessage string
	var configResponse dto.InitConfigResponse
	bannerResponse, merr := useServ.configRepository.FetchBanners(apartmentid)
	if merr != nil {
		log.Println(merr.Error())
		errMessage = errMessage + merr.Error()
	} else {
		configResponse.Banners = &bannerResponse
	}
	messageResponse, err := useServ.configRepository.FetchApartmentMessages(apartmentid, languagecode)
	if err != nil {
		log.Println(err.Error())
		errMessage = errMessage + err.Error()
	} else {
		configResponse.Messages = &messageResponse
	}
	infoResponse, errIn := useServ.configRepository.FetchApartmentBasicInfo(apartmentid)
	if errIn != nil {
		log.Println(err.Error())
		errMessage = errMessage + errIn.Error()
	} else {
		configResponse.Basic_Info = &infoResponse
	}

	promoResponse, err := useServ.promoRepository.FetchUserActivePromocode(userid)
	if err != nil {
		log.Println(err.Error())
		errMessage = errMessage + err.Error()
	} else {
		configResponse.Promocode = promoResponse
	}

	serviceResponse, err := useServ.serviceRepository.FetchServiceList(apartmentid, languagecode)
	if err != nil {
		log.Println(err.Error())
		errMessage = errMessage + err.Error()
	} else {
		configResponse.Services = serviceResponse
		log.Println(configResponse.Services)
	}
	srqResponse, err := useServ.srqRepository.FetchOpenSRQByUser(userid, apartmentid,languagecode)
	if err != nil {
		log.Println(err.Error())
		errMessage = errMessage + err.Error()
	} else {
		configResponse.ActiveSRQ = srqResponse
	}
	if errMessage != "" {
		if strings.Contains(errMessage, "error") || strings.Contains(errMessage, "Error") {
			response.Resultcode = 1
			response.Message = errMessage
		}
	} else {
		response.Resultcode = 0
		response.Message = "User details fetched successfully"
	}
	response.Payload = configResponse
	return response
}

func (useServ *UserService) FetchProblemCategory(input entity.FetchProblemCategoryInput) (response entity.CustomResponse) {
	resp, err := useServ.userRepository.ProblemCategoryFetch(input)
	if err == nil {
		if len(resp) == 0 {
			response.Resultcode = 0
			response.Message = "No problem category found"
		} else {
			response.Resultcode = 0
			response.Message = dto.SuccessMessageSearchProblemCategory
			response.Payload = resp
		}
	} else {
		response.Resultcode = 1
		response.Message = dto.ErrorMessageSearchProblemCategory + err.Error()
	}

	return response
}

func (useServ *UserService) GetAllUsers(input entity.GetAllUsersInput) (response entity.CustomResponse) {
	resp, err := useServ.userRepository.FetchAllUsers(input)
	if err == nil {
		if input.Page > resp.Page {

			response.Resultcode = 0
			response.Message = "Invalid page number"
			return response

		} else if len(resp.User_Info) == 0 {
			response.Resultcode = 0
			response.Message = "No records found for this category"
			return response
		} else {
			response.Resultcode = 0
			response.Message = dto.SuccessMessageGetAllUsers
			response.Payload = resp
		}

	} else {
		response.Resultcode = 1
		response.Message = dto.ErrorMessageGetAllUsers + err.Error()
	}
	return response
}

func (useServ *UserService) UpdateProfileService(input entity.UpdateProfileInput, image string) (response entity.CustomResponse) {
	tx, errt := useServ.userRepository.Begin()
	if errt != nil {
		response.Resultcode = 1
		response.Message = errt.Error()
		return response
	}
	
	resp, err := useServ.userRepository.UpdateProfile(tx,input, image)
	if err != nil {
		tx.Rollback()
		response.Resultcode = 1
		response.Message = dto.ErrorMessageUpdateProfile + err.Error()
		return response
	}else{
		commitError := tx.Commit()
	if commitError != nil{
		response.Resultcode = 1
		response.Message = dto.ErrorMessageUpdateProfile + err.Error()
		return response
	} else {
		response.Resultcode = 0
		response.Message = dto.SuccessMessageUpdateProfile
		response.Payload = resp
		return response
	}
	}
}
