package dev.lions.unionflow.server.api;

import dev.lions.unionflow.server.api.dto.analytics.AnalyticsDataResponse;
import dev.lions.unionflow.server.api.dto.dashboard.DashboardDataResponse;
import dev.lions.unionflow.server.api.dto.dashboard.DashboardStatsResponse;
import dev.lions.unionflow.server.api.dto.dashboard.RecentActivityResponse;
import dev.lions.unionflow.server.api.dto.dashboard.UpcomingEventResponse;
import dev.lions.unionflow.server.api.dto.membre.request.CreateMembreRequest;
import dev.lions.unionflow.server.api.dto.membre.response.MembreSummaryResponse;
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.response.NotificationResponse;
import dev.lions.unionflow.server.api.dto.solidarite.response.CommentaireAideResponse;
import dev.lions.unionflow.server.api.dto.solidarite.response.DemandeAideResponse;
import dev.lions.unionflow.server.api.dto.solidarite.response.EvaluationAideResponse;
import dev.lions.unionflow.server.api.dto.solidarite.response.PropositionAideResponse;
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 DTOs =====

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

  public static MembreSummaryResponse createMembreSummaryResponse(String numero, String nom, String prenom,
      String email) {
    return new MembreSummaryResponse(
        UUID.randomUUID(), numero, prenom, nom, email, "0102030405", "Profession", "ACTIF", "Actif", "success", true,
        List.of("MEMBRE"), null, null);
  }

  public static CreateMembreRequest createCreateMembreRequest(int age) {
    return new CreateMembreRequest(
        "Jean", "Dupont", "jean@example.com", "0102030405", "+22501020304",
        LocalDate.now().minusYears(age), "Profession", "photo.jpg", "CELIBATAIRE", "Ivoirienne", "CNI", "123456789");
  }

  // ===== 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<MembreSummaryResponse> 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 DashboardStatsResponse createDashboardStatsResponse() {
    return DashboardStatsResponse.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 RecentActivityResponse createRecentActivityResponse() {
    return createRecentActivityResponse("member", LocalDateTime.now().minusHours(1));
  }

  public static RecentActivityResponse createRecentActivityResponse(String type, LocalDateTime timestamp) {
    return RecentActivityResponse.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 UpcomingEventResponse createUpcomingEventResponse() {
    return createUpcomingEventResponse(LocalDateTime.now().plusDays(1));
  }

  public static UpcomingEventResponse createUpcomingEventResponse(LocalDateTime startDate) {
    return UpcomingEventResponse.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 DashboardDataResponse createDashboardDataResponse() {
    return DashboardDataResponse.builder()
        .stats(createDashboardStatsResponse())
        .recentActivities(List.of(createRecentActivityResponse()))
        .upcomingEvents(List.of(createUpcomingEventResponse()))
        .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 NotificationResponse createNotificationResponse() {
    NotificationResponse notification = new NotificationResponse();
    notification.setId(UUID.randomUUID());
    notification.setDateCreation(now());
    return notification;
  }

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

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

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

  public static DemandeAideResponse createDemandeAideResponse() {
    DemandeAideResponse dto = new DemandeAideResponse();
    dto.setId(UUID.randomUUID());
    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 PropositionAideResponse createPropositionAideResponse() {
    PropositionAideResponse dto = new PropositionAideResponse();
    dto.setId(UUID.randomUUID());
    dto.setNumeroReference("PA-2025-000001");
    dto.setTypeAide(dev.lions.unionflow.server.api.enums.solidarite.TypeAide.AIDE_FINANCIERE_URGENTE);
    dto.setTitre("Proposition d'aide financière");
    dto.setDescription("Je propose une aide financière pour les membres en difficulté");
    dto.setProposantId(UUID.randomUUID().toString());
    dto.setProposantNom("Marie Martin");
    dto.setOrganisationId(UUID.randomUUID().toString());
    return dto;
  }

  public static EvaluationAideResponse createEvaluationAideResponse() {
    EvaluationAideResponse dto = new EvaluationAideResponse();
    dto.setId(UUID.randomUUID());
    dto.setDemandeAideId(UUID.randomUUID());
    dto.setEvaluateurId(UUID.randomUUID());
    dto.setEvaluateurNom("Évaluateur Test");
    dto.setRoleEvaluateur("beneficiaire");
    dto.setNoteGlobale(4.5);
    dto.setCommentairePrincipal("Très satisfait de l'aide reçue");
    dto.setStatut(dev.lions.unionflow.server.api.enums.solidarite.StatutEvaluation.ACTIVE);
    return dto;
  }

  public static CommentaireAideResponse createCommentaireAideResponse() {
    CommentaireAideResponse dto = new CommentaireAideResponse();
    dto.setId(UUID.randomUUID());
    dto.setAuteurId(UUID.randomUUID());
    dto.setAuteurNom("Auteur Test");
    dto.setContenu("Ceci est un commentaire de test");
    dto.setDateCreation(now());
    return dto;
  }
}
