package service

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

type Configusecase interface {
	LoadStatelist(language int) entity.CustomResponse
	LoadCitylist(stateid int, language int) entity.CustomResponse
	LoadApartmentList(stateid int, cityid int, language int) entity.CustomResponse
	AddNewState(input entity.AddStateInput) entity.CustomResponse
	AddNewCity(input entity.AddCityInput) entity.CustomResponse
	AddAddress(address entity.AddAddressInput) entity.CustomResponse
	FetchService(input entity.FetchServicesInput) entity.CustomResponse
	AddFeedbackService(input entity.AddFeedback) entity.CustomResponse
	UpdateApartmentParamService(Apartment_Id int, Param_Key string, Param_Value string, PARAM_SUB string, Validity string, Action string, newimage string) entity.CustomResponse
}

type ConfigService struct {
	configRepository  *repository.ConfigRepository
	addressRepository *repository.AddressRepository
	serviceRepository *repository.ServiceRepository
}

// auth-jwt
func ConfigServiceInit(configRepository *repository.ConfigRepository, addressRepository *repository.AddressRepository, serviceRepository *repository.ServiceRepository) *ConfigService {
	return &ConfigService{
		configRepository:  configRepository,
		addressRepository: addressRepository,
		serviceRepository: serviceRepository,
	}
}

func (configServ *ConfigService) FetchService(input entity.FetchServicesInput) (response entity.CustomResponse) {
	serviceResponse, err := configServ.serviceRepository.FetchAllServices(input) //db (query execution in repository)
	if err == nil {
		response.Resultcode = 0
		response.Message = dto.SuccessMessageServiceFetch
		response.Payload = serviceResponse
	} else {
		response.Resultcode = 0
		response.Message = dto.ErrorMessageServiceFetch + err.Error()
	}

	return response
}

func (configServ *ConfigService) LoadStatelist(language int) (response entity.CustomResponse) {
	stateResponse, err := configServ.configRepository.FetchStates(language) //db (query execution in repository)
	if err == nil {
		response.Resultcode = 0
		response.Message = dto.SuccessMessageStatesFetch
		response.Payload = stateResponse
	} else {
		response.Resultcode = 0
		response.Message = dto.ErrorMessageStatesFetch + err.Error()
	}

	return response
}

func (configServ *ConfigService) AddAddress(address entity.AddAddressInput) (response entity.CustomResponse) {
	resp, err := configServ.addressRepository.AddAddress(address)
	if err != nil {
		log.Println("ConfigService: AddAddress: AddingAddress: Error: ", err.Error())
		response.Resultcode = 1
		response.Message = dto.ErrorMessageAddAddress + err.Error()
	} else {
		response.Resultcode = 0
		response.Message = dto.SuccessMessageAddAddress
		response.Payload = resp
	}
	return response
}

func (configServ *ConfigService) LoadCitylist(stateid int, language int) (response entity.CustomResponse) {
	stateResponse, err := configServ.configRepository.FetchCities(stateid, language)
	if err == nil {
		response.Resultcode = 0
		response.Message = dto.SuccessMessageCitiesFetch
		response.Payload = stateResponse
	} else {
		response.Resultcode = 0
		if err == sql.ErrNoRows {
			response.Message = "No Cities configured for the selected state"
		} else {
			response.Message = dto.ErrorMessageCitiesFetch
		}

	}
	return response
}

func (configServ *ConfigService) LoadApartmentList(stateid int, cityid int, language int) (response entity.CustomResponse) {
	stateResponse, err := configServ.configRepository.FetchApartments(stateid, cityid, language)
	if err == nil {
		response.Resultcode = 0
		response.Message = dto.SuccessMessageApartmentFetch
		response.Payload = stateResponse
	} else {
		response.Resultcode = 0
		if err == sql.ErrNoRows {
			response.Message = "No Apartments configured for the selected city"
		} else {
			response.Message = dto.ErrorMessageApartmentsFetch
		}

	}
	return response
}

func (configServ *ConfigService) AddFeedbackService(input entity.AddFeedback) (response entity.CustomResponse) {
	feedbackResponse, err := configServ.configRepository.AddFeedback(input)
	if err == nil {
		response.Resultcode = 0
		response.Message = dto.SuccessMessageAddFeedback
		response.Payload = feedbackResponse
	} else {
		response.Resultcode = 1
		if err == sql.ErrNoRows {
			response.Message = "No feedback added" + err.Error()
		} else {
			response.Message = dto.ErrorMessageAddFeedback + err.Error()
		}
	}
	return response
}

func (configServ *ConfigService) AddNewState(input entity.AddStateInput) (response entity.CustomResponse) {
	tx, errt := configServ.configRepository.Begin()
	if errt != nil {
		response.Resultcode = 1
		response.Message = errt.Error()
		return response

	}
	resp, err := configServ.configRepository.AddState(tx, input)
	if err != nil {
		tx.Rollback()
		response.Resultcode = 1
		response.Message = dto.ErrorMessageAddState + err.Error()
		return response
	}
	commitError := tx.Commit()
	if commitError != nil {
		response.Resultcode = 1
		response.Message = dto.ErrorMessageAddState + err.Error()
		return response
	} else {
		response.Resultcode = 0
		response.Message = dto.SuccessMessageAddState
		response.Payload = resp
		return response
	}

}

func (configServ *ConfigService) AddNewCity(input entity.AddCityInput) (response entity.CustomResponse) {
	tx, errt := configServ.configRepository.Begin()
	if errt != nil {
		response.Resultcode = 1
		response.Message = errt.Error()
		return response

	}
	resp, err := configServ.configRepository.AddCity(tx, input)
	if err != nil {
		tx.Rollback()
		response.Resultcode = 1
		response.Message = dto.ErrorMessageAddCity + err.Error()
		return response
	}
	commitError := tx.Commit()
	if commitError != nil {

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

		response.Resultcode = 0
		response.Message = dto.SuccessMessageAddCity
		response.Payload = resp
		return response
	}

}

func (configServ *ConfigService) SuperAdminDashboard(input entity.SuperAdminDashboardInput) (response entity.CustomResponse) {

	resp, err := configServ.configRepository.DashboardSuperAdmin(input)
	if err != nil {
		response.Resultcode = 1
		response.Message = dto.ErrorMessageSuperAdmDashboard + err.Error()
	} else {
		response.Resultcode = 0
		response.Message = dto.SuccessMessageSuperAdmDashboard
		response.Payload = resp
	}

	return response
}

func (configServ *ConfigService) UpdateApartmentParamService(Apartment_Id int, Param_Key string, Param_Value string, PARAM_SUB string, Validity string, Action string, newsImage string) (response entity.CustomResponse) {
	tx, errt := configServ.configRepository.Begin()
	if errt != nil {
		response.Resultcode = 1
		response.Message = errt.Error()
		return response

	}
	updateApartmentParamResponse, err := configServ.configRepository.UpdateApartmentParam(tx, Apartment_Id, Param_Key, Param_Value, PARAM_SUB, Validity, Action, newsImage)
	if err != nil {
		tx.Rollback()
		response.Resultcode = 1
		response.Message = dto.ErrorMessageUpdateApartmentParam + err.Error()
		return response
	}

	commitError := tx.Commit()
	if commitError != nil || commitError == sql.ErrNoRows {
		response.Resultcode = 1
		response.Message = dto.ErrorMessageUpdateApartmentParam + commitError.Error()
		return response
	} else {
		response.Resultcode = 0
		response.Message = dto.SuccessMessageUpdateApartmentParam
		response.Payload = updateApartmentParamResponse
		return response
	}
}
