package controllers

import (
	"math/rand"
	"nearle/db"
	"nearle/domain"
	"nearle/models"
	"nearle/utils"
	"net/http"
	"strconv"
	"strings"

	"github.com/gofiber/fiber/v2"
)

func Login(c *fiber.Ctx) error {

	var user models.User
	var info models.UserInfo
	var uid int
	var q1 string

	if err := c.BodyParser(&user); err != nil {
		return err
	}

	if user.Authname != "" {

		q1 = `SELECT a.userid from app_users a WHERE  a.authname= '` + user.Authname + `' and a.configid=` + strconv.Itoa(user.Configid)

	} else {

		q1 = `SELECT a.userid from app_users a WHERE  a.contactno= '` + user.Contactno + `' and a.configid=` + strconv.Itoa(user.Configid)

	}

	db.DB.Raw(q1).Find(&uid)

	if uid != 0 {

		user.Userid = uid
		// cno := domain.GetTenantId(uid, "")
		// domain.UpdatUser(user)
		info = domain.Getuserbyid(uid)

	} else {

		return c.JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusConflict,
			"message": "User not found",
		})

	}

	return c.JSON(fiber.Map{
		"code":    http.StatusOK,
		"message": "Success",
		"status":  true,
		"details": info,
	})
}

func TenantLogin(c *fiber.Ctx) error {

	var user models.User
	var info models.TenantUserInfo
	var uid int
	var q1 string

	if err := c.BodyParser(&user); err != nil {
		return err
	}

	if user.Authname != "" {

		q1 = `SELECT a.userid from app_users a WHERE  a.authname= '` + user.Authname + `' and a.configid=` + strconv.Itoa(user.Configid)

	} else {

		q1 = `SELECT a.userid from app_users a WHERE  a.contactno= '` + user.Contactno + `' and a.configid=` + strconv.Itoa(user.Configid)

	}

	db.DB.Raw(q1).Find(&uid)

	if uid != 0 {

		user.Userid = uid
		// user.Tenantid = domain.GetTenantId(user.Contactno)
		// domain.UpdatUser(user)
		info = domain.GetTenantUserbyId(uid)

	} else {

		return c.JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusConflict,
			"message": "User not found",
		})

	}

	return c.JSON(fiber.Map{
		"code":    http.StatusOK,
		"message": "Success",
		"status":  true,
		"details": info,
	})
}

// func Partnerlogin(c *fiber.Ctx) error {
// 	var user models.User
// 	var info models.UserInfo
// 	var uid int
// 	var q1 string

// 	if err := c.BodyParser(&user); err != nil {
// 		return err
// 	}

// 	if user.Authname != "" {
// 		q1 = `SELECT a.userid FROM app_users a
// 			  WHERE a.authname = '` + user.Authname + `'
// 			  AND a.configid = ` + strconv.Itoa(user.Configid)
// 	} else {
// 		q1 = `SELECT a.userid FROM app_users a
// 			  WHERE a.contactno = '` + user.Contactno + `'
// 			  AND a.configid = ` + strconv.Itoa(user.Configid)
// 	}

// 	db.DB.Raw(q1).Scan(&uid)

// 	if uid != 0 {
// 		user.Userid = uid
// 		user.Pin = rand.Intn(6000) + 1000

// 		if user.Userfcmtoken != "" {
// 			log.Println("Updating FCM Token for UID:", uid, "Token:", user.Userfcmtoken)
// 			result := db.DB.Exec(`UPDATE app_users SET userfcmtoken = ? WHERE userid = ?`, user.Userfcmtoken, uid)
// 			if result.Error != nil {
// 				log.Println("Error updating FCM token:", result.Error)
// 			} else {
// 				log.Println("FCM token updated successfully")
// 			}
// 		}

// 		domain.UpdatUser(user)

// 		info = domain.GetPartnerUserbyid(uid)

// 		if user.Configid == 5 && user.Authname != "" {
// 			config := domain.GetAppconfig(user.Configid)

// 			err := domain.SendLoginNotification(info.Userfcmtoken, config.Fcmkey, info.Pin)
// 			if err != nil {
// 				log.Println("FCM send error:", err)

