package handlers

import (
	"bytes"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/google/uuid"

	"mgit.msbls.de/m/KanzlAI-mGMT/internal/auth"
)

func TestCreateTenant_MissingFields(t *testing.T) {
	h := &TenantHandler{} // no service needed for validation

	// Build request with auth context
	body := `{"name":"","slug":""}`
	r := httptest.NewRequest("POST", "/api/tenants", bytes.NewBufferString(body))
	r = r.WithContext(auth.ContextWithUserID(r.Context(), uuid.New()))
	w := httptest.NewRecorder()

	h.CreateTenant(w, r)

	if w.Code != http.StatusBadRequest {
		t.Errorf("expected 400, got %d", w.Code)
	}

	var resp map[string]string
	json.NewDecoder(w.Body).Decode(&resp)
	if resp["error"] != "name and slug are required" {
		t.Errorf("unexpected error: %s", resp["error"])
	}
}

func TestCreateTenant_NoAuth(t *testing.T) {
	h := &TenantHandler{}
	r := httptest.NewRequest("POST", "/api/tenants", bytes.NewBufferString(`{}`))
	w := httptest.NewRecorder()

	h.CreateTenant(w, r)

	if w.Code != http.StatusUnauthorized {
		t.Errorf("expected 401, got %d", w.Code)
	}
}

func TestGetTenant_InvalidID(t *testing.T) {
	h := &TenantHandler{}
	r := httptest.NewRequest("GET", "/api/tenants/not-a-uuid", nil)
	r.SetPathValue("id", "not-a-uuid")
	r = r.WithContext(auth.ContextWithUserID(r.Context(), uuid.New()))
	w := httptest.NewRecorder()

	h.GetTenant(w, r)

	if w.Code != http.StatusBadRequest {
		t.Errorf("expected 400, got %d", w.Code)
	}
}

func TestInviteUser_InvalidTenantID(t *testing.T) {
	h := &TenantHandler{}
	body := `{"email":"test@example.com","role":"member"}`
	r := httptest.NewRequest("POST", "/api/tenants/bad/invite", bytes.NewBufferString(body))
	r.SetPathValue("id", "bad")
	r = r.WithContext(auth.ContextWithUserID(r.Context(), uuid.New()))
	w := httptest.NewRecorder()

	h.InviteUser(w, r)

	if w.Code != http.StatusBadRequest {
		t.Errorf("expected 400, got %d", w.Code)
	}
}

func TestInviteUser_NoAuth(t *testing.T) {
	h := &TenantHandler{}
	body := `{"email":"test@example.com"}`
	r := httptest.NewRequest("POST", "/api/tenants/"+uuid.New().String()+"/invite", bytes.NewBufferString(body))
	r.SetPathValue("id", uuid.New().String())
	w := httptest.NewRecorder()

	h.InviteUser(w, r)

	if w.Code != http.StatusUnauthorized {
		t.Errorf("expected 401, got %d", w.Code)
	}
}

func TestRemoveMember_InvalidIDs(t *testing.T) {
	h := &TenantHandler{}
	r := httptest.NewRequest("DELETE", "/api/tenants/bad/members/bad", nil)
	r.SetPathValue("id", "bad")
	r.SetPathValue("uid", "bad")
	r = r.WithContext(auth.ContextWithUserID(r.Context(), uuid.New()))
	w := httptest.NewRecorder()

	h.RemoveMember(w, r)

	if w.Code != http.StatusBadRequest {
		t.Errorf("expected 400, got %d", w.Code)
	}
}

func TestJsonResponse(t *testing.T) {
	w := httptest.NewRecorder()
	jsonResponse(w, map[string]string{"key": "value"}, http.StatusOK)

	if w.Code != http.StatusOK {
		t.Errorf("expected 200, got %d", w.Code)
	}
	if ct := w.Header().Get("Content-Type"); ct != "application/json" {
		t.Errorf("expected application/json, got %s", ct)
	}
}

func TestJsonError(t *testing.T) {
	w := httptest.NewRecorder()
	jsonError(w, "something went wrong", http.StatusBadRequest)

	if w.Code != http.StatusBadRequest {
		t.Errorf("expected 400, got %d", w.Code)
	}

	var resp map[string]string
	json.NewDecoder(w.Body).Decode(&resp)
	if resp["error"] != "something went wrong" {
		t.Errorf("unexpected error: %s", resp["error"])
	}
}
