package repository

import (
	//"bpmsapi/entity"
	"bpmsapi/dto"
	"bpmsapi/entity"
	"errors"
	"log"
	"strings"

	"github.com/jmoiron/sqlx"
)

type ServiceActions interface {
	FetchServiceList(apartmentid int, languagecode int) ([]entity.Service, error)
	FetchAllServices(input entity.FetchServicesInput) ([]entity.Service, error)
	AddService(tx *sqlx.Tx, input entity.AddServiceInput, img_path1 string, img_path2 string) (serviceList []entity.Service, errr error)
	ProblemCategoryUpdate(input entity.UpdateProblemCategoryInput) ([]entity.UpdateProblemCategory, error)
}

type ServiceRepository struct {
	db *sqlx.DB
}

// auth-jwt
func ServiceRepositoryInit(db *sqlx.DB) *ServiceRepository {
	return &ServiceRepository{
		db: db,
	}
}

func (srvRepo *ServiceRepository) Begin() (*sqlx.Tx, error) {
	tx, err := srvRepo.db.Beginx()
	if err != nil {
		return nil, err
	}
	return tx, nil
}

func (serviceRepo *ServiceRepository) FetchServiceList(apartmentid int, languagecode int) (services []entity.Service, err error) {
	err = serviceRepo.db.Select(&services, "select s.Service_Id, s.Service_Description, s.Service_Image_Small, s.Service_Image_large, s.Service_Min_Cost ,s.Service_time_required, strans.Service_Name from BPMS_SERVICE s INNER JOIN BPMS_SERVICE_TRANSLATIONS strans on s.Service_Id = strans.Service_Id INNER JOIN BPMS_SERVICE_APARTMENT_MAPPING ba on s.Service_Id = ba.Service_Id where ba.Apartment_Id = ? AND strans.Language_Code = ?", apartmentid, languagecode)
	log.Println(languagecode)
	if err != nil {
		return nil, err
	} else {
		return services, nil
	}
}

func (serviceRepo *ServiceRepository) FetchAllServices(input entity.FetchServicesInput) (services []entity.Service, err error) {
	if input.Apartment_Id != 0 {
		err = serviceRepo.db.Select(&services, "select s.Service_Id, s.Service_Description, s.Service_Image_Small, s.Service_Image_large, s.Service_Min_Cost ,s.Service_time_required, strans.Service_Name from BPMS_SERVICE s INNER JOIN BPMS_SERVICE_TRANSLATIONS strans on s.Service_Id = strans.Service_Id INNER JOIN BPMS_SERVICE_APARTMENT_MAPPING bsam ON s.Service_Id = bsam.Service_Id where strans.Language_Code = ? AND bsam.Apartment_Id =?", input.Language_Code, input.Apartment_Id)
	} else {
		err = serviceRepo.db.Select(&services, "select s.Service_Id, s.Service_Description, s.Service_Image_Small, s.Service_Image_large, s.Service_Min_Cost ,s.Service_time_required, strans.Service_Name from BPMS_SERVICE s INNER JOIN BPMS_SERVICE_TRANSLATIONS strans on s.Service_Id = strans.Service_Id where strans.Language_Code = ?", input.Language_Code)
	}
	if err != nil {
		log.Println("ServiceRepository: FetchAllServices: Error ", err.Error())
		return nil, err
	} else {
		return services, nil
	}
}

func (serviceRepo *ServiceRepository) AddService(tx *sqlx.Tx, input entity.AddServiceInput, img_path1 string, img_path2 string) (serviceList []entity.Service, errr error) {

	SrvQuery := "INSERT INTO `BPMS_SERVICE`( `Service_Description`, `Service_Image_Small`, `Service_Image_large`) VALUES (?,?,?)"

	insert, err1 := tx.Exec(SrvQuery, input.Service_Description, img_path1, img_path2)
	if err1 != nil {
		tx.Rollback()
		log.Println("ServiceRepository: AddService: Input: ", input.Service_Description, "Error1 ", err1.Error())
		return nil, err1
	}

	last_srvid, inserr := insert.LastInsertId()
	if inserr != nil {
		log.Println("ServiceRepository: AddService: Input: ", input, "Error2 ", inserr.Error())
		return nil, inserr
	}
	//fmt.Println("sow",last_stateid)

	SrvNameQuery := "INSERT INTO `BPMS_SERVICE_TRANSLATIONS`(`Service_Id`, `Language_Code`, `Service_Name`) VALUES (?,?,?)"

	_, err2 := tx.Exec(SrvNameQuery, last_srvid, input.Language_Code, input.Service_Name)
	if err2 != nil {
		tx.Rollback()
		log.Println("ServiceRepository: AddService: Input: ", input, "Error3 ", err2.Error())
		return nil, err2
	}

	errs := tx.Select(&serviceList, "SELECT st.Service_Id, st.Service_Name,s.Service_Description, s.Service_Image_Small, s.Service_Image_large, st.Language_Code FROM `BPMS_SERVICE_TRANSLATIONS` st inner join `BPMS_SERVICE` s where (st.Service_Id=s.Service_Id and st.Language_Code=1)")
	if errs != nil {
		log.Println("ServiceRepository: AddService: Error: ", errs.Error())
		return nil, errs
	} else {
		return serviceList, nil
	}
}

