package webhooks

import (
	"testing"
	"time"

	"github.com/stretchr/testify/require"

	"github.com/tidbcloud/AgentTeam/internal/core/webhook"
	"github.com/tidbcloud/AgentTeam/internal/store/app/runtime"
)

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

	connectionRef, status := ResolveGitHubServiceEventConnectionFromConnections(
		[]runtime.ConnectionView{{
			ExternalSubjectRef: "789",
			DisplayLabel:       "acme",
		}},
		"other/repo",
		"",
	)

	require.Empty(t, connectionRef)
	require.Equal(t, ServiceEventConnectionResourceNotAccessible, status)
}

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

	connectionRef, status := ResolveGitHubServiceEventConnectionFromConnections(
		[]runtime.ConnectionView{{
			ExternalSubjectRef: "789",
			DisplayLabel:       "789",
		}},
		"other/repo",
		"",
	)

	require.Equal(t, "789", connectionRef)
	require.Equal(t, ServiceEventConnectionReady, status)
}

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

	connectionRef, status := ResolveGitHubServiceEventConnectionFromConnections(
		[]runtime.ConnectionView{{
			ExternalSubjectRef: "789",
			DisplayLabel:       "acme",
		}},
		"acme/repo",
		"789",
	)

	require.Equal(t, "789", connectionRef)
	require.Equal(t, ServiceEventConnectionReady, status)
}

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

	payload := []byte(`{
	  "action": "submitted",
	  "repository": {
	    "full_name": "Acme/AgentTeam"
	  },
	  "pull_request": {
	    "number": 42,
	    "html_url": "https://github.com/acme/agentteam/pull/42",
	    "updated_at": "2026-04-19T10:10:00Z"
	  },
	  "review": {
	    "state": "approved",
	    "body": "LGTM",
	    "html_url": "https://github.com/acme/agentteam/pull/42#pullrequestreview-1",
	    "submitted_at": "2026-04-19T10:12:13Z",
	    "user": {
	      "login": "reviewer"
	    }
	  }
	}`)

	event, parsed, err := webhook.ParseGitHubWebhookPayload(payload)
	require.NoError(t, err)
	require.True(t, parsed)

	fallback := time.Date(2026, 4, 19, 12, 0, 0, 0, time.UTC)
	normalized, ok, err := webhook.NormalizeGitHubProviderEvent("ws_123", "789", "delivery-1", "pull_request_review_submitted", event, fallback)
	require.NoError(t, err)
	require.True(t, ok)
	require.Equal(t, time.Date(2026, 4, 19, 10, 12, 13, 0, time.UTC), normalized.OccurredAt)
}

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

	payload := []byte(`{
	  "action": "created",
	  "repository": {
	    "full_name": "Acme/AgentTeam"
	  },
	  "issue": {
	    "number": 42,
	    "html_url": "https://gitea.example.com/acme/agentteam/issues/42",
	    "pull_request": {
	      "html_url": "https://gitea.example.com/acme/agentteam/pulls/42"
	    }
	  },
	  "comment": {
	    "id": 1,
	    "body": "Please fix this",
	    "html_url": "https://gitea.example.com/acme/agentteam/issues/42#issuecomment-1",
	    "created_at": "2026-04-19T09:08:07Z",
	    "user": {
	      "login": "reviewer"
	    }
	  }
	}`)

	event, parsed, err := webhook.ParseGiteaWebhookPayload(payload)
	require.NoError(t, err)
	require.True(t, parsed)

	fallback := time.Date(2026, 4, 19, 12, 0, 0, 0, time.UTC)
	normalized, ok, err := webhook.NormalizeGiteaProviderEvent("ws_123", "acme", "delivery-2", "issue_comment_created", event, fallback, "https://gitea.example.com")
	require.NoError(t, err)
	require.True(t, ok)
	require.Equal(t, time.Date(2026, 4, 19, 9, 8, 7, 0, time.UTC), normalized.OccurredAt)
}

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

	payload := []byte(`{
	  "action": "reopened",
	  "repository": {
	    "full_name": "Acme/AgentTeam"
	  },
	  "pull_request": {
	    "number": 42,
	    "html_url": "https://github.com/acme/agentteam/pull/42"
	  },
	  "sender": {
	    "login": "maintainer"
	  }
	}`)

	event, parsed, err := webhook.ParseGitHubWebhookPayload(payload)
	require.NoError(t, err)
	require.True(t, parsed)

	fallback := time.Date(2026, 4, 19, 12, 34, 56, 0, time.UTC)
	normalized, ok, err := webhook.NormalizeGitHubProviderEvent("ws_123", "789", "delivery-3", "pull_request_reopened", event, fallback)
	require.NoError(t, err)
	require.True(t, ok)
	require.Equal(t, fallback, normalized.OccurredAt)
}
