package handler

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

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

type ServiceRequestHandler struct {
	logName string
}

func NewServiceRequestHandler(logName string) *ServiceRequestHandler {
	return &ServiceRequestHandler{
		logName: logName,
	}
}

func (serviceRequestHandler *ServiceRequestHandler) CreateServiceRequestHandler(c *gin.Context) {

	var response entity.CustomResponse
	db, err := util.GetDBConnection()

	if db != nil {
		defer db.Close()
	}

	if err != nil {
		response.Resultcode = 1
		response.Message = "Problem in establishing database connection"
		c.Set("response", response)
		return
	}

	body := entity.CreateRequestInput{}
	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
		}
		log.Println("ServiceRepository: CreateServiceRequest: promocode: ", body.Promo_Id, "srq_id :", body.Srq_Apartment_Id)
		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)
			log.Println("servicerequesthandler : CreateServiceRequest : imagename:", 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.CreateRequestInput)
	srqRepository := repository.ServiceRequestRepositoryInit(db)
	srqService := service.SrqServiceInit(srqRepository, nil, nil)
	log.Println("Servicerequesthandler : CreateServiceRequestHandler : servicerequestimage :lenghtofimage:", len(img_paths))
	response = srqService.CreateRequest(body, img_paths)

	c.Set("response", response)

}

func (serviceRequestHandler *ServiceRequestHandler) GetProblemDescriptionHandler(c *gin.Context) {
	var resp entity.CustomResponse
	db, err := util.GetDBConnection()
	if db != nil {
		defer db.Close()
	}
	if err != nil {
		resp.Resultcode = 1
		resp.Message = "Problem in establishing database connection"
		c.Set("response", resp)
		return
	}
	body := entity.GetProblemDescriptionInput{}

	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.GetProblemDescriptionInput)

	srqRepository := repository.ServiceRequestRepositoryInit(db)
	srqService := service.SrqServiceInit(srqRepository, nil, nil)
	resp = srqService.GetProblemDescription(body)
	c.Set("response", resp)
}

func (serviceRequestHandler *ServiceRequestHandler) FetchServiceRequestHandler(c *gin.Context) {
	var resp entity.CustomResponse
	db, err := util.GetDBConnection()
	if db != nil {
		defer db.Close()
	}
	if err != nil {
		resp.Resultcode = 1
		resp.Message = "Problem in establishing database connection"
		c.Set("response", resp)
		return
	}
	body := entity.FetchServiceRequestInput{}

	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.FetchServiceRequestInput)
	srqRepository := repository.ServiceRequestRepositoryInit(db)
	srqService := service.SrqServiceInit(srqRepository, nil, nil)
	resp = srqService.FetchServiceRequest(body)
	c.Set("response", resp)
}
func (serviceRequestHandler *ServiceRequestHandler) UpdateServiceRequestTechHandler(c *gin.Context) {

	var response entity.CustomResponse
	db, err := util.GetDBConnection()

	if db != nil {
		defer db.Close()
	}

	if err != nil {
		response.Resultcode = 1
		response.Message = "Problem in establishing database connection"
		c.Set("response", response)
		return
	}

	body := entity.UpdateSrqTechInput{}

	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_path_save, img_path string
	if body.Image != nil {
		file, err1 := c.FormFile("srq_image")

		if err1 != nil {
			c.AbortWithStatusJSON(http.StatusBadRequest, err1)
			return
		}
		if file == nil {
			errMsg := "No file uploaded for srq_image"
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": errMsg})
			return
		}

		timestamp := time.Now().Unix()
		imageName := fmt.Sprintf("%d%s", timestamp, file.Filename)
		// image_path_save = fmt.Sprintf("image/%s", imageName)
		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
		}
	}

	body = util.Default_tag(body).(entity.UpdateSrqTechInput)
	log.Println("tech", body)
	technicianRepository := repository.TechnicianRepositoryInit(db)
	technicianService := service.TechnicianServiceInit(technicianRepository)
	response = technicianService.UpdateServiceRequestTech(body, img_path)
	c.Set("response", response)

}

func (userHandler *UserHandler) UpdateServiceRequestHandler(c *gin.Context) {
	var updateServiceRequestResp entity.CustomResponse
	db, err := util.GetDBConnection()
	if db != nil {
		defer db.Close()
	}
	if err != nil {
		updateServiceRequestResp.Message = "Problem in establishing database connection " + err.Error()
		updateServiceRequestResp.Resultcode = 1 //error while processing inside the code
	}
	body := entity.UpdateServiceRequestInput{}
	// 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
			}
		}
	}
	

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

		if err1 != nil {
			c.AbortWithStatusJSON(http.StatusBadRequest, err1)
			return
		}

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

		if len(files) == 0 {
			errMsg := "No files uploaded for srq_img"
			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("image/%s", imageName)
			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 {
				log.Println(err2.Error())
				c.AbortWithStatusJSON(http.StatusBadRequest, err2)
				return
			}
			img_paths = append(img_paths, img_path)
		}
	}
	var timeslot string
	if body.Srq_Visit_Timeslot != "" {
		timeslot = body.Srq_Visit_Timeslot
	} else if body.Schedule_Slot != "" {
		timeslot = body.Schedule_Slot
	}
	body = util.Default_tag(body).(entity.UpdateServiceRequestInput)
	srqRepository := repository.ServiceRequestRepositoryInit(db)
	srqService := service.SrqServiceInit(srqRepository, nil, nil)
	updateServiceRequestResp = srqService.UpdateServiceRequestService(body.User_Id, body.Srq_Id, body.Status, body.Srq_Problem_Desc, timeslot, img_paths, body.Language_Code, body.Payment_Mode, body.Payment_Status)
	c.Set("response", updateServiceRequestResp)
}
