package de.cannamanage.api.integration;

import de.cannamanage.api.dto.distribution.CreateDistributionRequest;
import de.cannamanage.api.dto.member.MemberResponse;
import de.cannamanage.api.dto.stock.BatchResponse;
import org.junit.jupiter.api.*;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;

/**
 * Integration test: Multi-tenant data isolation.
 * Verifies that Tenant A cannot see Tenant B's members (and vice versa).
 */
class TenantIsolationTest extends AbstractIntegrationTest {

    private UUID tenantA;
    private UUID tenantB;
    private String tokenA;
    private String tokenB;

    @BeforeEach
    void setUp() {
        tenantA = createTestClub("Club Alpha");
        tenantB = createTestClub("Club Beta");

        createAdminUser(tenantA, "admin-a@alpha.de", "AlphaPass123!");
        createAdminUser(tenantB, "admin-b@beta.de", "BetaPass123!");

        tokenA = getAccessToken("admin-a@alpha.de", "AlphaPass123!");
        tokenB = getAccessToken("admin-b@beta.de", "BetaPass123!");
    }

    @Test
    @DisplayName("Tenant A creates members — only visible to Tenant A")
    void tenantA_createsMembers_onlyVisibleToTenantA() {
        createTestMember(tokenA, "Anna", "Alpha", "anna@alpha.de", LocalDate.of(1990, 1, 15));
        createTestMember(tokenA, "Alex", "Alpha", "alex@alpha.de", LocalDate.of(1985, 6, 20));

        ResponseEntity<String> responseA = restClient().get()
                .uri("/api/v1/members")
                .header("Authorization", "Bearer " + tokenA)
                .retrieve()
                .toEntity(String.class);

        assertThat(responseA.getStatusCode().value()).isEqualTo(200);
        assertThat(responseA.getBody()).contains("Anna");
        assertThat(responseA.getBody()).contains("Alex");
    }

    @Test
    @DisplayName("Tenant B creates members — only visible to Tenant B")
    void tenantB_createsMembers_onlyVisibleToTenantB() {
        createTestMember(tokenB, "Bob", "Beta", "bob@beta.de", LocalDate.of(1992, 3, 10));

        ResponseEntity<String> responseB = restClient().get()
                .uri("/api/v1/members")
                .header("Authorization", "Bearer " + tokenB)
                .retrieve()
                .toEntity(String.class);

        assertThat(responseB.getStatusCode().value()).isEqualTo(200);
        assertThat(responseB.getBody()).contains("Bob");
    }

    @Test
    @DisplayName("Tenant A cannot see Tenant B's members")
    void tenantA_cannotSeeTenantB_members() {
        createTestMember(tokenA, "Anna", "Alpha", "anna2@alpha.de", LocalDate.of(1990, 1, 15));
        createTestMember(tokenB, "Bob", "Beta", "bob2@beta.de", LocalDate.of(1992, 3, 10));

        ResponseEntity<String> responseA = restClient().get()
                .uri("/api/v1/members")
                .header("Authorization", "Bearer " + tokenA)
                .retrieve()
                .toEntity(String.class);

        assertThat(responseA.getStatusCode().value()).isEqualTo(200);
        assertThat(responseA.getBody()).contains("Anna");
        assertThat(responseA.getBody()).doesNotContain("Bob");
    }

    @Test
    @DisplayName("Tenant B cannot see Tenant A's members")
    void tenantB_cannotSeeTenantA_members() {
        createTestMember(tokenA, "Anna", "Alpha", "anna3@alpha.de", LocalDate.of(1990, 1, 15));
        createTestMember(tokenB, "Bob", "Beta", "bob3@beta.de", LocalDate.of(1992, 3, 10));

        ResponseEntity<String> responseB = restClient().get()
                .uri("/api/v1/members")
                .header("Authorization", "Bearer " + tokenB)
                .retrieve()
                .toEntity(String.class);

        assertThat(responseB.getStatusCode().value()).isEqualTo(200);
        assertThat(responseB.getBody()).contains("Bob");
        assertThat(responseB.getBody()).doesNotContain("Anna");
    }

    @Test
    @DisplayName("Distributions are isolated between tenants")
    void distributions_areIsolated_betweenTenants() {
        MemberResponse memberA = createTestMember(tokenA, "Anna", "Alpha",
                "anna4@alpha.de", LocalDate.of(1990, 1, 15));

        BatchResponse batchA = createTestBatch(tokenA, UUID.randomUUID(),
                new BigDecimal("100.0"), "BATCH-A-001");

        // Create distribution for Tenant A
        restClient().post()
                .uri("/api/v1/distributions")
                .header("Authorization", "Bearer " + tokenA)
                .contentType(MediaType.APPLICATION_JSON)
                .body(new CreateDistributionRequest(
                        memberA.id(), batchA.id(), new BigDecimal("5.0"), "Test distribution A"))
                .retrieve()
                .toEntity(String.class);

        // Tenant B's distribution list should be empty
        ResponseEntity<String> responseB = restClient().get()
                .uri("/api/v1/distributions")
                .header("Authorization", "Bearer " + tokenB)
                .retrieve()
                .toEntity(String.class);

        assertThat(responseB.getStatusCode().value()).isEqualTo(200);
        assertThat(responseB.getBody()).isEqualTo("[]");
    }
}