// 			}
// 		}
// 	} else {
// 		return c.JSON(fiber.Map{
// 			"status":  false,
// 			"code":    http.StatusConflict,
// 			"message": "User not found",
// 		})
// 	}

// 	return c.JSON(fiber.Map{
// 		"code":    http.StatusOK,
// 		"message": "Success",
// 		"status":  true,
// 		"details": info,
// 	})
// }

func Partnerlogin(c *fiber.Ctx) error {
	var user models.User
	var info models.UserInfo
	var uid int
	var q1 string

	if err := c.BodyParser(&user); err != nil {
		return err
	}

	if user.Authname != "" {
		q1 = `SELECT a.userid FROM app_users a 
			  WHERE a.authname = '` + user.Authname + `' 
			  AND a.configid = ` + strconv.Itoa(user.Configid)
	} else {
		q1 = `SELECT a.userid FROM app_users a 
			  WHERE a.contactno = '` + user.Contactno + `' 
			  AND a.configid = ` + strconv.Itoa(user.Configid)
	}

	db.DB.Raw(q1).Scan(&uid)

	if uid != 0 {
		user.Userid = uid
		user.Pin = rand.Intn(6000) + 1000

		if user.Userfcmtoken != "" {
			utils.Logger.Infow("Updating FCM Token", "uid", uid, "token", user.Userfcmtoken)
			result := db.DB.Exec(`UPDATE app_users SET userfcmtoken = ? WHERE userid = ?`, user.Userfcmtoken, uid)
			if result.Error != nil {
				utils.Logger.Errorw("Error updating FCM token", "error", result.Error)
			} else {
				utils.Logger.Infow("FCM token updated successfully")
			}
		}

		domain.UpdatUser(user)

		info = domain.GetPartnerUserbyid(uid)

		if user.Configid == 5 && user.Authname != "" {
			config := domain.GetAppconfig(user.Configid)

			err := domain.SendLoginNotification(info.Userfcmtoken, config.Fcmkey, info.Pin)
			if err != nil {
				utils.Logger.Errorw("FCM send error", "error", err)

			}
		}
	} else {
		return c.JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusConflict,
			"message": "User not found",
		})
	}

	return c.JSON(fiber.Map{
		"code":    http.StatusOK,
		"message": "Success",
		"status":  true,
		"details": info,
	})
}

func Riderlogin(c *fiber.Ctx) error {

	var user models.User
	var info models.RiderInfo
	var uid int
	var q1 string

	if err := c.BodyParser(&user); err != nil {
		return err
	}

	if user.Authname != "" {

		q1 = `SELECT a.userid from app_users a WHERE  a.authname= '` + user.Authname + `' and a.configid=` + strconv.Itoa(user.Configid)

	} else {

		q1 = `SELECT a.userid from app_users a WHERE  a.contactno= '` + user.Contactno + `' and a.configid=` + strconv.Itoa(user.Configid)

	}

	db.DB.Raw(q1).Find(&uid)

	if uid != 0 {

		user.Userid = uid
		user.Pin = rand.Intn(6000) + 1000
		domain.UpdatUser(user)
		info = domain.GetRiderUserbyid(uid)

		if user.Configid == 5 && user.Authname != "" {

			config := domain.GetAppconfig(user.Configid)
			domain.SendLoginNotification(info.Userfcmtoken, config.Fcmkey, info.Pin)

		}

	} else {

		return c.JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusConflict,
			"message": "User not found",
		})

	}

	utils.Logger.Debugw("Rider Login Query", "query", q1)

	return c.JSON(fiber.Map{
		"code":    http.StatusOK,
		"message": "Success",
		"status":  true,
		"details": info,
	})

}

