package handler

import (
	"bpmsapi/entity"
	"bpmsapi/repository"
	"bpmsapi/service"
	"bpmsapi/util"
	"fmt"
	"io"
	"log"
	"net/http"

	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
)

type CommonHandler struct {
	logName string
}

func NewCommonHandler(logName string) *CommonHandler {
	return &CommonHandler{
		logName: logName,
	}
}

func (commonHandler *CommonHandler) SignupHandler(c *gin.Context) {
	var stateResp entity.CustomResponse
	db, err := util.GetDBConnection()
	if db != nil {
		defer db.Close()
	}
	if err != nil {
		stateResp.Message = "Problem in Database connection. Please try again " + err.Error()
		stateResp.Resultcode = 1
		c.Set("response", stateResp)
		return

	}

	body := entity.Signupuser{}
	if err := c.ShouldBindJSON(&body); err != nil && err != io.EOF {
		log.Println(err.Error())
		fmt.Print(err.Error())
		switch err.(type) {
		case validator.ValidationErrors:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
				"error": err.(validator.ValidationErrors).Translate(util.Trans),
			})
		default:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
		return
	} else {
		if err != nil && err == io.EOF {
			fmt.Println(err.Error())
			if util.CheckRequired(body) {
				c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Mandatory input fields missing"})
				return
			}
		}
	}

	log.Println("email_id", body.User_Emailid)
	log.Println("door_no", body.Doorno)

	userRepository := repository.UserRepositoryInit(db)
	authService := service.AuthenticateServiceInit(nil, userRepository, nil, nil, nil)
	stateResp = authService.InsertCustomerService(body)
	c.Set("response", stateResp)
}

func (commonHandler *CommonHandler) FetchServiceHandler(c *gin.Context) {
	var stateResp entity.CustomResponse
	body := entity.FetchServicesInput{}
	// using BindJson method to serialize body with struct
	if err := c.ShouldBind(&body); err != nil && err != io.EOF {
		//fmt.Print(err.Error())
		//c.AbortWithError(http.StatusBadRequest, err)
		switch err.(type) {
		case validator.ValidationErrors:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
				"error": err.(validator.ValidationErrors).Translate(util.Trans),
			})
		default:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
		return
	}
	body = util.Default_tag(body).(entity.FetchServicesInput)
	db, err := util.GetDBConnection()
	if db != nil {
		defer db.Close()
	}
	if err != nil {
		log.Println("Commonhandler: AddAddressHandler: InitializingDB: Error ", err.Error())
	}
	serviceRepository := repository.ServiceRepositoryInit(db)
	configService := service.ConfigServiceInit(nil, nil, serviceRepository)
	stateResp = configService.FetchService(body)
	c.Set("response", stateResp)
}

func (commonHandler *CommonHandler) AddAddressHandler(c *gin.Context) {
	var stateResp entity.CustomResponse
	body := entity.AddAddressInput{}
	// using BindJson method to serialize body with struct
	if err := c.ShouldBindJSON(&body); err != nil && err != io.EOF {
		//fmt.Print(err.Error())
		//c.AbortWithError(http.StatusBadRequest, err)
		switch err.(type) {
		case validator.ValidationErrors:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
				"error": err.(validator.ValidationErrors).Translate(util.Trans),
			})
		default:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
		return
	} else {
		if err != nil && err == io.EOF {
			if util.CheckRequired(body) {
				c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Mandatory input fields missing"})
				return
			}
		}
	}
	db, err := util.GetDBConnection()
	if db != nil {
		defer db.Close()
	}
	if err != nil {
		log.Println("Commonhandler: AddAddressHandler: InitializingDB: Error ", err.Error())
	}
	addressRepository := repository.AddressRepositoryInit(db)
	configService := service.ConfigServiceInit(nil, addressRepository, nil)
	stateResp = configService.AddAddress(body)
	c.Set("response", stateResp)
}

