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;

@DisplayName("Tests pour RecentActivityDTO")
class RecentActivityDTOTest {

  @Test
  @DisplayName("Test de base - classe peut être instanciée")
  void testClasseInstanciable() {
    RecentActivityDTO dto = new RecentActivityDTO();
    assertThat(dto).isNotNull();
  }

  @Nested
  @DisplayName("Tests de construction")
  class ConstructionTests {

    @Test
    @DisplayName("Constructeur par défaut")
    void testConstructeurParDefaut() {
      RecentActivityDTO dto = new RecentActivityDTO();

      assertThat(dto).isNotNull();
    }

    @Test
    @DisplayName("Builder pattern")
    void testBuilder() {
      LocalDateTime timestamp = LocalDateTime.now();
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .id("act-123")
          .type("member")
          .title("Nouveau membre")
          .description("Un nouveau membre a rejoint")
          .userName("Jean Dupont")
          .timestamp(timestamp)
          .userAvatar("http://example.com/avatar.jpg")
          .actionUrl("http://example.com/action")
          .build();

      assertThat(dto.getId()).isEqualTo("act-123");
      assertThat(dto.getType()).isEqualTo("member");
      assertThat(dto.getTitle()).isEqualTo("Nouveau membre");
      assertThat(dto.getDescription()).isEqualTo("Un nouveau membre a rejoint");
      assertThat(dto.getUserName()).isEqualTo("Jean Dupont");
      assertThat(dto.getTimestamp()).isEqualTo(timestamp);
      assertThat(dto.getUserAvatar()).isEqualTo("http://example.com/avatar.jpg");
      assertThat(dto.getActionUrl()).isEqualTo("http://example.com/action");
    }
  }

  @Nested
  @DisplayName("Tests getTimeAgo")
  class GetTimeAgoTests {

    @Test
    @DisplayName("getTimeAgo - moins de 60 minutes")
    void testGetTimeAgoMinutes() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .timestamp(LocalDateTime.now().minusMinutes(30))
          .build();

      String timeAgo = dto.getTimeAgo();
      assertThat(timeAgo).contains("min");
    }

    @Test
    @DisplayName("getTimeAgo - moins de 24 heures")
    void testGetTimeAgoHeures() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .timestamp(LocalDateTime.now().minusHours(5))
          .build();

