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 AuthenticationHandler struct {
	logName string
}

func NewAuthHandler(logName string) *AuthenticationHandler {
	return &AuthenticationHandler{
		logName: logName,
	}
}

func (authHandler *AuthenticationHandler) VerifyOTPHandler(c *gin.Context) {
	var otpResp entity.CustomResponse
	redisClient := util.GetRedisConnection()
	db, err := util.GetDBConnection()
	//defer redisClient.Close()
	if db != nil {
		defer db.Close()
	}

	if redisClient != nil {
		defer redisClient.Close()
	}
	if err != nil {
		otpResp.Message = "Problem in Database connection. Please try again " + err.Error()
		otpResp.Resultcode = 1
		c.Set("response", otpResp)
		return

	}
	body := entity.VerifyOTPInput{}
	// 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
	}
	otpRepository := repository.OTPRepositoryInit(redisClient)
	//userRepository := repository.UserRepositoryInit(db)
	//notification := repository.NotificationRepositoryInit(db)
	authService := service.AuthenticateServiceInit(nil, nil, otpRepository, nil, nil)
	otpResp = authService.VerifyOTPCustomerService(body.Mobno, int64(body.OTP))
	c.Set("response", otpResp)
}

func (authHandler *AuthenticationHandler) AuthenticateAdminHandler(c *gin.Context) {
	var response entity.CustomResponse
	db, err := util.GetDBConnection()
	redisClient := util.GetRedisConnection()
	if db != nil {
		defer db.Close()
	}
	if redisClient != nil {
		defer redisClient.Close()
	}
	if err != nil {
		response.Message = "Problem in Database connection. Please try again"
		response.Resultcode = 1
		c.Set("response", response)
		return
	}

	log.Println(redisClient)

	body := entity.AdminAuthInput{}
	// using BindJson method to serialize body with struct
	if err := c.ShouldBind(&body); err != nil {
		c.AbortWithError(http.StatusBadRequest, err)
		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.AdminAuthInput)

	//userRepository := repository.UserRepositoryInit(db)
	notification := repository.NotificationRepositoryInit(db)
	adminRepository := repository.AdminRepositoryInit(db)
	otpRepository := repository.OTPRepositoryInit(redisClient)
	authService := service.AuthenticateServiceInit(notification, nil, otpRepository, adminRepository, nil)
	response = authService.AuthenticateAdminService(body.Mobno, body.Language_Code)
	fmt.Print(response)
	//db.Close()

	c.Set("response", response)
}

func (authHandler *AuthenticationHandler) AuthenticateCustomerHandler(c *gin.Context) {
	var response entity.CustomResponse
	db, err := util.GetDBConnection()
	redisClient := util.GetRedisConnection()
	if db != nil {
		defer db.Close()
	}
	if redisClient != nil {
		defer redisClient.Close()
	}
	//body = util.Default_tag(body).(entity.UserAuthInput)
	if err != nil {
		response.Message = "Problem in Database connection. Please try again"
		response.Resultcode = 1
		c.Set("response", response)
		return
	}
	log.Println(redisClient)

	body := entity.UserAuthInput{}
	// 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
		//c.AbortWithError(http.StatusBadRequest, err)
		//return
	}

	userRepository := repository.UserRepositoryInit(db)
	notification := repository.NotificationRepositoryInit(db)
	configuration := repository.ConfigRepositoryInit(db)
	otpRepository := repository.OTPRepositoryInit(redisClient)
	authService := service.AuthenticateServiceInit(notification, userRepository, otpRepository, nil, configuration)
	response = authService.AuthenticateCustomerService(body.Mobno)
	fmt.Print(response)
	//db.Close()

	c.Set("response", response)
}