func (commonHandler *CommonHandler) StateListHandler(c *gin.Context) {
	db, err := util.GetDBConnection()
	var stateResp entity.CustomResponse
	if err != nil {
		stateResp.Resultcode = 1
		stateResp.Message = "Problem in establishing database connection " + err.Error()
		c.Set("response", stateResp)
		return
	}
	if db != nil {
		defer db.Close()
	}

	body := entity.StateListInput{}
	//body = util.Default_tag(body).(entity.StateListInput)
	// using BindJson method to serialize body with struct
	//if body
	if err := c.Bind(&body); err != nil && err != io.EOF {
		fmt.Print(err.Error())
		//c.AbortWithError(http.StatusBadRequest, err)
		switch err.(type) {
		case validator.ValidationErrors:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
				"error": err.(validator.ValidationErrors).Translate(util.Trans),
			})
		default:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
		return
	} /*else {
		if err != nil && err == io.EOF {
			if util.CheckRequired(body) {
				c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Mandatory input fields missing"})
				return
			}
		}
	}*/
	body = util.Default_tag(body).(entity.StateListInput)
	if err != nil {
		stateResp.Message = "Problem in Database connection. Please try again"
		stateResp.Resultcode = 1 //error while processing inside the code
	} else {
		//userRepository := repository.UserRepositoryInit(db)
		//notification := repository.NotificationRepositoryInit(db)
		configRepository := repository.ConfigRepositoryInit(db)
		configService := service.ConfigServiceInit(configRepository, nil, nil)
		stateResp = configService.LoadStatelist(body.Language_Code)
	}
	c.Set("response", stateResp)
}

func (commonHandler *CommonHandler) CityListHandler(c *gin.Context) {
	var cityResp entity.CustomResponse
	db, err := util.GetDBConnection()
	if err != nil {
		cityResp.Resultcode = 1
		cityResp.Message = "Problem in establishing database connection"
		c.Set("response", cityResp)
		return
	}
	if db != nil {
		defer db.Close()
	}
	body := entity.CityListInput{}
	// using BindJson method to serialize body with struct

	if err := c.Bind(&body); err != nil {
		switch errTyp := err.(type) {
		case validator.ValidationErrors:
			log.Print(errTyp)
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
				"error": err.(validator.ValidationErrors).Translate(util.Trans),
			})
		default:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
		return
	}
	body = util.Default_tag(body).(entity.CityListInput)
	if err != nil {
		cityResp.Message = "Problem in Database connection. Please try again"
		cityResp.Resultcode = 1
	} else {
		//userRepository := repository.UserRepositoryInit(db)
		//notification := repository.NotificationRepositoryInit(db)
		configRepository := repository.ConfigRepositoryInit(db)
		configService := service.ConfigServiceInit(configRepository, nil, nil)
		cityResp = configService.LoadCitylist(body.State_Id, body.Language_Code)
	}
	c.Set("response", cityResp)
}

func (commonHandler *CommonHandler) AddStateHandler(c *gin.Context) {
	var response entity.CustomResponse
	db, err := util.GetDBConnection()
	if db != nil {
		defer db.Close()
	}
	if err != nil {
		response.Message = "Problem in Database connection. Please try again " + err.Error()
		response.Resultcode = 1
		c.Set("response", response)
		return

	}

	body := entity.AddStateInput{}

	if err := c.ShouldBindJSON(&body); err != nil && err != io.EOF {
		switch err.(type) {
		case validator.ValidationErrors:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
				"error": err.(validator.ValidationErrors).Translate(util.Trans),
			})
		default:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
				"error": err.Error()})
		}

		return

	} else {
		if err != nil && err == io.EOF {
			if util.CheckRequired(body) {
				c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Mandatory input fields missing"})
				return
			}
		}
	}
	body = util.Default_tag(body).(entity.AddStateInput)

	configRepository := repository.ConfigRepositoryInit(db)
	configService := service.ConfigServiceInit(configRepository, nil, nil)
	response = configService.AddNewState(body)

	c.Set("response", response)
}

