package controllers

import (
	"net/http"
	"strconv"

	"nearle/models"
	"nearle/services"

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

type DeliveriesController struct {
	deliveriesService services.DeliveriesService
}

func NewDeliveriesController(deliveriesService services.DeliveriesService) *DeliveriesController {
	return &DeliveriesController{deliveriesService: deliveriesService}
}

func (ctl *DeliveriesController) CreateDeliveries(c *fiber.Ctx) error {
	var deliveries []models.Deliveries

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

	err := ctl.deliveriesService.CreateDeliveriesService(deliveries)
	if err != nil {
		return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
			"code":    500,
			"status":  false,
			"message": err.Error(),
		})
	}

	return c.Status(http.StatusOK).JSON(fiber.Map{
		"code":    200,
		"status":  true,
		"message": "Deliveries created successfully",
	})
}

func (ctl *DeliveriesController) UpdateDelivery(c *fiber.Ctx) error {
	var data models.UpdateDeliveryStatus

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

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

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

func (ctl *DeliveriesController) GetDeliverySummary(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"))
	lid, _ := strconv.Atoi(c.Query("locationid"))
	fdate := c.Query("fromdate")
	tdate := c.Query("todate")

	data, err := ctl.deliveriesService.GetDeliverySummary(tid, pid, uid, aid, lid, fdate, tdate)
	if err != nil {
		return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
			"code":    http.StatusInternalServerError,
			"message": err.Error(),
			"status":  false,
		})
	}

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

func (ctl *DeliveriesController) GetDeliveryInsight(c *fiber.Ctx) error {
	// Get tenantid from query param
	tenantIDStr := c.Query("tenantid")
	tenantID, _ := strconv.Atoi(tenantIDStr)

	// Call service with tenantID
	locations, err := ctl.deliveriesService.GetDeliveryInsightService(tenantID)
	if err != nil {
		return c.Status(http.StatusConflict).JSON(fiber.Map{
			"code":    http.StatusConflict,
			"message": err.Error(),
			"status":  false,
		})
	}

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

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

	data, err := ctl.deliveriesService.GetLocationDeliverySummary(tenantID)
	if 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 (ctl *DeliveriesController) 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")

	data, err := ctl.deliveriesService.GetReportSummary(tid, pid, uid, aid, fdate, tdate)
	if err != nil {
		return c.JSON(fiber.Map{
			"code":    http.StatusInternalServerError,
			"message": err.Error(),
			"status":  false,
		})
	}

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

func (ctl *DeliveriesController) GetRiderSummary(c *fiber.Ctx) error {
	aid, _ := strconv.Atoi(c.Query("applocationid"))
	pid, _ := strconv.Atoi(c.Query("partnerid"))
	tid, _ := strconv.Atoi(c.Query("tenantid"))
	fdate := c.Query("fromdate")
	tdate := c.Query("todate")

	data, err := ctl.deliveriesService.GetRiderSummary(aid, pid, tid, fdate, tdate)
	if err != nil {
		return c.JSON(fiber.Map{
			"code":    http.StatusInternalServerError,
			"message": err.Error(),
			"status":  false,
		})
	}

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

func (ctl *DeliveriesController) GetDeliveries(c *fiber.Ctx) error {

	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"))
	lid, _ := strconv.Atoi(c.Query("locationid")) // 👈 NEW

	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")

	if pid == 0 && tid == 0 && uid == 0 && cid == 0 && aid == 0 && aud == 0 {
		return c.Status(http.StatusBadRequest).JSON(fiber.Map{
			"code":    http.StatusBadRequest,
			"message": "At least one of tenantid, partnerid, customerid, applocationid, userid or appuserid is required",
			"status":  false,
		})
	}

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

	result := ctl.deliveriesService.GetDeliveries(info)
	if result == nil {
		result = []models.Deliveryinfo{}
	}

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

func (ctl *DeliveriesController) GetDeliveryQueues(c *fiber.Ctx) error {
	fdate := c.Query("fromdate")
	tdate := c.Query("todate")
	uid, _ := strconv.Atoi(c.Query("userid"))

	result, err := ctl.deliveriesService.GetDeliveryQueues(uid, fdate, tdate)
	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":    http.StatusOK,
		"message": "Success",
		"status":  true,
		"details": result,
	})
}