func Riderloginv2(c *fiber.Ctx) error {
	var user models.User

	if err := c.BodyParser(&user); err != nil {
		return c.JSON(fiber.Map{
			"status":  false,
			"code":    400,
			"message": "Invalid request body",
		})
	}

	var uid int

	if user.Contactno != "" {
		uid = domain.GetUserIDByContact(user.Contactno, user.Configid)
	}

	if uid == 0 && user.Authname != "" {
		uid = domain.GetUserIDByAuth(user.Authname, user.Configid)
	}

	if uid == 0 {
		return c.JSON(fiber.Map{
			"status":  false,
			"code":    404,
			"message": "User not found",
		})
	}

	status := domain.GetUserStatus(uid)
	if strings.ToLower(status) != "active" {
		return c.JSON(fiber.Map{
			"status":  false,
			"code":    403,
			"message": "User is inactive. Contact administrator.",
		})
	}

	storedPin := domain.GetStoredPin(uid)
	authmode := domain.GetAuthMode(uid)

	if authmode == 1 {
		// Update FCM Token
		if user.Userfcmtoken != "" {
			_ = domain.UpdateUserFcmToken(uid, user.Userfcmtoken)
		}

		info := domain.GetRiderUserbyid(uid)

		return c.JSON(fiber.Map{
			"status":  true,
			"code":    200,
			"message": "Login successful",
			"details": info,
		})
	}

	if storedPin == 0 {
		return c.JSON(fiber.Map{
			"status":   false,
			"code":     400,
			"message":  "PIN not set for this user. Please set a PIN before logging in.",
			"userid":   uid,
			"authmode": authmode,
		})
	}

	if user.Pin == 0 {
		return c.JSON(fiber.Map{
			"status":   true,
			"code":     200,
			"message":  "User verified. Please enter your PIN.",
			"userid":   uid,
			"authmode": authmode,
		})
	}

	if storedPin != user.Pin {
		return c.JSON(fiber.Map{
			"status":   false,
			"code":     401,
			"message":  "Invalid PIN",
			"authmode": authmode,
		})
	}

	if user.Userfcmtoken != "" {
		if err := domain.UpdateUserFcmToken(uid, user.Userfcmtoken); err != nil {
			return c.JSON(fiber.Map{
				"status":  false,
				"code":    500,
				"message": "Failed to update FCM token",
			})
		}
	}

	info := domain.GetRiderUserbyid(uid)

	return c.JSON(fiber.Map{
		"status":  true,
		"code":    200,
		"message": "Login successful",
		"details": info,
	})
}

func AdminLogin(c *fiber.Ctx) error {
	var user models.User
	var uid int
	var q1 string

	if err := c.BodyParser(&user); err != nil {
		return err
	}

	if user.Authname != "" {
		q1 = `SELECT a.userid FROM app_users a WHERE a.authname = '` + user.Authname + `' AND a.password = '` + user.Password + `' AND a.configid = ` + strconv.Itoa(user.Configid)
	}

	db.DB.Raw(q1).Scan(&uid)

	if uid == 0 {
		return c.JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusConflict,
			"message": "User not found",
		})
	}

	if user.Userfcmtoken != "" {
		updateQuery := `UPDATE app_users SET userfcmtoken = ? WHERE userid = ?`
		if err := db.DB.Exec(updateQuery, user.Userfcmtoken, uid).Error; err != nil {
			utils.Logger.Errorw("Failed to update FCM token", "error", err)
		}
	}

	user = domain.GetAdminUserbyid(uid)

	return c.JSON(fiber.Map{
		"code":    http.StatusOK,
		"message": "Success",
		"status":  true,
		"details": user,
	})
}

func AdminConsoleLogin(c *fiber.Ctx) error {

	var user models.User
	var uid int
	var status, dbPassword string
	var query string

	if err := c.BodyParser(&user); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"code":    400,
			"status":  false,
			"message": "Invalid request body",
		})
	}

	if strings.TrimSpace(user.Authname) == "" {
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"code":    400,
			"status":  false,
			"message": "authname is required",
		})
	}

	query = `
		SELECT userid, password, status
		FROM app_users
		WHERE authname = ? AND configid = ?
	`
	db.DB.Raw(query, user.Authname, 9).Row().Scan(&uid, &dbPassword, &status)

	if uid == 0 {
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":  false,
			"code":    409,
			"message": "Invalid Email",
		})
	}

	if strings.EqualFold(status, "InActive") {
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":  false,
			"code":    403,
			"message": "Inactive Account. Contact admin.",
		})
	}

	if strings.TrimSpace(dbPassword) == "" {
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":  true,
			"code":    409,
			"message": "Please setup a password.",
			"details": fiber.Map{
				"userid": uid,
				"setup":  true,
			},
		})
	}

	if strings.TrimSpace(user.Password) == "" {
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":  true,
			"code":    401,
			"message": "Password is required",
			"userid":  uid,
		})
	}

	if user.Password != dbPassword {
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":  false,
			"code":    401,
			"message": "Incorrect password",
		})
	}

	if user.Userfcmtoken != "" {
		_ = db.DB.Exec(
			`UPDATE app_users SET userfcmtoken = ? WHERE userid = ?`,
			user.Userfcmtoken, uid,
		)
	}

	user = domain.GetAdminUserbyid(uid)

	return c.Status(fiber.StatusOK).JSON(fiber.Map{
		"status":  true,
		"code":    200,
		"message": "Login successful",
		"details": user,
	})
}

