package handler

import (
	"bpmsapi/entity"
	"bpmsapi/repository"
	"bpmsapi/service"
	"bpmsapi/util"
	"fmt"
	"io"
	"time"

	"log"
	"net/http"

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

type AdminHandler struct {
	logName string
}

func NewAdminHandler(logName string) *AdminHandler {
	return &AdminHandler{
		logName: logName,
	}
}

func (adminHandler *AdminHandler) SignupAdminHandler(c *gin.Context) {
	var Response entity.CustomResponse
	db, err := util.GetDBConnection()
	if db != nil {
		defer db.Close()
	}
	if err != nil {
		Response.Message = "Problem in establishing database connection " + err.Error()
		Response.Resultcode = 1 //error while processing inside the code
		c.Set("response", Response)
	}
	body := entity.SignUpAdminInput{}
	// using ShouldBindJSON method to serialize body with struct
	if err := c.ShouldBind(&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.SignUpAdminInput)

	var img_path, img_path_save string
	if body.Photo != nil {
		file, err1 := c.FormFile("photo")

		if err1 != nil {
			log.Println(err1.Error())
			c.AbortWithStatusJSON(http.StatusBadRequest, err1)
			return
		}
		if file == nil {
			errMsg := "No file uploaded for Photo"
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": errMsg})
			return
		}
		timestamp := time.Now().Unix()
		imageName1 := fmt.Sprintf("%d%s", timestamp, file.Filename)
		// img_path = fmt.Sprintf("image/%s", imageName1)
		img_path = fmt.Sprintf("http://151.106.120.127/bashyam/assets/Profile/%s", imageName1)
		img_path_save = fmt.Sprintf("./var/www/html/bashyam/assets/Profile/%s", imageName1)

		if err2 := c.SaveUploadedFile(file, img_path_save); err != nil {
			// log.Println(err2.Error())
			c.AbortWithStatusJSON(http.StatusBadRequest, err2)
			return
		}
	}
	rolerepository := repository.RoleRepositoryInit(db)
	adminrepository := repository.AdminRepositoryInit(db)
	servicerepository := repository.ServiceRepositoryInit(db)
	commonRepository := repository.ConfigRepositoryInit(db)
	adminService := service.AdminServiceInit(nil, nil, nil, adminrepository, rolerepository, servicerepository, commonRepository)
	Response = adminService.SignupAdminService(body, img_path)
	c.Set("response", Response)
}

func (validateHandler *AdminHandler) ValidateCustomerHandler(c *gin.Context) {
	var validateresp entity.CustomResponse
	db, errd := util.GetDBConnection()
	if db != nil {
		defer db.Close()
	}
	if errd != nil {
		validateresp.Message = "Problem in establishing database connection " + errd.Error()
		validateresp.Resultcode = 1
	}
	body := entity.ValidateCustomer{}
	// using BindJson method to serialize body with struct
	if err := c.ShouldBindJSON(&body); err != nil && err != io.EOF {
		fmt.Print(err.Error())
		log.Println(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
			}
		}
	}

	//otpRepository := repository.OTPRepositoryInit(redisClient)
	userRepository := repository.UserRepositoryInit(db)
	//adminRepository := repository.AdminRepositoryInit(db)
	//notification := repository.NotificationRepositoryInit(db)
	validateService := service.AdminServiceInit(nil, userRepository, nil, nil, nil, nil, nil)
	validateresp = validateService.ValidateCustomerService(body)
	c.Set("response", validateresp)
}

func (adminHandler *AdminHandler) GetAdminHandler(c *gin.Context) {
	db, err := util.GetDBConnection()
	var getAdminResp entity.CustomResponse
	if db != nil {
		defer db.Close()
	}
	if err != nil {
		getAdminResp.Message = "Problem in establishing database connection " + err.Error()
		getAdminResp.Resultcode = 1
		return
	}
	body := entity.GetAdminListInput{}
	// using BindJson method to serialize body with struct
	if err := c.Bind(&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
	}
	body = util.Default_tag(body).(entity.GetAdminListInput)
	//userRepository := repository.UserRepositoryInit(db)
	//notification := repository.NotificationRepositoryInit(db)
	adminRepository := repository.AdminRepositoryInit(db)
	getAdminService := service.AdminServiceInit(nil, nil, nil, adminRepository, nil, nil, nil)
	getAdminResp = getAdminService.GetAdminListService(body)

	c.Set("response", getAdminResp)
}

