package dev.lions.unionflow.server.api.dto.dashboard;

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

import java.time.LocalDateTime;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

/**
 * Tests unitaires pour RecentActivityResponse.
 * Couvre getTimeAgo (toutes branches), getActivityIcon, getActivityColor, getIsRecent, getIsToday.
 *
 * @author UnionFlow Team
 * @version 1.0
 * @since 2026-02-21
 */
@DisplayName("Tests RecentActivityResponse")
class RecentActivityResponseTest {

  @Nested
  @DisplayName("getTimeAgo")
  class GetTimeAgo {

    @Test
    @DisplayName("retourne chaîne vide quand timestamp null")
    void testNull() {
      RecentActivityResponse dto = RecentActivityResponse.builder().build();
      assertThat(dto.getTimeAgo()).isEmpty();
    }

    @Test
    @DisplayName("retourne Xmin quand moins de 60 minutes")
    void testMinutes() {
      RecentActivityResponse dto = RecentActivityResponse.builder()
          .timestamp(LocalDateTime.now().minusMinutes(30)).build();
      assertThat(dto.getTimeAgo()).isEqualTo("30min");
    }

    @Test
    @DisplayName("retourne Xh quand moins de 24h")
    void testHeures() {
      RecentActivityResponse dto = RecentActivityResponse.builder()
          .timestamp(LocalDateTime.now().minusHours(5)).build();
      assertThat(dto.getTimeAgo()).isEqualTo("5h");
    }

    @Test
    @DisplayName("retourne Xj quand moins de 7 jours")
    void testJours() {
      RecentActivityResponse dto = RecentActivityResponse.builder()
          .timestamp(LocalDateTime.now().minusDays(3)).build();
      assertThat(dto.getTimeAgo()).isEqualTo("3j");
    }

    @Test
    @DisplayName("retourne Xsem quand 7 jours ou plus")
    void testSemaines() {
      RecentActivityResponse dto = RecentActivityResponse.builder()
          .timestamp(LocalDateTime.now().minusDays(14)).build();
      assertThat(dto.getTimeAgo()).isEqualTo("2sem");
    }
  }

  @Nested
  @DisplayName("getActivityIcon")
  class GetActivityIcon {

    @Test
    @DisplayName("retourne help_outline quand type null")
    void testNull() {
      RecentActivityResponse dto = RecentActivityResponse.builder().build();
      assertThat(dto.getActivityIcon()).isEqualTo("help_outline");
    }

    @Test
    @DisplayName("retourne icône selon type member, event, contribution, organization, system")
    void testIcons() {
      assertThat(RecentActivityResponse.builder().type("member").build().getActivityIcon()).isEqualTo("person");
      assertThat(RecentActivityResponse.builder().type("event").build().getActivityIcon()).isEqualTo("event");
      assertThat(RecentActivityResponse.builder().type("contribution").build().getActivityIcon()).isEqualTo("payment");
      assertThat(RecentActivityResponse.builder().type("organization").build().getActivityIcon()).isEqualTo("business");
      assertThat(RecentActivityResponse.builder().type("system").build().getActivityIcon()).isEqualTo("settings");
    }

    @Test
    @DisplayName("retourne info pour type inconnu")
    void testDefault() {
      RecentActivityResponse dto = RecentActivityResponse.builder().type("other").build();
      assertThat(dto.getActivityIcon()).isEqualTo("info");
    }

    @Test
    @DisplayName("type insensible à la casse")
    void testCaseInsensitive() {
      assertThat(RecentActivityResponse.builder().type("MEMBER").build().getActivityIcon()).isEqualTo("person");
    }
  }

  @Nested
  @DisplayName("getActivityColor")
  class GetActivityColor {

    @Test
    @DisplayName("retourne grey quand type null")
    void testNull() {
      RecentActivityResponse dto = RecentActivityResponse.builder().build();
      assertThat(dto.getActivityColor()).isEqualTo("#6B7280");
    }