func CustomerLogin(c *fiber.Ctx) error {

	var data models.Customer

	if err := c.BodyParser(&data); err != nil {
		return err
	}

	q1 := `select a.customerid,a.authmode,a.configid,a.deviceid,a.devicetype,a.customertoken,a.firstname,a.lastname,
		a.contactno,a.profileimage,a.address,a.suburb,a.city,a.state,a.landmark,a.doorno,a.postcode,
		a.latitude,a.longitude,a.applocationid,a.status,a.profileimage, a.dialcode, a.deviceid, a.devicetype, a.authmode, 
		a.configid, a.customertoken, a.intro, b.tenantid , c.qrmode, b.locationid
		from customers a 
		INNER JOIN tenantcustomers b ON a.customerid=b.customerid 
		LEFT JOIN app_location c ON a.applocationid=c.applocationid
		where a.configid=2 and a.contactno= '` + data.Contactno + `' `

	utils.Logger.Debugw("Customer Login Query", "query", q1)

	db.DB.Raw(q1).Find(&data)

	if data.Customerid == 0 {

		return c.JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusConflict,
			"message": "Account not found",
		})

	}

	return c.JSON(fiber.Map{
		"code":    http.StatusOK,
		"message": "Success",
		"status":  true,
		"details": data,
	})
}

func BasicRoute(c *fiber.Ctx) error {

	return c.JSON(fiber.Map{
		"code":    http.StatusOK,
		"message": "Success",
		"status":  true,
		"details": "Hello Customer Route",
	})
}

func CreateUser(c *fiber.Ctx) error {

	var user models.User
	var info models.UserInfo

	// 🔹 Parse request body
	if err := c.BodyParser(&user); err != nil {
		return c.Status(http.StatusBadRequest).JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusBadRequest,
			"message": "Invalid request body",
		})
	}

	// 🔹 Validate mandatory fields
	if user.Configid == 0 {
		return c.Status(http.StatusBadRequest).JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusBadRequest,
			"message": "configid is required",
		})
	}

	// 🔹 Check duplicate user (contactno / emailid + configid)
	exists, err := domain.CheckUserExists(user.Contactno, user.Email, user.Configid)
	if err != nil {
		return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusInternalServerError,
			"message": "Database error",
		})
	}

	if exists {
		return c.Status(http.StatusOK).JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusConflict,
			"message": "User already exists with this contact number or email",
		})
	}

	// 🔹 Start transaction
	tx := db.DB.Begin()

	if err := tx.Table("app_users").Create(&user).Error; err != nil {
		tx.Rollback()
		return c.Status(http.StatusConflict).JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusConflict,
			"message": "Failed to create user",
		})
	}

	if err := tx.Commit().Error; err != nil {
		return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusInternalServerError,
			"message": "Transaction failed",
		})
	}

	// 🔹 Fetch created user info
	info = domain.Getuserbyid(user.Userid)

	return c.Status(http.StatusCreated).JSON(fiber.Map{
		"status":  true,
		"code":    http.StatusCreated,
		"message": "Success",
		"details": info,
	})
}