func (adminHandler *AdminHandler) FetchTechnicianHandler(c *gin.Context) {
	var fetchTechnicianResp entity.CustomResponse
	db, err := util.GetDBConnection()
	if db != nil {
		defer db.Close()
	}
	//body = util.Default_tag(body).(entity.UserAuthInput)
	if err != nil {
		fetchTechnicianResp.Message = "Problem in Database connection. Please try again"
		fetchTechnicianResp.Resultcode = 1
		c.Set("response", fetchTechnicianResp)
		return
	}

	body := entity.FetchTechnicianInput{}
	// using BindJson method to serialize body with struct
	if err := c.Bind(&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
	}
	body = util.Default_tag(body).(entity.FetchTechnicianInput)
	technicianRepository := repository.TechnicianRepositoryInit(db)
	fetchTechnicianService := service.TechnicianServiceInit(technicianRepository)
	fetchTechnicianResp = fetchTechnicianService.FetchTechnicianService(body)
	c.Set("response", fetchTechnicianResp)
}

func (adminHandler *AdminHandler) UpdateCostHandler(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"
		response.Resultcode = 1
		c.Set("response", response)
		return
	}
	body := entity.UpdateSrqCostInput{}
	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.UpdateSrqCostInput)
	adminRepository := repository.AdminRepositoryInit(db)
	adminService := service.AdminServiceInit(nil, nil, nil, adminRepository, nil, nil, nil)
	response = adminService.UpdateSrqCost(body)
	c.Set("response", response)
}

func (adminHandler *AdminHandler) CreateChildServiceRequestHandler(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"
		response.Resultcode = 1
		c.Set("response", response)
		return
	}

	body := entity.CreateChildServiceRequestInput{}
	if err := c.ShouldBind(&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
			}
		}
	}

	var img_paths []string
	if body.Srq_Image != nil {
		form, err1 := c.MultipartForm()

		if err1 != nil {
			c.AbortWithStatusJSON(http.StatusBadRequest, err1)
			return
		}
		files := form.File["srq_img"]
		if len(files) == 0 {
			errMsg := "No files uploaded for srq_img"
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": errMsg})
			return
		}
		if len(files) > 3 {
			errMsg := "The maximum number of images you can upload is three"
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": errMsg})
			return
		}

		for _, file := range files {
			timestamp := time.Now().Unix()
			imageName := fmt.Sprintf("%d%s", timestamp, file.Filename)
			img_path := fmt.Sprintf("http://151.106.120.127/bashyam/assets/srq_image/%s", imageName)
			img_path_save := fmt.Sprintf("./var/www/html/bashyam/assets/srq_image/%s", imageName)

			if err2 := c.SaveUploadedFile(file, img_path_save); err != nil {
				c.AbortWithStatusJSON(http.StatusBadRequest, err2)
				return
			}
			img_paths = append(img_paths, img_path)
		}
	}
	body = util.Default_tag(body).(entity.CreateChildServiceRequestInput)

	adminRepository := repository.AdminRepositoryInit(db)
	adminService := service.AdminServiceInit(nil, nil, nil, adminRepository, nil, nil, nil)
	response = adminService.CreateChildServiceRequest(body, img_paths)
	c.Set("response", response)

}

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

	body := entity.UpdateServiceRequestAdminInput{}
	// using BindJson method to serialize body with struct
	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
	}
	body = util.Default_tag(body).(entity.UpdateServiceRequestAdminInput)
	updateSrqAdminRepository := repository.AdminRepositoryInit(db)
	updateSrqAdminService := service.SrqServiceInit(nil, nil, updateSrqAdminRepository)
	updateServiceRequestAdminResp = updateSrqAdminService.UpdateServiceRequestAdminService(body)
	log.Println("input check")
	log.Println("adminid", body.Adm_Id)
	log.Println("techid", body.Technician_Id)
	log.Println("admincomment", body.Admin_Comments)
	log.Println("time", body.Srq_Visit_Timeslot)
	log.Println("mode", body.Payment_Mode)
	log.Println("assign", body.Assign)
	log.Println("action", body.Action)
	log.Println("olds", body.Old_status)
	log.Println("news", body.New_status)
	c.Set("response", updateServiceRequestAdminResp)
}

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

	body := entity.AdminDashboardInput{}
	// using BindJson method to serialize body with struct
	if err := c.Bind(&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
	}
	adminDashboardRepository := repository.AdminRepositoryInit(db)
	adminDashboardService := service.AdminServiceInit(nil, nil, nil, adminDashboardRepository, nil, nil, nil)
	adminDashboardResp = adminDashboardService.AdminDashboardService(body)

	c.Set("response", adminDashboardResp)
}
