package controllers

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

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

const (
	core = `SELECT COUNT(DISTINCT a.deliveryid) AS total,

    COUNT(DISTINCT CASE WHEN a.orderstatus = 'pending'   THEN a.deliveryid END) AS pending,
    COUNT(DISTINCT CASE WHEN a.orderstatus = 'accepted'  THEN a.deliveryid END) AS accepted,
    COUNT(DISTINCT CASE WHEN a.orderstatus = 'arrived'   THEN a.deliveryid END) AS arrived,
    COUNT(DISTINCT CASE WHEN a.orderstatus = 'picked'    THEN a.deliveryid END) AS picked,
    COUNT(DISTINCT CASE WHEN a.orderstatus = 'active'    THEN a.deliveryid END) AS active,
    COUNT(DISTINCT CASE WHEN a.orderstatus = 'delivered' THEN a.deliveryid END) AS delivered,
    COUNT(DISTINCT CASE WHEN a.orderstatus = 'cancelled' THEN a.deliveryid END) AS cancelled,
    COUNT(DISTINCT CASE WHEN a.orderstatus = 'skipped'   THEN a.deliveryid END) AS skipped`

	reports = `SELECT 
	c.userid,e.firstname,e.lastname,e.contactno AS ridercontact,b.tenantid,b.tenantname,a.locationid, d.locationname, 
	COUNT(*) AS totalorders,
	SUM(CASE WHEN a.orderstatus = 'created' THEN 1 ELSE 0 END) AS orderscreated,
	SUM(CASE WHEN a.orderstatus = 'pending' THEN 1 ELSE 0 END) AS orderspending,
	SUM(CASE WHEN a.orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS orderscancelled,
	SUM(CASE WHEN a.orderstatus = 'delivered' THEN 1 ELSE 0 END) AS orderscompleted,
	SUM(CASE WHEN c.orderstatus = 'pending' THEN 1 ELSE 0 END) AS deliveriespending,
	SUM(CASE WHEN c.orderstatus = 'delivered' THEN 1 ELSE 0 END) AS deliveriescompleted,
	SUM(CASE WHEN c.orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS deliveriescancelled,
	SUM(CASE WHEN c.paymenttype = 64 THEN c.deliveryamt ELSE 0 END) AS paylater, 
	SUM(CASE WHEN c.paymenttype = 43 THEN c.deliveryamt ELSE 0 END) AS payondelivery, 
	ROUND(SUM(CAST(COALESCE(NULLIF(c.kms, ''), '0') AS NUMERIC)), 2) AS kms,
	ROUND(SUM(CAST(COALESCE(NULLIF(c.actualkms, ''), '0') AS NUMERIC)), 2) AS actualkms,
	SUM(c.deliveryamt) AS charges,
	SUM(CASE WHEN c.orderstatus = 'delivered' THEN c.cumulativekms ELSE 0 END) AS cumulativekms,
	SUM(CASE WHEN c.orderstatus = 'delivered' THEN c.deliveryamt ELSE 0 END) AS deliveryamt,
	SUM(c.previouskms) AS previouskms,
	SUM(c.previouskms) AS previouskms,
	SUM(CAST(COALESCE(NULLIF(c.riderkms, ''), '0') AS NUMERIC)) AS riderkms,
	SUM(c.quantity) AS quantity, SUM(c.collectionamt) AS collectionamt, SUM(c.collectedamt) AS collectedamt, c.collectionstatus
	FROM
	tenants b
	right JOIN orders a ON b.tenantid = a.tenantid
	right JOIN deliveries c ON a.orderheaderid = c.orderheaderid 
	LEFT JOIN tenantlocations d ON a.locationid = d.locationid
	LEFT JOIN app_users e ON e.userid = c.userid`

	Ridersummary = `SELECT a.userid, a.firstname, a.lastname, a.contactno AS ridercontact, MAX(b.tenantid) AS tenantid, MAX(c.tenantname) AS tenantname, MAX(b.locationid) AS locationid, MAX(d.locationname) AS locationname,
    CONCAT(a.firstname, ' ', a.lastname) AS fullname, a.status, SUM(COALESCE(b.quantity,0)) AS quantity, SUM(COALESCE(b.collectionamt,0)) AS collectionamt, SUM(COALESCE(b.collectedamt,0)) AS collectedamt, COALESCE(MAX(b.collectionstatus),0) AS collectionstatus,
	COUNT(b.orderid) AS totalorders,
    SUM(CASE WHEN b.orderstatus = 'pending' THEN 1 ELSE 0 END) AS pending,
    SUM(CASE WHEN b.orderstatus = 'assigned' THEN 1 ELSE 0 END) AS assigned,
	SUM(CASE WHEN b.orderstatus = 'accepted' THEN 1 ELSE 0 END) AS accepted,
    SUM(CASE WHEN b.orderstatus = 'arrived' THEN 1 ELSE 0 END) AS arrived,
    SUM(CASE WHEN b.orderstatus = 'picked' THEN 1 ELSE 0 END) AS picked,
	SUM(CASE WHEN b.orderstatus = 'active' THEN 1 ELSE 0 END) AS active,
	SUM(CASE WHEN b.orderstatus = 'skipped' THEN 1 ELSE 0 END) AS skipped,
    SUM(CASE WHEN b.orderstatus = 'delivered' THEN 1 ELSE 0 END) AS delivered,
	SUM(CASE WHEN b.orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS cancelled,
    SUM(CASE WHEN b.orderstatus = 'delivered' THEN CAST(COALESCE(NULLIF(b.actualkms, ''), '0') AS NUMERIC) ELSE 0 END) AS actualkms,
    SUM(CASE WHEN b.orderstatus = 'delivered' THEN CAST(COALESCE(NULLIF(b.kms, ''), '0') AS NUMERIC) ELSE 0 END) AS kms,   
	SUM(CASE WHEN b.paymenttype = 64 THEN b.deliveryamt ELSE 0 END) AS paylater, 
	SUM(CASE WHEN b.paymenttype = 43 THEN b.deliveryamt ELSE 0 END) AS payondelivery, 
    SUM(CASE WHEN b.orderstatus = 'delivered' THEN b.cumulativekms ELSE 0 END) AS cumulativekms,
	SUM(CASE WHEN b.orderstatus = 'delivered' THEN b.deliveryamt ELSE 0 END) AS deliveryamt,
	SUM(b.previouskms) AS previouskms
	FROM app_users a
	LEFT JOIN deliveries b ON a.userid = b.userid
	LEFT JOIN tenants c ON b.tenantid = c.tenantid
    LEFT JOIN tenantlocations d ON b.locationid = d.locationid`
)