func GetUserInfo(c *fiber.Ctx) error {
	uid, _ := strconv.Atoi(c.Query("userid"))

	user := domain.Getuserbyid(uid)

	return c.JSON(fiber.Map{
		"code":    http.StatusCreated,
		"message": "Success",
		"status":  true,
		"details": user,
	})
}
func GetAllUsers(c *fiber.Ctx) error {
	roleID, _ := strconv.Atoi(c.Query("roleid", "0"))
	configID, _ := strconv.Atoi(c.Query("configid", "0"))
	tenantID, _ := strconv.Atoi(c.Query("tenantid", "0"))
	pageno, _ := strconv.Atoi(c.Query("pageno", "1"))
	pagesize, _ := strconv.Atoi(c.Query("pagesize", "10"))
	status := c.Query("status", "") // 👈 added
	keyword := c.Query("keyword", "")

	users := domain.GetAllUsers(roleID, configID, tenantID, pageno, pagesize, status, keyword)

	return c.JSON(fiber.Map{
		"code":    http.StatusOK,
		"message": "Success",
		"status":  true,
		"details": users,
	})
}

func DeleteUser(c *fiber.Ctx) error {
	type Request struct {
		Userid int `json:"userid"`
	}

	var req Request

	if err := c.BodyParser(&req); err != nil {
		return c.JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusBadRequest,
			"message": "Invalid request body",
		})
	}

	if req.Userid == 0 {
		return c.JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusBadRequest,
			"message": "Missing userid",
		})
	}

	err := db.DB.Table("app_users").Where("userid = ?", req.Userid).Delete(nil).Error
	if err != nil {
		return c.JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusInternalServerError,
			"message": err.Error(),
		})
	}

	return c.JSON(fiber.Map{
		"status":  true,
		"code":    http.StatusOK,
		"message": "User deleted successfully",
	})
}

func TenantWebLogin(c *fiber.Ctx) error {
	utils.Logger.Infow("Starting TenantWebLogin")

	var user models.User
	var info models.TenantUserInfo
	var uid, roleid int
	var status, dbPassword string
	var query string

	// Parse request body
	if err := c.BodyParser(&user); err != nil {
		utils.Logger.Errorw("Error parsing body", "error", err)
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"code":    400,
			"status":  false,
			"message": "Invalid request body",
		})
	}

	// Check login method: authname or contactno
	if user.Authname != "" {
		query = `
			SELECT userid, password, status, roleid
			FROM app_users
			WHERE authname = ? AND configid = ?
		`
		db.DB.Raw(query, user.Authname, user.Configid).Row().Scan(&uid, &dbPassword, &status, &roleid)
	} else if user.Contactno != "" {
		query = `
			SELECT userid, password, status, roleid
			FROM app_users
			WHERE contactno = ? AND configid = ?
		`
		db.DB.Raw(query, user.Contactno, user.Configid).Row().Scan(&uid, &dbPassword, &status, &roleid)
	} else {
		utils.Logger.Errorw("Missing authname or contactno")
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"code":    400,
			"status":  false,
			"message": "authname or contactno required",
		})
	}

	tenantFormExists := true

	if uid == 0 {
		utils.Logger.Infow("Invalid Email at TenantWebLogin", "email", user.Authname)
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":     false,
			"code":       409,
			"message":    "Invalid Email",
			"tenantform": tenantFormExists,
		})
	}

	// Check if user is inactive
	if status == "InActive" {
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":  false,
			"code":    403,
			"message": "Inactive Account. Contact admin.",
		})
	}

	// Compare roleid in request vs DB
	if user.Roleid != roleid {
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":  false,
			"code":    403,
			"message": "Unauthorized email.",
		})
	}

	// Check if password is not set
	if strings.TrimSpace(dbPassword) == "" {
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":     true,
			"code":       409,
			"message":    "Please setup a password.",
			"tenantform": tenantFormExists,
			"details": fiber.Map{
				"userid": uid,
				"setup":  true,
			},
		})
	}

	// Check if password is provided in request
	if strings.TrimSpace(user.Password) == "" {
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":     true,
			"code":       401,
			"message":    "Password is required",
			"tenantform": tenantFormExists,
		})
	}

	// Validate password
	if user.Password != dbPassword {
		utils.Logger.Infow("Incorrect password attempt", "uid", uid)
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":     false,
			"code":       401,
			"message":    "Incorrect password",
			"tenantform": tenantFormExists,
		})
	}

	user.Userid = uid

	// Update FCM token if provided
	if user.Userfcmtoken != "" {
		updateQuery := `
			UPDATE app_users
			SET userfcmtoken = ?
			WHERE userid = ?
		`
		if err := db.DB.Exec(updateQuery, user.Userfcmtoken, uid).Error; err != nil {
			utils.Logger.Errorw("Error updating userfcmtoken", "error", err)
		} else {
			utils.Logger.Infow("Updated userfcmtoken", "userid", uid)
		}
	}

	info = domain.GetTenantUserbyId(uid)

	utils.Logger.Infow("Tenant found", "tenant", info.Tenantname)

	return c.Status(fiber.StatusOK).JSON(fiber.Map{
		"status":  true,
		"code":    200,
		"message": "Login successful",
		"details": info,
	})
}

