package repository

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

	"github.com/jmoiron/sqlx"
)

type QuotationActions interface {
	FetchOrderSummary(input entity.UpdateQuotationDetailsInput) (*entity.ServiceRequest, error)
}

type QuotationRepository struct {
	db *sqlx.DB
}

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

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

func (quotationRepo *QuotationRepository) UpdateQuotation(tx *sqlx.Tx, input entity.UpdateQuotationDetailsInput) (*entity.ServiceRequest, error) {
	var lastInsertId int64
	var err, inserr error
	if input.Quote_Status == 2 {
		//reject
		query := "UPDATE BPMS_SERVICE_REQUEST SET Srq_Quote_Status = 2 WHERE Srq_Id = ?"
		_, err = tx.Exec(query, input.Parent_Srq)
		if err != nil {
			tx.Rollback()
			log.Println("QuotationRepository: UpdateQuotation: quotestatusupdate : srq_Id :", input.Parent_Srq, " : error: ", err.Error())
			return nil, err
		} else {
			log.Println("QuotationRepository: UpdateQuotation: quotestatusupdate : reject : srq_Id :", input.Parent_Srq)
			return nil, nil
		}
	} else if input.Quote_Status == 0 {
		//accept
		query := "UPDATE BPMS_SERVICE_REQUEST SET Srq_Quote_Status = 0 WHERE Srq_Id = ?"
		_, err = tx.Exec(query, input.Parent_Srq)
		if err != nil {
			tx.Rollback()
			log.Println("QuotationRepository: UpdateQuotation: quotestatusupdate : srq_Id :", input.Parent_Srq, " : error: ", err.Error())
			return nil, err
		} else {
			parentSrqInfo := entity.ServiceRequest{}
			getQuery := "SELECT bsr.Srq_Service, bsr.Request_Type, bsr.Srq_Apartment_Id, bsr.User_Id,  bsr.Srq_Tax_Percentage,  bsr.Quote_Labour_Cost, bsr.Quote_Service_Cost, bsr.Quote_Material_Cost, bsr.Quote_Tax, bsr.Quote_Other_Cost, bsr.Srq_Quote_Cost, bsr.Srq_Problem_Desc, bsr.Srq_Problem_Category, bsr.Srq_Category_others, bsr.Srq_Instructions, GROUP_CONCAT(bsi.Image_Path) as SRQ_Image FROM BPMS_SERVICE_REQUEST bsr LEFT JOIN BPMS_SRQ_IMAGE bsi ON bsr.Srq_Id = bsi.Srq_Id WHERE bsr.Srq_Id =?"
			err = tx.Get(&parentSrqInfo, getQuery, input.Parent_Srq)
			if err != nil {
				tx.Rollback()
				log.Println("QuotationRepository: UpdateQuotation: gettingparentsrqdetails : srq_Id :", input.Parent_Srq, " : error: ", err.Error())
				return nil, err
			} else {

				query := "INSERT INTO `BPMS_SERVICE_REQUEST` ( `Srq_Service`, `Parent_Request`, `Request_Type`, `Srq_Apartment_Id`, `User_Id`, `Srq_Service_Cost`, `Srq_Material_Cost`, `Srq_Labour_Cost`, `Srq_Tax_Percentage`, `Srq_Tax`, `Srq_Final_Cost`, `Srq_Other_Cost`,  `Srq_Stage_1`, `Srq_Stage_1_ts`, `Srq_Problem_Desc`, `Srq_Problem_Category`, `Srq_Category_others`, `Srq_Visit_Timeslot`,  `Srq_Instructions`, `Created_Date`) VALUES (?,?,?,?,?,? ,?,?,?,?,?,?,1,CURRENT_TIMESTAMP(), ?, ?, ?, ?,?, CURRENT_TIMESTAMP())"
				insert, err := tx.Exec(query, parentSrqInfo.Srq_Service, input.Parent_Srq, parentSrqInfo.Request_Type, parentSrqInfo.Srq_Apartment_Id, parentSrqInfo.User_Id, parentSrqInfo.Quote_Service_Cost, parentSrqInfo.Quote_Material_Cost, parentSrqInfo.Quote_Labour_Cost, parentSrqInfo.Srq_Tax_Percentage, parentSrqInfo.Quote_Tax, parentSrqInfo.Srq_Quote_Cost, parentSrqInfo.Quote_Other_Cost, parentSrqInfo.Srq_Problem_Desc, parentSrqInfo.Srq_Problem_Category, parentSrqInfo.Srq_Category_Others, input.Srq_Visit_Timeslot, parentSrqInfo.Srq_Instructions)
				if err != nil {
					tx.Rollback()
					log.Println("QuotationRepository: UpdateQuotation: creatingnewsrq : srq_Id :", input.Parent_Srq, " : error: ", err.Error())
					return nil, err
				}

				lastInsertId, inserr = insert.LastInsertId()
				if inserr != nil {
					tx.Rollback()
					log.Println("QuotationRepository: UpdateQuotation: gettingsrqid : Error: ", inserr.Error())
					return nil, err
				}

				newkey := fmt.Sprintf("%d", lastInsertId)
				newKeyId := "SRQ-" + newkey

				keyQuery := "UPDATE BPMS_SERVICE_REQUEST SET Srq_Key=? WHERE Srq_Id = ?"
				_, errIn := tx.Exec(keyQuery, newKeyId, lastInsertId)
				if errIn != nil {
					tx.Rollback()
					log.Println("QuotationRepository: UpdateQuotation : updatingSrqKey: input: srq_id:", lastInsertId, " Error: ", errIn.Error())
					return nil, errIn
				}

				childQuery := "update `BPMS_SERVICE_REQUEST` set Child_Request =? Where Srq_Id = ?"
				_, errC := tx.Exec(childQuery, lastInsertId, input.Parent_Srq)
				if errC != nil {
					tx.Rollback()
					log.Println("QuotationRepository: UpdateQuotation : updatingthechildsrq:  input: srq_Id:", input.Parent_Srq, " : error : ", errC.Error())
					return nil, errC
				}
				if parentSrqInfo.Srq_Img != nil {
					images := strings.Split(*parentSrqInfo.Srq_Img, ",")
					for _, image := range images {
						imgQuery := "Insert INTO `BPMS_SRQ_IMAGE` (`Image_Path`,`Srq_Id`) values (?,?)"
						_, errImg := tx.Exec(imgQuery, image, lastInsertId)
						if errImg != nil {
							tx.Rollback()
							log.Println("QuotationRepository: UpdateQuotation : insertingimage: input: ", lastInsertId, " Error: ", errImg.Error())
							return nil, errImg
						}
					}

				}
				srqDetails := entity.ServiceRequest{}
				getQuery := "SELECT bsr.Srq_Id, bsr.Srq_Key, bsr.Srq_Service, bst.Service_Name, bs.Service_Description, bs.Service_Image_Large, bs.Service_Image_Small, bsr.Request_Type, bsr.Parent_Request, bsr.Child_Request, bsr.Srq_Apartment_Id, bat.Apartment_Name,ba.Apartment_Image, bsat.State_Name, bct.City_Name, bsr.User_Id, bu.User_Name, bu.User_Mobno, bu.User_Image, buam.Block, buam.Door_No, bsr.Adm_Id, be.Emp_Name AS Admin_Name, be.Emp_Mobno AS Admin_Mobno, bsr.Admin_Comments, bsr.Technician_Id, bet.Emp_Name As Technician_Name, bet.Emp_Mobno AS Technician_Mobno, bet.Emp_Image AS Tech_Image, bsr.Technician_Comments, bpm.Promocode_Id, bp.Name, bp.Discount, bp.Max_Discount, bsr.Srq_Service_Cost,bsr.Srq_Material_Cost, bsr.Srq_Labour_Cost, bsr.Srq_Tax_Percentage, bsr.Srq_Tax, bsr.Srq_Discount_Amount, bsr.Srq_Other_Cost, bsr.Srq_Special_Discount, bsr.Srq_Final_Cost, bsr.Quote_Service_Cost,bsr.Quote_Labour_Cost, bsr.Quote_Material_Cost, bsr.Quote_Tax, bsr.Quote_Other_Cost, bsr.Srq_Quote_Cost, bsr.Srq_Stage_1, bsr.Srq_Stage_1_ts, bsr.Srq_Stage_2, bsr.Srq_Stage_2_ts, bsr.Srq_Stage_3, bsr.Srq_Stage_3_ts, bsr.Srq_Stage_4, bsr.Srq_Stage_4_ts, bsr.Srq_Stage_5, bsr.Srq_Stage_5_ts, bsr.Srq_Stage_6, bsr.Srq_Stage_6_ts, bsr.Srq_Stage_7, bsr.Srq_Stage_7_ts, bsr.Srq_Stage_8, bsr.Srq_Stage_8_ts, bsr.Srq_Stage_9, bsr.Srq_Stage_9_ts, bsr.Is_Happycode_Validated, bsr.Srq_Payment_Mode, bsr.Srq_Payment_Status, bsr.Srq_Quote_Status, bsr.Srq_Problem_Desc, bsr.Srq_Problem_Category,bpct.Problem_Name, bsr.Srq_Category_others,GROUP_CONCAT(bsi.Image_Path) As SRQ_Image, bsr.Srq_Visit_Timeslot, bsr.Srq_Instructions, bsr.Created_Date, bf.Feedback, bf.Rating FROM BPMS_SERVICE_REQUEST bsr INNER JOIN BPMS_SERVICE_TRANSLATIONS bst ON bsr.Srq_Service = bst.Service_Id And bst.Language_Code =? INNER JOIN BPMS_SERVICE bs ON bsr.Srq_Service = bs.Service_Id LEFT JOIN BPMS_APARTMENT ba ON bsr.Srq_Apartment_Id = ba.Apartment_Id INNER JOIN BPMS_APARTMENT_TRANSLATIONS bat ON bsr.Srq_Apartment_Id = bat.Apartment_Id AND bat.Language_Code =? INNER JOIN BPMS_STATE_TRANSLATIONS bsat ON ba.State = bsat.State_Id And bsat.Language_Code =? INNER JOIN BPMS_CITY bc ON ba.State = bc.State_Id INNER JOIN BPMS_CITY_TRANSLATIONS bct ON bc.City_Id = bct.City_Id AND bct.Language_Code =? INNER JOIN BPMS_USER bu ON bsr.User_Id = bu.User_Id LEFT JOIN BPMS_PROMO_MAPPING bpm ON bsr.Srq_Id = bpm.Srq_Id LEFT JOIN BPMS_PROMOCODE bp ON bpm.Promocode_Id = bp.Promocode_Id LEFT JOIN BPMS_PROBLEM_CATEGORIES_TRANSLATIONS bpct ON bsr.Srq_Problem_Category = bpct.Problem_Id AND bpct.Language_Code =? LEFT JOIN BPMS_FEEDBACK bf ON bsr.Srq_Id = bf.Service_Id LEFT JOIN BPMS_EMPLOYEE be ON bsr.Adm_Id = be.Emp_Id LEFT JOIN BPMS_EMPLOYEE bet ON bsr.Technician_Id = bet.Emp_Id LEFT JOIN BPMS_SRQ_IMAGE bsi ON bsr.Srq_Id = bsi.Srq_Id INNER JOIN BPMS_USER_APARTMENT_MAPPING buam ON bsr.Srq_Apartment_Id = buam.Apartment_Id AND bsr.User_Id = buam.User_Id WHERE bsr.Srq_Id=?"
				errQuery := tx.Get(&srqDetails, getQuery, input.Language_Code, input.Language_Code, input.Language_Code, input.Language_Code, input.Language_Code, lastInsertId)
				if errQuery != nil {
					log.Println("QuotationRepository: UpdateQuotation: fetchingsrq : Srq_Id:", lastInsertId, " Error: ", errQuery.Error())
					return nil, errQuery
				} else {
					return &srqDetails, nil
				}
			}

		}

	} else {
		log.Println("QuotationRepository: UpdateQuotation: invalidstatus : parent_srqId : ", input.Parent_Srq)
		return nil, errors.New(dto.ErrorMessageInvalidQuoteStatus)
	}
}