func PublishLog(c *fiber.Ctx) error {

	var data []models.Deliverylogs

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

	err := domain.PublishLog(data)

	if err != nil {

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

	}

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

}

func GetDeliverylogs(c *fiber.Ctx) error {

	did, _ := strconv.Atoi(c.Query("deliveryid"))

	result := domain.GetDeliverylogs(did)

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

}

func GetDeliveriesV1(c *fiber.Ctx) error {

	var result []models.Deliveryinfo

	pid, _ := strconv.Atoi(c.Query("partnerid"))
	tid, _ := strconv.Atoi(c.Query("tenantid"))
	uid, _ := strconv.Atoi(c.Query("userid"))
	cid, _ := strconv.Atoi(c.Query("customerid"))
	aid, _ := strconv.Atoi(c.Query("applocationid"))
	aud, _ := strconv.Atoi(c.Query("appuserid"))
	fdate := c.Query("fromdate")
	tdate := c.Query("todate")
	stat := c.Query("status")

	var info models.DeliveryQuery

	info.Partnerid = pid
	info.Tenantid = tid
	info.UserID = uid
	info.Appuserid = aud
	info.Applocationid = aid
	info.Fromdate = fdate
	info.ToDate = tdate
	info.Status = stat

	if tid != 0 {

		result = domain.GetTenantDeliveries(info)

	} else if pid != 0 {

		result = domain.GetPartnerDeliveries(info)

	} else if cid != 0 {

		result = domain.GetCustomerDeliveries(info)

	} else if aid != 0 {

		result = domain.GetAdminDeliveries(info)

	} else if uid != 0 {

		result = domain.GetUserDeliveries(info)

	} else if aud != 0 {

		result = domain.GetAppUserDeliveries(info)

	}

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

}