func AppLogin(c *fiber.Ctx) error {
	utils.Logger.Infow("Starting TenantWebLogin")

	var user models.User
	var info models.TenantUserInfo
	var uid int
	var status, dbPassword string
	var query string

	// Parse request body
	if err := c.BodyParser(&user); err != nil {
		utils.Logger.Errorw("Error parsing body", "error", err)
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"code":    400,
			"status":  false,
			"message": "Invalid request body",
		})
	}

	// Check login method: authname or contactno
	if user.Authname != "" {
		query = `
			SELECT userid, password, status
			FROM app_users
			WHERE authname = ? AND configid = ?
		`
		db.DB.Raw(query, user.Authname, user.Configid).Row().Scan(&uid, &dbPassword, &status)
	} else if user.Contactno != "" {
		query = `
			SELECT userid, password, status
			FROM app_users
			WHERE contactno = ? AND configid = ?
		`
		db.DB.Raw(query, user.Contactno, user.Configid).Row().Scan(&uid, &dbPassword, &status)
	} else {
		utils.Logger.Errorw("Missing authname or contactno")
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"code":    400,
			"status":  false,
			"message": "authname or contactno required",
		})
	}

	tenantFormExists := true

	if uid == 0 {
		utils.Logger.Infow("Invalid Email at TenantWebLogin", "email", user.Authname)
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":     false,
			"code":       409,
			"message":    "Invalid Email",
			"tenantform": tenantFormExists,
		})
	}

	// Check if user is inactive
	if status == "InActive" {
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":  false,
			"code":    403,
			"message": "Inactive Account. Contact admin.",
		})
	}

	// Check if password is not set
	if strings.TrimSpace(dbPassword) == "" {
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":     true,
			"code":       409,
			"message":    "Please setup a password.",
			"tenantform": tenantFormExists,
			"details": fiber.Map{
				"userid": uid,
				"setup":  true,
			},
		})
	}

	// Check if password is provided in request
	if strings.TrimSpace(user.Password) == "" {
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":     true,
			"code":       401,
			"message":    "Password is required",
			"tenantform": tenantFormExists,
		})
	}

	// Validate password
	if user.Password != dbPassword {
		utils.Logger.Infow("Incorrect password attempt", "uid", uid)
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":     false,
			"code":       401,
			"message":    "Incorrect password",
			"tenantform": tenantFormExists,
		})
	}

	user.Userid = uid

	// Update FCM token if provided
	if user.Userfcmtoken != "" {
		updateQuery := `
			UPDATE app_users
			SET userfcmtoken = ?
			WHERE userid = ?
		`
		if err := db.DB.Exec(updateQuery, user.Userfcmtoken, uid).Error; err != nil {
			utils.Logger.Errorw("Error updating userfcmtoken", "error", err)
		} else {
			utils.Logger.Infow("Updated userfcmtoken", "userid", uid)
		}
	}

	info = domain.GetTenantUserbyId(uid)

	utils.Logger.Infow("Tenant found", "tenant", info.Tenantname)

	return c.Status(fiber.StatusOK).JSON(fiber.Map{
		"status":  true,
		"code":    200,
		"message": "Login successful",
		"details": info,
	})
}

