package dev.lions.unionflow.server.api;

import dev.lions.unionflow.server.api.dto.analytics.AnalyticsDataDTO;
import dev.lions.unionflow.server.api.dto.dashboard.DashboardDataDTO;
import dev.lions.unionflow.server.api.dto.dashboard.DashboardStatsDTO;
import dev.lions.unionflow.server.api.dto.dashboard.RecentActivityDTO;
import dev.lions.unionflow.server.api.dto.dashboard.UpcomingEventDTO;
import dev.lions.unionflow.server.api.dto.membre.MembreDTO;
import dev.lions.unionflow.server.api.dto.membre.MembreSearchCriteria;
import dev.lions.unionflow.server.api.dto.membre.MembreSearchResultDTO;
import dev.lions.unionflow.server.api.dto.notification.NotificationDTO;
import dev.lions.unionflow.server.api.enums.membre.StatutMembre;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Factory pour créer des objets de test réutilisables.
 * Principe: Write Once, Use Everywhere (WOU) et DRY.
 */
public final class TestDataFactory {

  private TestDataFactory() {
    // Utility class
  }

  // ===== MEMBRE DTO =====

  public static MembreDTO createMembreDTO() {
    return createMembreDTO("UF-2025-000001", "Dupont", "Jean", "jean@example.com");
  }

  public static MembreDTO createMembreDTO(String numero, String nom, String prenom, String email) {
    MembreDTO membre = new MembreDTO(numero, nom, prenom, email);
    membre.setAssociationId(UUID.randomUUID());
    membre.setStatut(StatutMembre.ACTIF);
    return membre;
  }

  public static MembreDTO createMembreDTOWithAge(int age) {
    MembreDTO membre = createMembreDTO();
    membre.setDateNaissance(LocalDate.now().minusYears(age));
    return membre;
  }

  // ===== MEMBRE SEARCH CRITERIA =====

  public static MembreSearchCriteria createMembreSearchCriteria() {
    return new MembreSearchCriteria();
  }

  public static MembreSearchCriteria createMembreSearchCriteria(String query) {
    MembreSearchCriteria criteria = new MembreSearchCriteria();
    criteria.setQuery(query);
    return criteria;
  }

  // ===== MEMBRE SEARCH RESULT =====

  public static MembreSearchResultDTO createMembreSearchResultDTO() {
    MembreSearchResultDTO result = new MembreSearchResultDTO();
    result.setMembres(List.of());
    result.setTotalElements(0L);
    result.setTotalPages(0);
    result.setCurrentPage(0);
    result.setPageSize(20);
    return result;
  }

  public static MembreSearchResultDTO createMembreSearchResultDTO(
      List<MembreDTO> membres, long totalElements, int totalPages, int currentPage) {
    MembreSearchResultDTO result = new MembreSearchResultDTO();
    result.setMembres(membres);
    result.setTotalElements(totalElements);
    result.setTotalPages(totalPages);
    result.setCurrentPage(currentPage);
    result.setPageSize(20);
    result.setNumberOfElements(membres != null ? membres.size() : 0);
    result.calculatePaginationFlags();
    return result;
  }

  // ===== DASHBOARD DTOs =====

  public static DashboardStatsDTO createDashboardStatsDTO() {
    return DashboardStatsDTO.builder()
        .totalMembers(100)
        .activeMembers(80)
        .totalEvents(50)
        .upcomingEvents(10)
        .totalContributions(200)
        .totalContributionAmount(50000.0)
        .pendingRequests(5)
        .completedProjects(15)
        .monthlyGrowth(5.5)
        .engagementRate(0.75)
        .lastUpdated(LocalDateTime.now())
        .build();
  }

  public static RecentActivityDTO createRecentActivityDTO() {
    return createRecentActivityDTO("member", LocalDateTime.now().minusHours(1));
  }

  public static RecentActivityDTO createRecentActivityDTO(String type, LocalDateTime timestamp) {
    return RecentActivityDTO.builder()
        .id("act-" + UUID.randomUUID().toString().substring(0, 8))
        .type(type)
        .title("Test Activity")
        .description("Test Description")
        .userName("Test User")
        .timestamp(timestamp)
        .build();
  }

  public static UpcomingEventDTO createUpcomingEventDTO() {
    return createUpcomingEventDTO(LocalDateTime.now().plusDays(1));
  }

  public static UpcomingEventDTO createUpcomingEventDTO(LocalDateTime startDate) {
    return UpcomingEventDTO.builder()
        .id("event-" + UUID.randomUUID().toString().substring(0, 8))
        .title("Test Event")
        .description("Test Description")
        .startDate(startDate)
        .endDate(startDate != null ? startDate.plusHours(2) : null)
        .location("Test Location")
        .maxParticipants(100)
        .currentParticipants(50)
        .status("open")
        .build();
  }