func GetDeliveriesV2(c *fiber.Ctx) error {
	var result []models.Deliveryinfo

	pid, _ := strconv.Atoi(c.Query("partnerid"))
	tid, _ := strconv.Atoi(c.Query("tenantid"))
	lid, _ := strconv.Atoi(c.Query("locationid"))
	uid, _ := strconv.Atoi(c.Query("userid"))
	cid, _ := strconv.Atoi(c.Query("customerid"))
	aid, _ := strconv.Atoi(c.Query("applocationid"))
	aud, _ := strconv.Atoi(c.Query("appuserid"))
	fdate := c.Query("fromdate")
	tdate := c.Query("todate")
	stat := c.Query("status")
	keyword := c.Query("keyword")

	pagenoStr := c.Query("pageno")
	pagesizeStr := c.Query("pagesize")

	var pageno, pagesize int
	var err error

	if pagenoStr != "" {
		pageno, err = strconv.Atoi(pagenoStr)
		if err != nil || pageno <= 0 {
			pageno = 1
		}
	}

	if pagesizeStr != "" {
		pagesize, err = strconv.Atoi(pagesizeStr)
		if err != nil || pagesize <= 0 {
			pagesize = 10
		}
	}

	info := models.DeliveryQuery{
		Partnerid:     pid,
		Tenantid:      tid,
		Locationid:    lid,
		UserID:        uid,
		Appuserid:     aud,
		Applocationid: aid,
		Fromdate:      fdate,
		ToDate:        tdate,
		Status:        stat,
		Pageno:        pageno,
		Pagesize:      pagesize,
		Keyword:       keyword,
	}

	utils.Logger.Infow("Searching Delivery", "keyword", keyword)

	switch {
	case tid != 0 && lid != 0:
		result = domain.GetTenantLocationDeliveries(info)
	case tid != 0:
		result = domain.GetTenantDeliveries(info)
	case lid != 0:
		result = domain.GetLocationDeliveries(info)
	case pid != 0:
		result = domain.GetPartnerDeliveries(info)
	case cid != 0:
		result = domain.GetCustomerDeliveries(info)
	case aid != 0:
		result = domain.GetAdminDeliveries(info)
	case uid != 0:
		result = domain.GetUserDeliveries(info)
	case aud != 0:
		result = domain.GetAppUserDeliveries(info)
	default:
		result = domain.GetDeliveries(info)
	}

	if result == nil {
		result = []models.Deliveryinfo{}
	}

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

func GetDeliveriesV3(c *fiber.Ctx) error {
	var result []models.Deliveryinfo

	pid, _ := strconv.Atoi(c.Query("partnerid"))
	tid, _ := strconv.Atoi(c.Query("tenantid"))
	uid, _ := strconv.Atoi(c.Query("userid"))
	cid, _ := strconv.Atoi(c.Query("customerid"))
	aid, _ := strconv.Atoi(c.Query("applocationid"))
	aud, _ := strconv.Atoi(c.Query("appuserid"))
	pageno, _ := strconv.Atoi(c.Query("pageno", "1"))
	pagesize, _ := strconv.Atoi(c.Query("pagesize", ""))
	fdate := c.Query("fromdate")
	tdate := c.Query("todate")
	stat := c.Query("status")
	keyword := c.Query("keyword")

	var info models.DeliveryQuery

	info.Partnerid = pid
	info.Tenantid = tid
	info.UserID = uid
	info.Appuserid = aud
	info.Applocationid = aid
	info.Fromdate = fdate
	info.ToDate = tdate
	info.Status = stat
	info.Pageno = pageno
	info.Pagesize = pagesize
	info.Keyword = keyword

	utils.Logger.Infow("Searching Delivery", "keyword", keyword)

	// Choose which delivery function to call
	switch {
	case tid != 0:
		result = domain.GetTenantDeliveries(info)
	case pid != 0:
		result = domain.GetPartnerDeliveries(info)
	case cid != 0:
		result = domain.GetCustomerDeliveries(info)
	case aid != 0:
		result = domain.GetAdminDeliveries(info)
	case uid != 0:
		result = domain.GetUserDeliveriesv1(info)
	case aud != 0:
		result = domain.GetAppUserDeliveries(info)
	default:
		result = domain.GetDeliveries(info)
	}

	// Ensure result is not nil (avoid "null" in JSON)
	if result == nil {
		result = []models.Deliveryinfo{}
	}

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

func GetDeliveries(c *fiber.Ctx) error {

	pid, _ := strconv.Atoi(c.Query("partnerid"))
	tid, _ := strconv.Atoi(c.Query("tenantid"))
	uid, _ := strconv.Atoi(c.Query("userid"))
	aid, _ := strconv.Atoi(c.Query("applocationid"))
	aud, _ := strconv.Atoi(c.Query("appuserid"))
	fdate := c.Query("fromdate")
	tdate := c.Query("todate")
	stat := c.Query("status")

	var info models.DeliveryQuery

	info.Partnerid = pid
	info.Tenantid = tid
	info.UserID = uid
	info.Appuserid = aud
	info.Applocationid = aid
	info.Fromdate = fdate
	info.ToDate = tdate
	info.Status = stat

	data := domain.GetDeliveries(info)

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

}

func GetReportSummary(c *fiber.Ctx) error {

	tid, _ := strconv.Atoi(c.Query("tenantid"))
	pid, _ := strconv.Atoi(c.Query("partnerid"))
	uid, _ := strconv.Atoi(c.Query("userid"))
	aid, _ := strconv.Atoi(c.Query("applocationid"))
	fdate := c.Query("fromdate")
	tdate := c.Query("todate")

	var data []models.ReportSummary
	var q1 string

	var params []interface{}
	q1 = reports

	if tid != 0 {
		q1 += " WHERE a.tenantid=? "
		params = append(params, tid)
	} else if pid != 0 {
		q1 += " WHERE a.partnerid=? "
		params = append(params, pid)
	} else if uid != 0 {
		q1 += " WHERE c.userid=? "
		params = append(params, uid)
	} else if aid != 0 {
		q1 += " WHERE c.applocationid=? "
		params = append(params, aid)
	} else {
		q1 += " WHERE 1=1 "
	}

	if fdate != "" && tdate != "" {
		q1 += " AND a.orderdate::date between ?::date and ?::date "
		params = append(params, fdate, tdate)
	}

	q1 += " GROUP BY a.tenantid, b.tenantname, c.userid, e.firstname, e.lastname, e.contactno, a.locationid, d.locationname, c.collectionstatus"

	utils.Logger.Debugw("ReportSummary SQL generated", "query", q1)

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

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

}

func GetReportLocationSummary(c *fiber.Ctx) error {

	tid, _ := strconv.Atoi(c.Query("tenantid"))
	lid, _ := strconv.Atoi(c.Query("locationid"))
	pid, _ := strconv.Atoi(c.Query("partnerid"))
	uid, _ := strconv.Atoi(c.Query("userid"))
	aid, _ := strconv.Atoi(c.Query("applocationid"))
	fdate := c.Query("fromdate")
	tdate := c.Query("todate")
	keyword := c.Query("keyword")

	var data []models.ReportSummary
	var q1 string

	var params []interface{}
	q1 = reports + " WHERE 1=1 "

	if tid != 0 {
		q1 += " AND a.tenantid=? "
		params = append(params, tid)
	}
	if lid != 0 {
		q1 += " AND a.locationid=? "
		params = append(params, lid)
	}
	if pid != 0 {
		q1 += " AND a.partnerid=? "
		params = append(params, pid)
	}
	if uid != 0 {
		q1 += " AND c.userid=? "
		params = append(params, uid)
	}
	if aid != 0 {
		q1 += " AND c.applocationid=? "
		params = append(params, aid)
	}
	if keyword != "" {
		q1 += " AND LOWER(d.locationname) LIKE LOWER(?) "
		params = append(params, "%"+keyword+"%")
	}
	if fdate != "" && tdate != "" {
		q1 += " AND a.orderdate::date BETWEEN ?::date AND ?::date "
		params = append(params, fdate, tdate)
	}

	q1 += " GROUP BY a.locationid, b.tenantid, b.tenantname, c.userid, e.firstname, e.lastname, e.contactno, d.locationname, c.collectionstatus"

	utils.Logger.Debugw("ReportLocationSummary SQL generated", "query", q1)

	db.DB.Raw(q1, params...).Scan(&data)

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

func GetRiderLocationReportSummary(c *fiber.Ctx) error {

	tid, _ := strconv.Atoi(c.Query("tenantid"))
	pid, _ := strconv.Atoi(c.Query("partnerid"))
	uid, _ := strconv.Atoi(c.Query("userid"))
	aid, _ := strconv.Atoi(c.Query("applocationid"))
	fdate := c.Query("fromdate")
	tdate := c.Query("todate")

	var data []models.ReportSummary
	var q1 string

	base := `
		SELECT b.tenantid,b.tenantname,a.locationid,d.locationname,e.userid,e.firstname,e.lastname,
			COUNT(*) AS totalorders,
			SUM(CASE WHEN a.orderstatus = 'created' THEN 1 ELSE 0 END) AS orderscreated,
			SUM(CASE WHEN a.orderstatus = 'pending' THEN 1 ELSE 0 END) AS orderspending,
			SUM(CASE WHEN a.orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS orderscancelled,
			SUM(CASE WHEN a.orderstatus = 'delivered' THEN 1 ELSE 0 END) AS orderscompleted,
			SUM(CASE WHEN c.orderstatus = 'pending' THEN 1 ELSE 0 END) AS deliveriespending,
			SUM(CASE WHEN c.orderstatus = 'delivered' THEN 1 ELSE 0 END) AS deliveriescompleted,
			SUM(CASE WHEN c.orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS deliveriescancelled,
			SUM(CASE WHEN c.paymenttype = 64 THEN c.deliveryamt ELSE 0 END) AS paylater,
			SUM(CASE WHEN c.paymenttype = 43 THEN c.deliveryamt ELSE 0 END) AS payondelivery,
			ROUND(SUM(CAST(COALESCE(NULLIF(c.kms, ''), '0') AS NUMERIC)), 2) AS kms,
			ROUND(SUM(CAST(COALESCE(NULLIF(c.actualkms, ''), '0') AS NUMERIC)), 2) AS actualkms,
			SUM(c.deliveryamt) AS charges
		FROM tenants b
		RIGHT JOIN orders a ON b.tenantid = a.tenantid
		RIGHT JOIN deliveries c ON a.orderheaderid = c.orderheaderid
		LEFT JOIN tenantlocations d ON a.locationid = d.locationid
		LEFT JOIN app_users e ON e.userid = c.userid
	`

	// WHERE conditions
	var where []string
	var params []interface{}

	// Tenant filter
	if tid != 0 {
		where = append(where, "a.tenantid=?")
		params = append(params, tid)
	}

	// Partner filter
	if pid != 0 {
		where = append(where, "a.partnerid=?")
		params = append(params, pid)
	}

	// Rider (userid) filter
	if uid != 0 {
		where = append(where, "c.userid=?")
		params = append(params, uid)
	}

	// Location filter
	if aid != 0 {
		where = append(where, "a.locationid=?")
		params = append(params, aid)
	}

	// Date filter
	if fdate != "" && tdate != "" {
		where = append(where, "a.orderdate::date BETWEEN ?::date AND ?::date")
		where = append(where, "c.deliverydate::date BETWEEN ?::date AND ?::date")
		params = append(params, fdate, tdate, fdate, tdate)
	}

	// Build WHERE clause
	if len(where) > 0 {
		q1 = base + " WHERE " + strings.Join(where, " AND ")
	} else {
		q1 = base
	}

	// GROUP BY
	q1 += " GROUP BY a.locationid, b.tenantid, b.tenantname, d.locationname, e.userid, e.firstname, e.lastname"

	utils.Logger.Debugw("RiderLocationReportSummary SQL generated", "query", q1)

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

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

func GetRiderSummary(c *fiber.Ctx) error {

	aid, _ := strconv.Atoi(c.Query("applocationid"))
	pid, _ := strconv.Atoi(c.Query("partnerid"))
	tid, _ := strconv.Atoi(c.Query("tenantid"))
	lid, _ := strconv.Atoi(c.Query("locationid"))
	uid, _ := strconv.Atoi(c.Query("userid"))

	fdate := c.Query("fromdate")
	tdate := c.Query("todate")
	keyword := c.Query("keyword")

	var data []models.Ridersummary

	var params []interface{}
	q1 := Ridersummary + " WHERE a.configid = 6"

	if uid != 0 {
		q1 += " AND a.userid=?"
		params = append(params, uid)
	}

	if tid != 0 {
		q1 += " AND b.tenantid=?"
		params = append(params, tid)
	}

	if lid != 0 {
		q1 += " AND b.locationid=?"
		params = append(params, lid)
	}

	if aid != 0 {
		q1 += " AND a.applocationid=?"
		params = append(params, aid)
	}

	if pid != 0 {
		q1 += " AND a.partnerid=?"
		params = append(params, pid)
	}

	if fdate != "" && tdate != "" {
		q1 += " AND b.deliverydate::date BETWEEN ?::date AND ?::date"
		params = append(params, fdate, tdate)
	}

	if keyword != "" {
		k := "%" + strings.ToLower(keyword) + "%"
		q1 += " AND (LOWER(a.firstname) LIKE ? OR LOWER(a.lastname) LIKE ? OR LOWER(CONCAT(a.firstname, ' ', a.lastname)) LIKE ?)"
		params = append(params, k, k, k)
	}

	q1 += " GROUP BY a.userid, a.firstname, a.lastname, a.contactno, a.status"

	utils.Logger.Debugw("RiderSummary SQL generated", "query", q1)

	db.DB.Raw(q1, params...).Scan(&data)

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

func GetRiderLocationSummary(c *fiber.Ctx) error {

	aid, _ := strconv.Atoi(c.Query("applocationid"))
	pid, _ := strconv.Atoi(c.Query("partnerid"))
	tid, _ := strconv.Atoi(c.Query("tenantid"))
	lid, _ := strconv.Atoi(c.Query("locationid"))
	fdate := c.Query("fromdate")
	tdate := c.Query("todate")

	var data []models.Ridersummary
	var q1 string

	var params []interface{}
	q1 = Ridersummary + " WHERE a.configid=6 "

	if tid != 0 {
		q1 += " AND b.tenantid=? "
		params = append(params, tid)
	}
	if lid != 0 {
		q1 += " AND b.locationid=? "
		params = append(params, lid)
	}
	if aid != 0 {
		q1 += " AND a.applocationid=? "
		params = append(params, aid)
	}
	if pid != 0 {
		q1 += " AND a.partnerid=? "
		params = append(params, pid)
	}
	if fdate != "" && tdate != "" {
		q1 += " AND b.deliverydate::date BETWEEN ?::date AND ?::date "
		params = append(params, fdate, tdate)
	}

	q1 += " GROUP BY a.userid, b.locationid, a.firstname, a.lastname, a.contactno, b.tenantid, c.tenantname, d.locationname, a.status"

	db.DB.Raw(q1, params...).Scan(&data)

	utils.Logger.Debugw("RiderLocationSummary SQL generated", "query", q1)

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

func GetDeliverySummary(c *fiber.Ctx) error {

	// 🔹 Query params
	appuid, _ := strconv.Atoi(c.Query("appuserid"))
	tid, _ := strconv.Atoi(c.Query("tenantid"))
	lid, _ := strconv.Atoi(c.Query("locationid"))
	aid, _ := strconv.Atoi(c.Query("applocationid"))
	uid, _ := strconv.Atoi(c.Query("userid"))

	status := c.Query("status")
	fdate := c.Query("fromdate")
	tdate := c.Query("todate")

	var data models.DeliverySummary
	var qb strings.Builder
	var params []interface{}

	qb.WriteString(core + `
		FROM deliveries a
		INNER JOIN tenants b ON a.tenantid = b.tenantid
		INNER JOIN app_users c ON a.userid = c.userid
		INNER JOIN tenantlocations e ON a.locationid = e.locationid
		INNER JOIN app_location f ON a.applocationid = f.applocationid
		INNER JOIN app_locationconfig g ON f.applocationid = g.applocationid
		WHERE b.moduleid = 6
		  AND g.status = 'Active'
	`)

	if appuid != 0 {
		qb.WriteString(" AND g.userid = ?")
		params = append(params, appuid)
	}

	if tid != 0 {
		qb.WriteString(" AND a.tenantid = ?")
		params = append(params, tid)
	}

	if lid != 0 {
		qb.WriteString(" AND a.locationid = ?")
		params = append(params, lid)
	}

	if aid != 0 {
		qb.WriteString(" AND a.applocationid = ?")
		params = append(params, aid)
	}

	if uid != 0 {
		qb.WriteString(" AND a.userid = ?")
		params = append(params, uid)
	}

	if status != "" && strings.ToLower(status) != "all" {
		qb.WriteString(" AND a.orderstatus = ?")
		params = append(params, status)
	}

	// 🔹 DATE FILTER (INDEX-FRIENDLY)
	if fdate != "" && tdate != "" {
		qb.WriteString(`
			AND a.deliverydate >= (CONCAT(?::text, ' 00:00:00'))::timestamp
			AND a.deliverydate <= (CONCAT(?::text, ' 23:59:59'))::timestamp
		`)
		params = append(params, fdate, tdate)
	}

	finalQuery := qb.String()

	utils.Logger.Infow("DeliverySummary SQL generated", "query", finalQuery, "params", params)

	db.DB.Raw(finalQuery, params...).Scan(&data)

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

func GetlocationdeliverySummary(c *fiber.Ctx) error {
	tenantIDStr := c.Query("tenantid")
	tenantID, _ := strconv.Atoi(tenantIDStr)

	var data []models.Ordersummary
	var q1 string
	var params []interface{}

	q1 = `SELECT b.locationname, a.applocationid, COUNT(*) AS total,
			SUM(CASE WHEN orderstatus = 'created' THEN 1 ELSE 0 END) AS created,
			SUM(CASE WHEN orderstatus = 'pending' THEN 1 ELSE 0 END) AS pending,
			SUM(CASE WHEN orderstatus = 'processing' THEN 1 ELSE 0 END) AS processing,
			SUM(CASE WHEN orderstatus = 'delivered' THEN 1 ELSE 0 END) AS delivered,
			SUM(CASE WHEN orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS cancelled
		FROM orders a 
		INNER JOIN app_location b ON a.applocationid = b.applocationid`

	// Apply tenant filter only if tenantID != 0
	if tenantID != 0 {
		q1 += " WHERE a.tenantid = ?"
		params = append(params, tenantID)
	}

	q1 += " GROUP BY a.applocationid, b.locationname"

	if err := db.DB.Raw(q1, params...).Scan(&data).Error; err != nil {
		return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusInternalServerError,
			"message": err.Error(),
		})
	}

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

func GetDeliveryInsight(c *fiber.Ctx) error {
	tenantIDStr := c.Query("tenantid")
	tenantID, _ := strconv.Atoi(tenantIDStr)

	var locations []models.OrderInsight
	var params []interface{}

	// Query 1: Get distinct locations
	q1 := `SELECT DISTINCT a.applocationid, b.locationname 
		   FROM deliveries a 
		   INNER JOIN app_location b ON a.applocationid = b.applocationid
		   WHERE b.status = 'Active'`

	if tenantID != 0 {
		q1 += " AND a.tenantid = ?"
		params = append(params, tenantID)
	}

	if err := db.DB.Raw(q1, params...).Scan(&locations).Error; err != nil {
		return c.JSON(fiber.Map{
			"code":    http.StatusConflict,
			"message": err.Error(),
			"status":  false,
		})
	}

	// Query 2: Fetch delivery insights for each location
	q2 := `SELECT 
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 1 THEN 1 ELSE 0 END), 0) AS jan,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 2 THEN 1 ELSE 0 END), 0) AS feb,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 3 THEN 1 ELSE 0 END), 0) AS mar,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 4 THEN 1 ELSE 0 END), 0) AS apr,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 5 THEN 1 ELSE 0 END), 0) AS may,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 6 THEN 1 ELSE 0 END), 0) AS jun,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 7 THEN 1 ELSE 0 END), 0) AS jul,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 8 THEN 1 ELSE 0 END), 0) AS aug,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 9 THEN 1 ELSE 0 END), 0) AS sep,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 10 THEN 1 ELSE 0 END), 0) AS oct,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 11 THEN 1 ELSE 0 END), 0) AS nov,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM a.deliverydate) = 12 THEN 1 ELSE 0 END), 0) AS dece
		FROM deliveries a
		WHERE a.applocationid = ? AND EXTRACT(YEAR FROM a.deliverydate) = EXTRACT(YEAR FROM CURRENT_DATE)`

	if tenantID != 0 {
		q2 += " AND a.tenantid = ?"
	}

	// Fetch monthly delivery counts for each location
	for i := range locations {
		var orderMonths models.Ordermonths

		if tenantID != 0 {
			if err := db.DB.Raw(q2, locations[i].Applocationid, tenantID).Scan(&orderMonths).Error; err != nil {
				return c.JSON(fiber.Map{
					"code":    http.StatusConflict,
					"message": err.Error(),
					"status":  false,
				})
			}
		} else {
			if err := db.DB.Raw(q2, locations[i].Applocationid).Scan(&orderMonths).Error; err != nil {
				return c.JSON(fiber.Map{
					"code":    http.StatusConflict,
					"message": err.Error(),
					"status":  false,
				})
			}
		}

		locations[i].Ordermonths = &orderMonths
	}

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

func DeliverySummary(c *fiber.Ctx) error {

	pid, _ := strconv.Atoi(c.Query("partnerid"))

	var data models.DeliverySummary

	q1 := `SELECT
		COUNT(*) AS deliveries,
		SUM(CASE WHEN orderstatus = 'cancelled' THEN 1 ELSE 0 END) AS cancelled,
		SUM(round(kms, 2)) AS kms,
		SUM(deliveryamt) AS amount
		FROM
		deliveries
		WHERE
		partnerid =?`

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

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

}

func CreateDelivery(c *fiber.Ctx) error {

	var data models.Deliveries

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

	err := domain.CreateDelivery(data)
	if err != nil {

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

	} else {

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

	}

}

func CreateDeliveries(c *fiber.Ctx) error {

	var data []models.Deliveries

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

	err := domain.CreateDeliveries(data)

	if err != nil {
		return c.JSON(fiber.Map{
			"code":    http.StatusConflict,
			"message": err.Error(),
			"status":  false,
		})
	}

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

}

func CreateDeliveriesV2(c *fiber.Ctx) error {

	var data []models.Deliveries

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

	utils.Logger.Infow("CreateDeliveriesV2 Call", "records", len(data))

	ids, err := domain.CreateDeliveriesV2(data)
	if err != nil {
		return c.Status(409).JSON(fiber.Map{
			"status":  false,
			"code":    409,
			"message": err.Error(),
		})
	}

	return c.JSON(fiber.Map{
		"status":      true,
		"code":        201,
		"message":     "Deliveries created successfully",
		"deliveryids": ids,
	})
}

func UpdateDelivery(c *fiber.Ctx) error {

	var data models.UpdateDeliveryStatus

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

	err := domain.UpdateDelivery(data)

	if err != nil {
		return c.JSON(fiber.Map{
			"code":    http.StatusConflict,
			"message": err.Error(),
			"status":  false,
		})
	}

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

}

func GetDeliveryQueues(c *fiber.Ctx) error {

	fdate := c.Query("fromdate")
	tdate := c.Query("todate")
	uid, _ := strconv.Atoi(c.Query("userid"))

	result := domain.GetDeliveryQueues(uid, fdate, tdate)

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

func GetDeliveryQueuesV1(c *fiber.Ctx) error {

	fdate := c.Query("fromdate")
	tdate := c.Query("todate")
	uid, _ := strconv.Atoi(c.Query("userid"))

	result := domain.GetDeliveryQueuesV1(uid, fdate, tdate)

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

func GetDeliveryQueuesPicked(c *fiber.Ctx) error {

	fdate := c.Query("fromdate")
	tdate := c.Query("todate")
	uid, _ := strconv.Atoi(c.Query("userid"))

	result := domain.GetDeliveryQueuesPicked(uid, fdate, tdate)

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

}

func GetlocationdeliverySummaryDaily(c *fiber.Ctx) error {
	tenantIDStr := c.Query("tenantid")
	tenantID, _ := strconv.Atoi(tenantIDStr)

	var data []models.Ordersummarylocation
	var q1 string
	var params []interface{}

	q1 = `
		SELECT 
			b.locationid, 
			b.locationname, 
			COALESCE(COUNT(a.orderid), 0) AS total,
			COALESCE(SUM(CASE WHEN a.orderstatus = 'created' THEN 1 ELSE 0 END), 0) AS created,
			COALESCE(SUM(CASE WHEN a.orderstatus = 'pending' THEN 1 ELSE 0 END), 0) AS pending,
			COALESCE(SUM(CASE WHEN a.orderstatus = 'processing' THEN 1 ELSE 0 END), 0) AS processing,
			COALESCE(SUM(CASE WHEN a.orderstatus = 'delivered' THEN 1 ELSE 0 END), 0) AS delivered,
			COALESCE(SUM(CASE WHEN a.orderstatus = 'cancelled' THEN 1 ELSE 0 END), 0) AS cancelled
		FROM tenantlocations b
		LEFT JOIN orders a ON a.locationid = b.locationid
	`

	// ✅ Apply tenant filter on tenantlocations (not orders only)
	if tenantID != 0 {
		q1 += " WHERE b.tenantid = ?"
		params = append(params, tenantID)
	}

	q1 += " GROUP BY b.locationid, b.locationname"

	if err := db.DB.Raw(q1, params...).Scan(&data).Error; err != nil {
		return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusInternalServerError,
			"message": err.Error(),
		})
	}

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

func GetDeliveryInsightDaily(c *fiber.Ctx) error {
	tenantIDStr := c.Query("tenantid")
	tenantID, _ := strconv.Atoi(tenantIDStr)

	var locations []models.OrderInsightv1
	var params []interface{}

	q1 := `SELECT DISTINCT l.locationid, l.locationname 
		   FROM tenantlocations l 
		   LEFT JOIN deliveries d ON l.locationid = d.locationid
		   WHERE l.status = 'Active'`

	if tenantID != 0 {
		q1 += " AND l.tenantid = ?"
		params = append(params, tenantID)
	}

	if err := db.DB.Raw(q1, params...).Scan(&locations).Error; err != nil {
		return c.JSON(fiber.Map{
			"code":    http.StatusConflict,
			"message": err.Error(),
			"status":  false,
		})
	}

	q2 := `SELECT 
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 1 THEN 1 ELSE 0 END), 0) AS jan,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 2 THEN 1 ELSE 0 END), 0) AS feb,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 3 THEN 1 ELSE 0 END), 0) AS mar,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 4 THEN 1 ELSE 0 END), 0) AS apr,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 5 THEN 1 ELSE 0 END), 0) AS may,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 6 THEN 1 ELSE 0 END), 0) AS jun,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 7 THEN 1 ELSE 0 END), 0) AS jul,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 8 THEN 1 ELSE 0 END), 0) AS aug,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 9 THEN 1 ELSE 0 END), 0) AS sep,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 10 THEN 1 ELSE 0 END), 0) AS oct,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 11 THEN 1 ELSE 0 END), 0) AS nov,
		COALESCE(SUM(CASE WHEN EXTRACT(MONTH FROM d.deliverydate) = 12 THEN 1 ELSE 0 END), 0) AS dece
		FROM deliveries d
		WHERE d.locationid = ? AND EXTRACT(YEAR FROM d.deliverydate) = EXTRACT(YEAR FROM CURRENT_DATE)`

	if tenantID != 0 {
		q2 += " AND d.tenantid = ?"
	}

	for i := range locations {
		var orderMonths models.Ordermonths

		if tenantID != 0 {
			if err := db.DB.Raw(q2, locations[i].Locationid, tenantID).Scan(&orderMonths).Error; err != nil {
				return c.JSON(fiber.Map{
					"code":    http.StatusConflict,
					"message": err.Error(),
					"status":  false,
				})
			}
		} else {
			if err := db.DB.Raw(q2, locations[i].Locationid).Scan(&orderMonths).Error; err != nil {
				return c.JSON(fiber.Map{
					"code":    http.StatusConflict,
					"message": err.Error(),
					"status":  false,
				})
			}
		}

		locations[i].Ordermonths = &orderMonths
	}

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

func PublishLogv1(c *fiber.Ctx) error {
	var data []models.Deliverylogs

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

	err := domain.PublishLogv1(data)
	if err != nil {
		return c.Status(http.StatusConflict).JSON(fiber.Map{
			"status":  false,
			"code":    http.StatusConflict,
			"message": err.Error(),
		})
	}

	return c.JSON(fiber.Map{
		"status":  true,
		"code":    http.StatusOK,
		"message": "Successfully saved logs to Redis",
	})
}

func GetDeliverylogsv1(c *fiber.Ctx) error {
	did, _ := strconv.Atoi(c.Query("deliveryid"))

	result, err := domain.GetDeliverylogsv1(did)
	if err != nil {
		return c.JSON(fiber.Map{
			"code":    http.StatusConflict,
			"message": err.Error(),
			"status":  false,
			"details": []models.Deliverylogs{},
		})
	}

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

func GetDeliveryLogsv1(c *fiber.Ctx) error {
	deliveryID := c.Query("deliveryid")
	if deliveryID == "" {
		return c.Status(http.StatusBadRequest).JSON(fiber.Map{
			"code":    http.StatusBadRequest,
			"message": "deliveryid is required",
			"status":  false,
		})
	}

	logs, err := domain.GetDeliveryLogsv1(deliveryID)
	if err != nil {
		return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
			"code":    http.StatusInternalServerError,
			"message": err.Error(),
			"status":  false,
		})
	}

	return c.JSON(fiber.Map{
		"code":    200,
		"details": logs,
		"status":  true,
	})
}

func GetRiderByDelivery(c *fiber.Ctx) error {

	fromdate := strings.TrimSpace(c.Query("fromdate"))
	todate := strings.TrimSpace(c.Query("todate"))
	keyword := strings.TrimSpace(c.Query("keyword"))

	if fromdate == "" || todate == "" {
		return c.Status(400).JSON(fiber.Map{
			"code":    400,
			"status":  false,
			"message": "fromdate and todate are required",
		})
	}

	applocationidStr := strings.TrimSpace(c.Query("applocationid"))
	tenantidStr := strings.TrimSpace(c.Query("tenantid"))
	locationidStr := strings.TrimSpace(c.Query("locationid"))

	applocationid, _ := strconv.Atoi(applocationidStr)
	tenantid, _ := strconv.Atoi(tenantidStr)
	locationid, _ := strconv.Atoi(locationidStr)

	var users []models.User
	var params []interface{}

	query := `
        SELECT b.userid,b.authname,b.firstname,b.lastname,b.password,b.email,b.dialcode,b.contactno,b.configid,b.authmode,b.roleid,b.pin,b.deviceid,b.devicetype,b.userfcmtoken,
            b.address,b.suburb,b.city,b.state,b.postcode,b.partnerid,a.tenantid,a.locationid,a.applocationid,b.status,b.shiftid,b.hashsalt
        FROM deliveries a
        LEFT JOIN app_users b ON a.userid = b.userid
        WHERE a.deliverydate::date BETWEEN ?::date AND ?::date
    `
	params = append(params, fromdate, todate)

	if tenantid != 0 {
		query += " AND a.tenantid = ?"
		params = append(params, tenantid)
	}
	if locationid != 0 {
		query += " AND a.locationid = ?"
		params = append(params, locationid)
	}
	if applocationid != 0 {
		query += " AND a.applocationid = ?"
		params = append(params, applocationid)
	}

	if keyword != "" {
		k := "%" + strings.ToLower(keyword) + "%"
		query += `
            AND (
                LOWER(b.firstname) LIKE ? OR
                LOWER(b.lastname) LIKE ? OR
                LOWER(b.contactno) LIKE ?
            )
        `
		params = append(params, k, k, k)
	}

	query += " GROUP BY b.userid ORDER BY b.userid DESC"

	if err := db.DB.Raw(query, params...).Scan(&users).Error; err != nil {
		return c.Status(500).JSON(fiber.Map{
			"code":    500,
			"status":  false,
			"message": "Database error: " + err.Error(),
		})
	}

	return c.JSON(fiber.Map{
		"code":    200,
		"status":  true,
		"details": users,
	})
}

func GetLastDeliveryByContact(c *fiber.Ctx) error {
	deliverycontactno := c.Query("deliverycontactno")
	fromdate := c.Query("fromdate")
	todate := c.Query("todate")

	var data []models.Deliveries
	var query string
	var args []interface{}

	dateCondition := ""
	if fromdate != "" && todate != "" {
		dateCondition = " AND deliverydate::date BETWEEN ?::date AND ?::date "
		args = append(args, fromdate, todate)
	} else if fromdate != "" {
		dateCondition = " AND deliverydate::date >= ?::date "
		args = append(args, fromdate)
	} else if todate != "" {
		dateCondition = " AND deliverydate::date <= ?::date "
		args = append(args, todate)
	}

	if deliverycontactno == "" {

		query = `
            SELECT d.*
            FROM deliveries d
            INNER JOIN (
                SELECT deliverycontactno, MAX(deliveryid) AS maxid
                FROM deliveries
                WHERE 1=1 ` + dateCondition + `
                GROUP BY deliverycontactno
            ) t ON d.deliveryid = t.maxid
            ORDER BY d.deliveryid DESC;
        `
	} else {

		query = `
            SELECT *
            FROM deliveries
            WHERE deliverycontactno = ? ` + dateCondition + `
            ORDER BY deliveryid DESC
            LIMIT 1;
        `

		args = append([]interface{}{deliverycontactno}, args...)
	}

	if err := db.DB.Raw(query, args...).Scan(&data).Error; err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
			"code":    500,
			"message": err.Error(),
			"status":  false,
		})
	}

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

func GetUserReportSummary(c *fiber.Ctx) error {

	tid, _ := strconv.Atoi(c.Query("tenantid"))
	// pid, _ := strconv.Atoi(c.Query("partnerid"))
	uid, _ := strconv.Atoi(c.Query("userid"))
	// aid, _ := strconv.Atoi(c.Query("applocationid"))
	fdate := c.Query("fromdate")
	tdate := c.Query("todate")

	var data []models.UserReportSummary
	var q1 string

	var params []interface{}
	q1 = reports

	if tid != 0 {
		q1 += " WHERE a.tenantid = ?"
		params = append(params, tid)
	} else if uid != 0 {
		q1 += " WHERE c.userid = ?"
		params = append(params, uid)
	} else {
		q1 += " WHERE 1=1"
	}

	if fdate != "" && tdate != "" {
		q1 += " AND a.orderdate::date BETWEEN ?::date AND ?::date"
		params = append(params, fdate, tdate)
	}

	q1 += ` GROUP BY 
		      c.userid, e.firstname, e.lastname, e.contactno,
		      b.tenantid, b.tenantname`

	utils.Logger.Debugw("RiderLocationReportSummary SQL generated", "query", q1)

	db.DB.Raw(q1, params...).Scan(&data)

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

func GetUserDeliveryLogs(c *fiber.Ctx) error {
	userid, err := strconv.Atoi(c.Query("userid"))
	if err != nil || userid == 0 {
		return c.Status(400).JSON(fiber.Map{
			"code":    400,
			"message": "Invalid userid",
			"status":  false,
			"details": []models.Deliverylogs{},
		})
	}

	fromdate := strings.TrimSpace(c.Query("fromdate"))
	todate := strings.TrimSpace(c.Query("todate"))

	result, err := domain.GetUserDeliveryLogs(userid, fromdate, todate)
	if err != nil {
		return c.JSON(fiber.Map{
			"code":    409,
			"message": err.Error(),
			"status":  false,
			"details": []models.Deliverylogs{},
		})
	}

	return c.JSON(fiber.Map{
		"code":    200,
		"message": "Success",
		"status":  true,
		"details": result,
	})
}