func CreateUserV2(c *fiber.Ctx) error {
	var user models.User
	var info models.UserInfo

	if err := c.BodyParser(&user); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"code":    400,
			"message": "Invalid request body",
			"status":  false,
		})
	}

	tx := db.DB.Begin()

	user.Status = "InActive"

	// Insert into app_users
	if err := tx.Table("app_users").Create(&user).Error; err != nil {
		tx.Rollback()
		return c.Status(fiber.StatusConflict).JSON(fiber.Map{
			"code":    409,
			"message": "Failed to create user",
			"status":  false,
		})
	}

	// Insert into tenantstaffs
	staff := models.Tenantstaffs{
		Tenantid:   user.Tenantid,
		Moduleid:   2,
		Locationid: user.Locationid,
		Userid:     user.Userid,
		Status:     "InActive",
	}

	if err := tx.Table("tenantstaffs").Create(&staff).Error; err != nil {
		tx.Rollback()
		return c.Status(fiber.StatusConflict).JSON(fiber.Map{
			"code":    409,
			"message": "Failed to create tenant staff",
			"status":  false,
		})
	}

	// Insert into app_userpools
	pool := models.AppUserpools{
		Userid:    user.Userid,
		Partnerid: user.Partnerid,
		Onduty:    1,
		Latitude:  "",
		Longitude: "",
		Status:    "idle",
	}

	if err := tx.Table("app_userpools").Create(&pool).Error; err != nil {
		tx.Rollback()
		return c.Status(fiber.StatusConflict).JSON(fiber.Map{
			"code":    409,
			"message": "Failed to create user pool",
			"status":  false,
		})
	}

	// Commit transaction
	if err := tx.Commit().Error; err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
			"code":    500,
			"message": "Transaction commit failed",
			"status":  false,
		})
	}

	// Fetch user info
	info = domain.Getuserbyid(user.Userid)

	return c.Status(fiber.StatusCreated).JSON(fiber.Map{
		"code":    201,
		"message": "User created successfully",
		"status":  true,
		"details": info,
	})
}

func UpdateUserV2(c *fiber.Ctx) error {
	var userInput map[string]interface{}

	if err := c.BodyParser(&userInput); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"code":    400,
			"message": "Invalid request body",
			"status":  false,
		})
	}

	userID, ok := userInput["userid"]
	if !ok || userID == nil {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"code":    400,
			"message": "Missing userid",
			"status":  false,
		})
	}

	tx := db.DB.Begin()

	// Update only fields provided for app_users
	if err := tx.Table("app_users").Where("userid = ?", userID).Updates(userInput).Error; err != nil {
		tx.Rollback()
		return c.Status(fiber.StatusConflict).JSON(fiber.Map{
			"code":    409,
			"message": "Failed to update user",
			"status":  false,
		})
	}

	// Filter relevant fields for tenantstaffs update
	staffFields := map[string]interface{}{}
	if tenantid, ok := userInput["tenantid"]; ok {
		staffFields["tenantid"] = tenantid
	}
	if locationid, ok := userInput["locationid"]; ok {
		staffFields["locationid"] = locationid
	}
	if status, ok := userInput["status"]; ok {
		staffFields["status"] = status
	}

	if len(staffFields) > 0 {
		if err := tx.Table("tenantstaffs").Where("userid = ?", userID).Updates(staffFields).Error; err != nil {
			tx.Rollback()
			return c.Status(fiber.StatusConflict).JSON(fiber.Map{
				"code":    409,
				"message": "Failed to update tenant staff",
				"status":  false,
			})
		}
	}

	if err := tx.Commit().Error; err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
			"code":    500,
			"message": "Transaction commit failed",
			"status":  false,
		})
	}

	info := domain.Getuserbyid(int(userID.(float64))) // type assert if coming from JSON

	return c.Status(fiber.StatusOK).JSON(fiber.Map{
		"code":    200,
		"message": "User updated successfully",
		"status":  true,
		"details": info,
	})
}

func TenantWebLoginv2(c *fiber.Ctx) error {
	utils.Logger.Infow("Unified login started")

	var user models.User
	var info models.TenantUserInfo
	var uid = c.Locals("uid").(int)
	var dbPassword = c.Locals("password").(string)

	if err := c.BodyParser(&user); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
			"code":    400,
			"status":  false,
			"message": "Invalid request body",
		})
	}

	tenantFormExists := true

	// Check if password is not set
	if strings.TrimSpace(dbPassword) == "" {
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":     true,
			"code":       409,
			"message":    "Please setup a password.",
			"tenantform": tenantFormExists,
			"details": fiber.Map{
				"userid": uid,
				"setup":  true,
			},
		})
	}

	if strings.TrimSpace(user.Password) == "" {
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":     false,
			"code":       401,
			"message":    "Password is required",
			"tenantform": tenantFormExists,
		})
	}

	if user.Password != dbPassword {
		return c.Status(fiber.StatusOK).JSON(fiber.Map{
			"status":     false,
			"code":       401,
			"message":    "Incorrect password",
			"tenantform": tenantFormExists,
		})
	}

	user.Userid = uid

	if user.Userfcmtoken != "" {
		updateQuery := `UPDATE app_users SET userfcmtoken = ? WHERE userid = ?`
		if err := db.DB.Exec(updateQuery, user.Userfcmtoken, uid).Error; err != nil {
			utils.Logger.Errorw("Error updating userfcmtoken", "error", err)
		}
	}

	info = domain.GetTenantUserbyId(uid)

	return c.Status(fiber.StatusOK).JSON(fiber.Map{
		"status":  true,
		"code":    200,
		"message": "Login successful",
		"details": info,
	})
}