  public static DashboardDataDTO createDashboardDataDTO() {
    return DashboardDataDTO.builder()
        .stats(createDashboardStatsDTO())
        .recentActivities(List.of(createRecentActivityDTO()))
        .upcomingEvents(List.of(createUpcomingEventDTO()))
        .userPreferences(Map.of("theme", "royal_teal", "language", "fr"))
        .organizationId("org-123")
        .userId("user-456")
        .build();
  }

  // ===== HELPERS POUR DATES =====

  public static LocalDateTime now() {
    return LocalDateTime.now();
  }

  public static LocalDateTime hoursAgo(int hours) {
    return now().minusHours(hours);
  }

  public static LocalDateTime daysAgo(int days) {
    return now().minusDays(days);
  }

  public static LocalDateTime daysFromNow(int days) {
    return now().plusDays(days);
  }

  public static LocalDate date(int year, int month, int day) {
    return LocalDate.of(year, month, day);
  }

  // ===== NOTIFICATION DTO =====

  public static NotificationDTO createNotificationDTO() {
    NotificationDTO notification = new NotificationDTO();
    notification.setId(UUID.randomUUID());
    notification.setDateCreation(now());
    return notification;
  }

  // ===== ANALYTICS DATA DTO =====

  public static AnalyticsDataDTO createAnalyticsDataDTO() {
    return AnalyticsDataDTO.builder()
        .dateCalcul(now())
        .dateDebut(now().minusDays(30))
        .dateFin(now())
        .build();
  }

  // ===== SOLIDARITE DTOs =====

  public static dev.lions.unionflow.server.api.dto.solidarite.DemandeAideDTO createDemandeAideDTO() {
    dev.lions.unionflow.server.api.dto.solidarite.DemandeAideDTO dto =
        new dev.lions.unionflow.server.api.dto.solidarite.DemandeAideDTO();
    dto.setNumeroReference("DA-2025-000001");
    dto.setTypeAide(dev.lions.unionflow.server.api.enums.solidarite.TypeAide.AIDE_FINANCIERE_URGENTE);
    dto.setTitre("Aide pour frais médicaux");
    dto.setDescription("Demande d'aide pour couvrir les frais d'hospitalisation");
    dto.setMembreDemandeurId(UUID.randomUUID());
    dto.setNomDemandeur("Jean Dupont");
    dto.setAssociationId(UUID.randomUUID());
    dto.setStatut(dev.lions.unionflow.server.api.enums.solidarite.StatutAide.EN_ATTENTE);
    dto.setPriorite(dev.lions.unionflow.server.api.enums.solidarite.PrioriteAide.NORMALE);
    return dto;
  }

  public static dev.lions.unionflow.server.api.dto.solidarite.PropositionAideDTO
      createPropositionAideDTO() {
    return dev.lions.unionflow.server.api.dto.solidarite.PropositionAideDTO.builder()
        .id("prop-" + UUID.randomUUID().toString())
        .numeroReference("PA-2025-000001")
        .typeAide(dev.lions.unionflow.server.api.enums.solidarite.TypeAide.AIDE_FINANCIERE_URGENTE)
        .titre("Proposition d'aide financière")
        .description("Je propose une aide financière pour les membres en difficulté")
        .proposantId("membre-" + UUID.randomUUID().toString())
        .proposantNom("Marie Martin")
        .organisationId("org-" + UUID.randomUUID().toString())
        .build();
  }

  public static dev.lions.unionflow.server.api.dto.solidarite.EvaluationAideDTO
      createEvaluationAideDTO() {
    return dev.lions.unionflow.server.api.dto.solidarite.EvaluationAideDTO.builder()
        .id("eval-" + UUID.randomUUID().toString())
        .demandeAideId("demande-" + UUID.randomUUID().toString())
        .evaluateurId("eval-" + UUID.randomUUID().toString())
        .evaluateurNom("Évaluateur Test")
        .roleEvaluateur("beneficiaire")
        .noteGlobale(4.5)
        .commentairePrincipal("Très satisfait de l'aide reçue")
        .build();
  }

  public static dev.lions.unionflow.server.api.dto.solidarite.CommentaireAideDTO
      createCommentaireAideDTO() {
    return dev.lions.unionflow.server.api.dto.solidarite.CommentaireAideDTO.builder()
        .id("comment-" + UUID.randomUUID().toString())
        .auteurId("auteur-" + UUID.randomUUID().toString())
        .auteurNom("Auteur Test")
        .contenu("Ceci est un commentaire de test")
        .dateCreation(now())
        .build();
  }
}

