package handler

import (
	"context"
	"eslogad-be/internal/appcontext"

	"eslogad-be/internal/contract"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

type DispositionRouteService interface {
	Create(ctx context.Context, req *contract.CreateDispositionRouteRequest) (*contract.DispositionRouteResponse, error)
	Update(ctx context.Context, id uuid.UUID, req *contract.UpdateDispositionRouteRequest) (*contract.DispositionRouteResponse, error)
	Get(ctx context.Context, id uuid.UUID) (*contract.DispositionRouteResponse, error)
	ListByFromDept(ctx context.Context, from uuid.UUID) (*contract.ListDispositionRoutesResponse, error)
	SetActive(ctx context.Context, id uuid.UUID, active bool) error
}

type DispositionRouteHandler struct{ svc DispositionRouteService }

func NewDispositionRouteHandler(svc DispositionRouteService) *DispositionRouteHandler {
	return &DispositionRouteHandler{svc: svc}
}

func (h *DispositionRouteHandler) Create(c *gin.Context) {
	var req contract.CreateDispositionRouteRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(400, &contract.ErrorResponse{Error: "invalid body", Code: 400})
		return
	}
	resp, err := h.svc.Create(c.Request.Context(), &req)
	if err != nil {
		c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
		return
	}
	c.JSON(201, contract.BuildSuccessResponse(resp))
}

func (h *DispositionRouteHandler) Update(c *gin.Context) {
	id, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(400, &contract.ErrorResponse{Error: "invalid id", Code: 400})
		return
	}
	var req contract.UpdateDispositionRouteRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(400, &contract.ErrorResponse{Error: "invalid body", Code: 400})
		return
	}
	resp, err := h.svc.Update(c.Request.Context(), id, &req)
	if err != nil {
		c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
		return
	}
	c.JSON(200, contract.BuildSuccessResponse(resp))
}

func (h *DispositionRouteHandler) Get(c *gin.Context) {
	id, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(400, &contract.ErrorResponse{Error: "invalid id", Code: 400})
		return
	}
	resp, err := h.svc.Get(c.Request.Context(), id)
	if err != nil {
		c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
		return
	}
	c.JSON(200, contract.BuildSuccessResponse(resp))
}

func (h *DispositionRouteHandler) ListByFromDept(c *gin.Context) {
	appCtx := appcontext.FromGinContext(c.Request.Context())

	resp, err := h.svc.ListByFromDept(c.Request.Context(), appCtx.DepartmentID)
	if err != nil {
		c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
		return
	}
	c.JSON(200, contract.BuildSuccessResponse(resp))
}

func (h *DispositionRouteHandler) SetActive(c *gin.Context) {
	id, err := uuid.Parse(c.Param("id"))
	if err != nil {
		c.JSON(400, &contract.ErrorResponse{Error: "invalid id", Code: 400})
		return
	}
	toggle := c.Query("active")
	active := toggle != "false"
	if err := h.svc.SetActive(c.Request.Context(), id, active); err != nil {
		c.JSON(500, &contract.ErrorResponse{Error: err.Error(), Code: 500})
		return
	}
	c.JSON(200, &contract.SuccessResponse{Message: "updated"})
}