func (serviceRepo *ServiceRepository) ProblemCategoryUpdate(tx *sqlx.Tx, input entity.UpdateProblemCategoryInput) (problemInfo []entity.UpdateProblemCategory, err error) {

	if strings.ToLower(input.Action) == "i" {
		query := "INSERT INTO `BPMS_PROBLEM_CATEGORIES` values()"
		insert, err := serviceRepo.db.Exec(query)

		if err != nil {
			tx.Rollback()
			log.Println("ServiceRepository: ProblemCategoryUpdate: insertingproblemid: Error: ", err.Error())
			return nil, err
		}

		last_problemid, inserr := insert.LastInsertId()
		if inserr != nil {
			tx.Rollback()
			log.Println("ServiceRepository: ProblemCategoryUpdate: gettingLastInsertId: Error: ", inserr.Error())
			return nil, inserr
		}

		insQuery := "UPDATE `BPMS_PROBLEM_CATEGORIES` SET Service_Id = ? WHERE Problem_Id = ?"
		res, err1 := serviceRepo.db.Exec(insQuery, input.Service_Id, last_problemid)
		if err1 != nil {
			tx.Rollback()
			log.Println("ServiceRepository: ProblemCategoryUpdate: updateServiceid: Input: ProblemId:", last_problemid, " Error: ", err1.Error())
			return nil, err1
		}

		rowsAffected, _ := res.RowsAffected()
		if rowsAffected == 0 {
			tx.Rollback()
			log.Println("ServiceRepository: ProblemCategoryUpdate : rowsaffected")
			return nil, errors.New(dto.ErrorrowsAffectedUpdatePrblmCategory)
		}
		transQuery := "INSERT INTO `BPMS_PROBLEM_CATEGORIES_TRANSLATIONS` (`Problem_Id`, `Language_Code`, `Problem_Name`) VALUES (?,?,?)"
		_, err2 := serviceRepo.db.Exec(transQuery, last_problemid, input.Language_Code, input.Problem_Name)
		if err2 != nil {
			tx.Rollback()
			log.Println("ServiceRepository: ProblemCategoryUpdate: AddingProblemCategory: Input: prblm", input.Problem_Name, "Error: ", err2.Error())
			return nil, err2
		}

	}
	if strings.ToLower(input.Action) == "d" {

		delPrblmName := "DELETE FROM `BPMS_PROBLEM_CATEGORIES_TRANSLATIONS` WHERE Problem_Id =?"
		rows, err1 := serviceRepo.db.Exec(delPrblmName, input.Problem_Id)

		if err1 != nil {
			tx.Rollback()
			log.Print("ServiceRepository: ProblemCategoryUpdate: deletingproblemname: input : Problem_Id:", input.Problem_Id, "Error:", err1.Error())
			return nil, err1

		}
		rowsAffectedPrblmName, _ := rows.RowsAffected()
		if rowsAffectedPrblmName == 0 {
			tx.Rollback()
			log.Print("ServiceRepository: ProblemCategoryUpdate: deletingproblemname: rowsaffected")
			return nil, errors.New(dto.ErrorrowsAffectedUpdatePrblmCategory)
		}

		delPrblmId := "DELETE FROM `BPMS_PROBLEM_CATEGORIES` WHERE Problem_Id =?"
		rowIn, err2 := serviceRepo.db.Exec(delPrblmId, input.Problem_Id)

		if err2 != nil {
			tx.Rollback()
			log.Print("ServiceRepository: ProblemCategoryUpdate: deletingproblemId: input : Problem_Id:", input.Problem_Id, "Error:", err2.Error())
			return nil, err2

		}
		rowsAffectedPrblm, _ := rowIn.RowsAffected()
		if rowsAffectedPrblm == 0 {
			tx.Rollback()
			log.Print("ServiceRepository: ProblemCategoryUpdate: deletingproblemId: rowsaffected")
			return nil, errors.New(dto.ErrorrowsAffectedUpdatePrblmCategory)
		}

	}

	err = serviceRepo.db.Select(&problemInfo, "SELECT bpc.Problem_Id, bpct.Problem_Name FROM BPMS_PROBLEM_CATEGORIES bpc INNER JOIN BPMS_PROBLEM_CATEGORIES_TRANSLATIONS bpct ON bpc.Problem_Id =bpct.Problem_Id AND bpct.Language_Code=? WHERE bpc.Service_Id= ?", input.Language_Code, input.Service_Id)
	if err != nil {
		log.Print("ServiceRepository: ProblemCategoryUpdate: gettingproblemCategory: input: ", input.Service_Id, " Error: ", err.Error())
		return nil, err
	} else {
		return problemInfo, nil
	}
}
