package org_test

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

	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/require"

	. "github.com/tidbcloud/AgentTeam/internal/api/testkit"
	agentteamorg "github.com/tidbcloud/AgentTeam/internal/store/organization"
)

func TestTiDBOrganizationProviderTokensSupportStructuredCodexCredentials(t *testing.T) {
	t.Parallel()

	runtime := startTiDBRuntimeWithOrganizationOptions(t, agentteamorg.ServiceOptions{
		FeishuCredentialEncryptionKey: testFeishuCredentialEncryptionKey(),
	})

	router := gin.New()
	runtime.RegisterRoutes(router)
	server := httptest.NewServer(router)
	defer server.Close()

	client := server.Client()
	ownerAuth := RegisterUserForOrganizationTests(t, client, server.URL, "tidb-codex-owner@example.com", "tidb-codex-owner")

	organization := FirstOrganizationForTests(t, client, server.URL, ownerAuth.AccessToken)
	response := (*http.Response)(nil)

	var provider agentteamorg.OrganizationProviderView
	response = DoJSON(t, client, http.MethodPost, server.URL+"/api/v1/orgs/"+organization.ID+"/providers", map[string]any{
		"name":       "Codex",
		"slug":       "codex",
		"driverKind": "codex",
		"capabilities": map[string]any{
			"openaiCompatible":    true,
			"responsesCompatible": true,
		},
		"models": []map[string]any{
			{"id": "gpt-5.3-codex", "name": "GPT-5.3 Codex"},
		},
	}, AuthHeaders(ownerAuth.AccessToken), &provider)
	require.Equal(t, http.StatusOK, response.StatusCode)
	require.Equal(t, "codex", provider.DriverKind)

	var createdBody map[string]any
	response = DoJSON(t, client, http.MethodPost, server.URL+"/api/v1/orgs/"+organization.ID+"/providers/"+provider.ID+"/tokens", map[string]any{
		"label": "primary",
		"config": map[string]any{
			"role":               "primary",
			"mode":               "api_key",
			"customPrompt":       "Act like Codex",
			"customPromptModels": []string{"gpt-5.3-codex"},
		},
		"secret": map[string]any{
			"apiKey": "sk-codex-12345",
		},
	}, AuthHeaders(ownerAuth.AccessToken), &createdBody)
	require.Equal(t, http.StatusOK, response.StatusCode, "body=%v", createdBody)
	createdRaw, err := json.Marshal(createdBody)
	require.NoError(t, err)
	var created agentteamorg.OrganizationProviderTokenView
	require.NoError(t, json.Unmarshal(createdRaw, &created))
	require.Equal(t, "primary", created.Config.Role)
	require.Equal(t, "api_key", created.Config.Mode)
	require.Equal(t, "Act like Codex", created.Config.CustomPrompt)
	require.Equal(t, []string{"gpt-5.3-codex"}, created.Config.CustomPromptModels)
	require.Equal(t, "2345", created.TokenHint)

	var listed []agentteamorg.OrganizationProviderTokenView
	response = DoJSON(t, client, http.MethodGet, server.URL+"/api/v1/orgs/"+organization.ID+"/providers/"+provider.ID+"/tokens", nil, AuthHeaders(ownerAuth.AccessToken), &listed)
	require.Equal(t, http.StatusOK, response.StatusCode)
	require.Len(t, listed, 1)
	require.Equal(t, created.ID, listed[0].ID)
	require.Equal(t, "primary", listed[0].Config.Role)
	require.Equal(t, "api_key", listed[0].Config.Mode)
	require.Equal(t, "Act like Codex", listed[0].Config.CustomPrompt)
	require.Equal(t, []string{"gpt-5.3-codex"}, listed[0].Config.CustomPromptModels)

	var authState struct {
		Configured bool `json:"configured"`
		Auth       []struct {
			Source string `json:"source"`
			Mode   string `json:"mode"`
			APIKey string `json:"apiKey"`
		} `json:"auth"`
		TotalCount int `json:"totalCount"`
	}
	response = DoJSON(t, client, http.MethodGet, server.URL+"/api/v1/orgs/"+organization.ID+"/providers/"+provider.ID+"/codex/auth", nil, AuthHeaders(ownerAuth.AccessToken), &authState)
	require.Equal(t, http.StatusOK, response.StatusCode)
	require.True(t, authState.Configured)
	require.Len(t, authState.Auth, 1)
	require.Equal(t, "primary", authState.Auth[0].Source)
	require.Equal(t, "api_key", authState.Auth[0].Mode)
	require.Contains(t, authState.Auth[0].APIKey, "****")
	require.Equal(t, 1, authState.TotalCount)
}