      String timeAgo = dto.getTimeAgo();
      assertThat(timeAgo).contains("h");
    }

    @Test
    @DisplayName("getTimeAgo - moins de 7 jours")
    void testGetTimeAgoJours() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .timestamp(LocalDateTime.now().minusDays(3))
          .build();

      String timeAgo = dto.getTimeAgo();
      assertThat(timeAgo).contains("j");
    }

    @Test
    @DisplayName("getTimeAgo - plus de 7 jours")
    void testGetTimeAgoSemaines() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .timestamp(LocalDateTime.now().minusDays(14))
          .build();

      String timeAgo = dto.getTimeAgo();
      assertThat(timeAgo).contains("sem");
    }

    @Test
    @DisplayName("getTimeAgo - timestamp null")
    void testGetTimeAgoNull() {
      RecentActivityDTO dto = new RecentActivityDTO();

      assertThat(dto.getTimeAgo()).isEmpty();
    }
  }

  @Nested
  @DisplayName("Tests getActivityIcon")
  class GetActivityIconTests {

    @Test
    @DisplayName("getActivityIcon - type member")
    void testGetActivityIconMember() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .type("member")
          .build();

      assertThat(dto.getActivityIcon()).isEqualTo("person");
    }

    @Test
    @DisplayName("getActivityIcon - type event")
    void testGetActivityIconEvent() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .type("event")
          .build();

      assertThat(dto.getActivityIcon()).isEqualTo("event");
    }

    @Test
    @DisplayName("getActivityIcon - type contribution")
    void testGetActivityIconContribution() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .type("contribution")
          .build();

      assertThat(dto.getActivityIcon()).isEqualTo("payment");
    }

    @Test
    @DisplayName("getActivityIcon - type organization")
    void testGetActivityIconOrganization() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .type("organization")
          .build();

      assertThat(dto.getActivityIcon()).isEqualTo("business");
    }

    @Test
    @DisplayName("getActivityIcon - type system")
    void testGetActivityIconSystem() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .type("system")
          .build();

      assertThat(dto.getActivityIcon()).isEqualTo("settings");
    }

    @Test
    @DisplayName("getActivityIcon - type inconnu")
    void testGetActivityIconInconnu() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .type("unknown")
          .build();

      assertThat(dto.getActivityIcon()).isEqualTo("info");
    }

    @Test
    @DisplayName("getActivityIcon - type null")
    void testGetActivityIconNull() {
      RecentActivityDTO dto = new RecentActivityDTO();

      assertThat(dto.getActivityIcon()).isEqualTo("help_outline");
    }

    @Test
    @DisplayName("getActivityIcon - type en majuscules")
    void testGetActivityIconMajuscules() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .type("MEMBER")
          .build();

      assertThat(dto.getActivityIcon()).isEqualTo("person");
    }
  }

  @Nested
  @DisplayName("Tests getActivityColor")
  class GetActivityColorTests {

    @Test
    @DisplayName("getActivityColor - type member")
    void testGetActivityColorMember() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .type("member")
          .build();

      assertThat(dto.getActivityColor()).isEqualTo("#10B981");
    }

    @Test
    @DisplayName("getActivityColor - type event")
    void testGetActivityColorEvent() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .type("event")
          .build();

      assertThat(dto.getActivityColor()).isEqualTo("#3B82F6");
    }

    @Test
    @DisplayName("getActivityColor - type contribution")
    void testGetActivityColorContribution() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .type("contribution")
          .build();

      assertThat(dto.getActivityColor()).isEqualTo("#008B8B");
    }

    @Test
    @DisplayName("getActivityColor - type organization")
    void testGetActivityColorOrganization() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .type("organization")
          .build();

      assertThat(dto.getActivityColor()).isEqualTo("#4169E1");
    }

    @Test
    @DisplayName("getActivityColor - type system")
    void testGetActivityColorSystem() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .type("system")
          .build();

      assertThat(dto.getActivityColor()).isEqualTo("#6B7280");
    }

    @Test
    @DisplayName("getActivityColor - type null")
    void testGetActivityColorNull() {
      RecentActivityDTO dto = new RecentActivityDTO();

      assertThat(dto.getActivityColor()).isEqualTo("#6B7280");
    }
  }

  @Nested
  @DisplayName("Tests getIsRecent")
  class GetIsRecentTests {

    @Test
    @DisplayName("getIsRecent - activité récente")
    void testGetIsRecent() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .timestamp(LocalDateTime.now().minusHours(12))
          .build();

      assertThat(dto.getIsRecent()).isTrue();
    }

    @Test
    @DisplayName("getIsRecent - activité ancienne")
    void testGetIsRecentAncienne() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .timestamp(LocalDateTime.now().minusHours(25))
          .build();

      assertThat(dto.getIsRecent()).isFalse();
    }

    @Test
    @DisplayName("getIsRecent - timestamp null")
    void testGetIsRecentNull() {
      RecentActivityDTO dto = new RecentActivityDTO();

      assertThat(dto.getIsRecent()).isFalse();
    }
  }

  @Nested
  @DisplayName("Tests getIsToday")
  class GetIsTodayTests {

    @Test
    @DisplayName("getIsToday - aujourd'hui")
    void testGetIsToday() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .timestamp(LocalDateTime.now())
          .build();

      assertThat(dto.getIsToday()).isTrue();
    }

    @Test
    @DisplayName("getIsToday - hier")
    void testGetIsTodayHier() {
      RecentActivityDTO dto = RecentActivityDTO.builder()
          .timestamp(LocalDateTime.now().minusDays(1))
          .build();

      assertThat(dto.getIsToday()).isFalse();
    }

    @Test
    @DisplayName("getIsToday - timestamp null")
    void testGetIsTodayNull() {
      RecentActivityDTO dto = new RecentActivityDTO();

      assertThat(dto.getIsToday()).isFalse();
    }
  }
}