func CreateConsoleUser(c *fiber.Ctx) error {

	var user models.ConsoleUser
	var info models.UserInfo

	// 🔹 Parse request body
	if err := c.BodyParser(&user); err != nil {
		return c.Status(http.StatusBadRequest).JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusBadRequest,
			"message": "Invalid request body",
		})
	}

	// 🔹 Validation
	if user.Configid == 0 {
		return c.Status(http.StatusBadRequest).JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusBadRequest,
			"message": "configid is required",
		})
	}

	// if len(user.Applocationids) == 0 {
	// 	return c.Status(http.StatusBadRequest).JSON(fiber.Map{
	// 		"status":  false,
	// 		"code":    http.StatusBadRequest,
	// 		"message": "at least one applocationid is required",
	// 	})
	// }

	// 🔹 Duplicate user check
	exists, err := domain.CheckUserExists(user.Contactno, user.Email, user.Configid)
	if err != nil {
		return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusInternalServerError,
			"message": "Database error",
		})
	}

	if exists {
		return c.Status(http.StatusConflict).JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusConflict,
			"message": "User already exists",
		})
	}

	// 🔹 Start transaction
	tx := db.DB.Begin()

	// 🔹 Create user
	if err := tx.Table("app_users").Create(&user).Error; err != nil {
		tx.Rollback()
		return c.Status(http.StatusConflict).JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusConflict,
			"message": "Failed to create user",
		})
	}

	// 🔹 Assign MULTIPLE location access
	// for _, locID := range user.Applocationids {
	// 	locationConfig := models.AppLocationConfig{
	// 		Applocationid: locID,
	// 		Configid:      user.Configid,
	// 		Userid:        user.Userid,
	// 		Partnerid:     0,
	// 		Notify:        "true",
	// 		Status:        "Active",
	// 	}

	// 	if err := tx.Table("app_locationconfig").Create(&locationConfig).Error; err != nil {
	// 		tx.Rollback()
	// 		return c.Status(http.StatusConflict).JSON(fiber.Map{
	// 			"status":  false,
	// 			"code":    http.StatusConflict,
	// 			"message": "Failed to assign location access",
	// 		})
	// 	}
	// }

	// 🔹 Commit transaction
	if err := tx.Commit().Error; err != nil {
		return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusInternalServerError,
			"message": "Transaction failed",
		})
	}

	// 🔹 Fetch created user info
	info = domain.Getuserbyid(user.Userid)

	return c.Status(http.StatusCreated).JSON(fiber.Map{
		"status":  true,
		"code":    http.StatusCreated,
		"message": "User created with multiple location access",
		"details": info,
	})
}

func GetAllUsersv2(c *fiber.Ctx) error {
	roleID, _ := strconv.Atoi(c.Query("roleid", "0"))
	configID, _ := strconv.Atoi(c.Query("configid", "0"))
	tenantID, _ := strconv.Atoi(c.Query("tenantid", "0"))
	pageno, _ := strconv.Atoi(c.Query("pageno", "1"))
	pagesize, _ := strconv.Atoi(c.Query("pagesize", "10"))
	keyword := c.Query("keyword", "")

	users := domain.GetAllUsersv2(roleID, configID, tenantID, pageno, pagesize, keyword)

	return c.JSON(fiber.Map{
		"code":    http.StatusOK,
		"message": "Success",
		"status":  true,
		"details": users,
	})
}