    @Test
    @DisplayName("retourne couleur selon type")
    void testCouleurs() {
      assertThat(RecentActivityResponse.builder().type("member").build().getActivityColor()).isEqualTo("#10B981");
      assertThat(RecentActivityResponse.builder().type("event").build().getActivityColor()).isEqualTo("#3B82F6");
      assertThat(RecentActivityResponse.builder().type("contribution").build().getActivityColor()).isEqualTo("#008B8B");
      assertThat(RecentActivityResponse.builder().type("organization").build().getActivityColor()).isEqualTo("#4169E1");
      assertThat(RecentActivityResponse.builder().type("system").build().getActivityColor()).isEqualTo("#6B7280");
    }

    @Test
    @DisplayName("retourne grey pour type inconnu")
    void testDefault() {
      RecentActivityResponse dto = RecentActivityResponse.builder().type("other").build();
      assertThat(dto.getActivityColor()).isEqualTo("#6B7280");
    }
  }

  @Nested
  @DisplayName("getIsRecent")
  class GetIsRecent {

    @Test
    @DisplayName("retourne false quand timestamp null")
    void testNull() {
      RecentActivityResponse dto = RecentActivityResponse.builder().build();
      assertThat(dto.getIsRecent()).isFalse();
    }

    @Test
    @DisplayName("retourne true quand moins de 24h")
    void testRecent() {
      RecentActivityResponse dto = RecentActivityResponse.builder()
          .timestamp(LocalDateTime.now().minusHours(2)).build();
      assertThat(dto.getIsRecent()).isTrue();
    }

    @Test
    @DisplayName("retourne false quand plus de 24h")
    void testNotRecent() {
      RecentActivityResponse dto = RecentActivityResponse.builder()
          .timestamp(LocalDateTime.now().minusHours(25)).build();
      assertThat(dto.getIsRecent()).isFalse();
    }
  }

  @Nested
  @DisplayName("getIsToday")
  class GetIsToday {

    @Test
    @DisplayName("retourne false quand timestamp null")
    void testNull() {
      RecentActivityResponse dto = RecentActivityResponse.builder().build();
      assertThat(dto.getIsToday()).isFalse();
    }

    @Test
    @DisplayName("retourne true quand timestamp aujourd'hui")
    void testToday() {
      RecentActivityResponse dto = RecentActivityResponse.builder()
          .timestamp(LocalDateTime.now()).build();
      assertThat(dto.getIsToday()).isTrue();
    }

    @Test
    @DisplayName("retourne false quand timestamp autre jour")
    void testOtherDay() {
      RecentActivityResponse dto = RecentActivityResponse.builder()
          .timestamp(LocalDateTime.now().minusDays(1)).build();
      assertThat(dto.getIsToday()).isFalse();
    }
  }

  @Nested
  @DisplayName("Getters standards")
  class GettersStandards {

    @Test
    @DisplayName("tous les champs builder sont accessibles")
    void testBuilderGetters() {
      LocalDateTime ts = LocalDateTime.now();
      RecentActivityResponse dto = RecentActivityResponse.builder()
          .id("act1")
          .type("event")
          .title("Titre")
          .description("Desc")
          .userName("User")
          .timestamp(ts)
          .userAvatar("http://avatar")
          .actionUrl("http://action")
          .build();
      assertThat(dto.getId()).isEqualTo("act1");
      assertThat(dto.getType()).isEqualTo("event");
      assertThat(dto.getTitle()).isEqualTo("Titre");
      assertThat(dto.getDescription()).isEqualTo("Desc");
      assertThat(dto.getUserName()).isEqualTo("User");
      assertThat(dto.getTimestamp()).isEqualTo(ts);
      assertThat(dto.getUserAvatar()).isEqualTo("http://avatar");
      assertThat(dto.getActionUrl()).isEqualTo("http://action");
    }
  }
}