func (commonHandler *CommonHandler) ApartmentListHandler(c *gin.Context) {
	var cityResp entity.CustomResponse
	db, err := util.GetDBConnection()
	if db != nil {
		defer db.Close()
	}
	if err != nil {
		cityResp.Message = "Problem in Database connection. Please try again " + err.Error()
		cityResp.Resultcode = 1
		c.Set("response", cityResp)
		return

	}

	body := entity.ApartmentListInput{}
	// using BindJson method to serialize body with struct
	if err := c.Bind(&body); err != nil {
		switch err.(type) {
		case validator.ValidationErrors:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
				"error": err.(validator.ValidationErrors).Translate(util.Trans),
			})
		default:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
		return
	}
	body = util.Default_tag(body).(entity.ApartmentListInput)
	if err != nil {
		cityResp.Message = "Problem in Database connection. Please try again"
		cityResp.Resultcode = 1
	} else {
		//userRepository := repository.UserRepositoryInit(db)
		//notification := repository.NotificationRepositoryInit(db)
		configRepository := repository.ConfigRepositoryInit(db)
		configService := service.ConfigServiceInit(configRepository, nil, nil)
		cityResp = configService.LoadApartmentList(body.State_Id, body.City_Id, body.Language_Code)
	}
	c.Set("response", cityResp)
}

func (commonHandler *CommonHandler) AddFeedbackHandler(c *gin.Context) {
	var feedbackResp entity.CustomResponse
	db, err := util.GetDBConnection()
	if db != nil {
		defer db.Close()
	}
	if err != nil {
		feedbackResp.Message = "Problem in establishing database connection " + err.Error()
		feedbackResp.Resultcode = 1 //error while processing inside the code
		c.Set("response", feedbackResp)
		return
	}
	body := entity.AddFeedback{}
	// using ShouldBindJSON method to serialize body with struct
	if err := c.ShouldBindJSON(&body); err != nil && err != io.EOF {
		log.Println(err.Error())
		fmt.Print(err.Error())
		switch err.(type) {
		case validator.ValidationErrors:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
				"error": err.(validator.ValidationErrors).Translate(util.Trans),
			})
		default:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
		return
	} else {
		if err != nil && err == io.EOF {
			if util.CheckRequired(body) {
				c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Mandatory input fields missing"})
				return
			}
		}
	}
	body = util.Default_tag(body).(entity.AddFeedback)
	configRepository := repository.ConfigRepositoryInit(db)
	commonService := service.ConfigServiceInit(configRepository, nil, nil)
	feedbackResp = commonService.AddFeedbackService(body)
	c.Set("response", feedbackResp)
}

func (commonHandler *CommonHandler) AddCityHandler(c *gin.Context) {
	var response entity.CustomResponse
	db, err := util.GetDBConnection()
	if db != nil {
		defer db.Close()
	}
	if err != nil {
		response.Message = "Problem in Database connection. Please try again " + err.Error()
		response.Resultcode = 1
		c.Set("response", response)
		return

	}

	body := entity.AddCityInput{}

	if err := c.ShouldBindJSON(&body); err != nil && err != io.EOF {
		switch err.(type) {
		case validator.ValidationErrors:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
				"error": err.(validator.ValidationErrors).Translate(util.Trans),
			})
		default:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
				"error": err.Error()})
		}

		return

	} else {
		if err != nil && err == io.EOF {
			if util.CheckRequired(body) {
				c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Mandatory input fields missing"})
				return
			}
		}
	}
	body = util.Default_tag(body).(entity.AddCityInput)

	configRepository := repository.ConfigRepositoryInit(db)
	configService := service.ConfigServiceInit(configRepository, nil, nil)
	response = configService.AddNewCity(body)

	c.Set("response", response)
}

func (commonHandler *CommonHandler) SuperAdminDashboardHandler(c *gin.Context) {

	var response entity.CustomResponse
	db, err := util.GetDBConnection()
	if db != nil {
		defer db.Close()
	}
	if err != nil {
		response.Message = "Problem in Database connection. Please try again " + err.Error()
		response.Resultcode = 1
		c.Set("response", response)
		return

	}

	body := entity.SuperAdminDashboardInput{}

	if err := c.Bind(&body); err != nil {
		switch err.(type) {
		case validator.ValidationErrors:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
				"error": err.(validator.ValidationErrors).Translate(util.Trans),
			})
		default:
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
				"error": err.Error()})
		}

		return

	}

	body = util.Default_tag(body).(entity.SuperAdminDashboardInput)

	configRepository := repository.ConfigRepositoryInit(db)
	configService := service.ConfigServiceInit(configRepository, nil, nil)
	response = configService.SuperAdminDashboard(body)

	c.Set("response", response)
}
