package handler

import (
	"log"
	"net/http"
	"time"

	"github.com/gofrs/uuid/v5"
	"github.com/saveinmed/backend-go/internal/domain"
)

// CreateAddress godoc
// @Summary Criar novo endereço
// @Tags Endereços
// @Security BearerAuth
// @Accept json
// @Produce json
// @Param address body createAddressRequest true "Dados do endereço"
// @Success 201 {object} domain.Address
// @Failure 400 {object} map[string]string
// @Router /api/v1/enderecos [post]
func (h *Handler) CreateAddress(w http.ResponseWriter, r *http.Request) {
	reqUser, err := getRequester(r)
	if err != nil {
		writeError(w, http.StatusUnauthorized, err)
		return
	}

	var req createAddressRequest
	if err := decodeJSON(r.Context(), r, &req); err != nil {
		writeError(w, http.StatusBadRequest, err)
		return
	}

	// Use CompanyID if available, otherwise UserID
	entityID := reqUser.ID
	if reqUser.CompanyID != nil {
		entityID = *reqUser.CompanyID
	}

	// Admin Override
	if req.EntityID != nil && reqUser.Role == "Admin" {
		entityID = *req.EntityID
	}

	addr := domain.Address{
		EntityID:   entityID,
		Title:      req.Title,
		ZipCode:    req.ZipCode,
		Street:     req.Street,
		Number:     req.Number,
		Complement: req.Complement,
		District:   req.District,
		City:       req.City,
		State:      req.State,
		CreatedAt:  time.Now(),
		UpdatedAt:  time.Now(),
	}

	if err := h.svc.CreateAddress(r.Context(), &addr); err != nil {
		log.Printf("Failed to create address: %v", err)
		writeError(w, http.StatusInternalServerError, err)
		return
	}

	writeJSON(w, http.StatusCreated, addr)
}

// ListAddresses godoc
// @Summary Listar endereços do usuário
// @Tags Endereços
// @Security BearerAuth
// @Produce json
// @Success 200 {array} domain.Address
// @Failure 500 {object} map[string]string
// @Router /api/v1/enderecos [get]
func (h *Handler) ListAddresses(w http.ResponseWriter, r *http.Request) {
	reqUser, err := getRequester(r)
	if err != nil {
		writeError(w, http.StatusUnauthorized, err)
		return
	}

	entityID := reqUser.ID
	if reqUser.CompanyID != nil {
		entityID = *reqUser.CompanyID
	}

	// Admin Override
	if reqUser.Role == "Admin" {
		if queryID := r.URL.Query().Get("entity_id"); queryID != "" {
			if id, err := uuid.FromString(queryID); err == nil {
				entityID = id
			}
		}
	}

	addresses, err := h.svc.ListAddresses(r.Context(), entityID)
	if err != nil {
		writeError(w, http.StatusInternalServerError, err)
		return
	}

	writeJSON(w, http.StatusOK, addresses)
}

// UpdateAddress godoc
// @Summary Atualizar endereço
// @Tags Endereços
// @Security BearerAuth
// @Accept json
// @Produce json
// @Param id path string true "ID do endereço"
// @Param address body createAddressRequest true "Dados do endereço"
// @Success 200 {object} map[string]string
// @Failure 400 {object} map[string]string
// @Router /api/v1/enderecos/{id} [put]
func (h *Handler) UpdateAddress(w http.ResponseWriter, r *http.Request) {
	reqUser, err := getRequester(r)
	if err != nil {
		writeError(w, http.StatusUnauthorized, err)
		return
	}

	idStr := r.PathValue("id")
	id, err := uuid.FromString(idStr)
	if err != nil {
		writeError(w, http.StatusBadRequest, err)
		return
	}

	var req createAddressRequest
	if err := decodeJSON(r.Context(), r, &req); err != nil {
		writeError(w, http.StatusBadRequest, err)
		return
	}

	addr := domain.Address{
		ID:         id,
		Title:      req.Title,
		ZipCode:    req.ZipCode,
		Street:     req.Street,
		Number:     req.Number,
		Complement: req.Complement,
		District:   req.District,
		City:       req.City,
		State:      req.State,
	}

	var companyID uuid.UUID
	if reqUser.CompanyID != nil {
		companyID = *reqUser.CompanyID
	}
	user := &domain.User{
		ID:        reqUser.ID,
		Role:      reqUser.Role,
		CompanyID: companyID,
	}

	if err := h.svc.UpdateAddress(r.Context(), &addr, user); err != nil {
		writeError(w, http.StatusInternalServerError, err)
		return
	}

	writeJSON(w, http.StatusOK, map[string]string{"message": "address updated"})
}

// DeleteAddress godoc
// @Summary Deletar endereço
// @Tags Endereços
// @Security BearerAuth
// @Produce json
// @Param id path string true "ID do endereço"
// @Success 200 {object} map[string]string
// @Failure 400 {object} map[string]string
// @Router /api/v1/enderecos/{id} [delete]
func (h *Handler) DeleteAddress(w http.ResponseWriter, r *http.Request) {
	reqUser, err := getRequester(r)
	if err != nil {
		writeError(w, http.StatusUnauthorized, err)
		return
	}

	idStr := r.PathValue("id")
	id, err := uuid.FromString(idStr)
	if err != nil {
		writeError(w, http.StatusBadRequest, err)
		return
	}

	var companyID uuid.UUID
	if reqUser.CompanyID != nil {
		companyID = *reqUser.CompanyID
	}
	user := &domain.User{
		ID:        reqUser.ID,
		Role:      reqUser.Role,
		CompanyID: companyID,
	}

	if err := h.svc.DeleteAddress(r.Context(), id, user); err != nil {
		writeError(w, http.StatusInternalServerError, err)
		return
	}

	writeJSON(w, http.StatusOK, map[string]string{"message": "address deleted"})
}
