/**
 * useCourseReviews Hooks
 * TanStack Query hooks for course reviews functionality
 * OQI-002: Modulo Educativo
 */

import { useQuery, useMutation, useQueryClient, useInfiniteQuery } from '@tanstack/react-query';
import { apiClient as api } from '../../../lib/apiClient';
import type { ApiResponse } from '../../../types/education.types';

// ============================================================================
// Query Keys
// ============================================================================

export const reviewKeys = {
  all: ['course-reviews'] as const,
  list: (courseId: string) => [...reviewKeys.all, courseId] as const,
  summary: (courseId: string) => [...reviewKeys.all, courseId, 'summary'] as const,
  myReview: (courseId: string) => [...reviewKeys.all, courseId, 'my-review'] as const,
  infinite: (courseId: string) => [...reviewKeys.all, courseId, 'infinite'] as const,
};

// ============================================================================
// Types
// ============================================================================

export interface Review {
  id: string;
  userId: string;
  userName: string;
  userAvatar?: string;
  rating: number;
  title?: string;
  comment: string;
  helpful: number;
  createdAt: string;
  verified?: boolean;
}

export interface RatingSummary {
  average: number;
  total: number;
  distribution: {
    5: number;
    4: number;
    3: number;
    2: number;
    1: number;
  };
}

export interface ReviewsResponse {
  reviews: Review[];
  summary: RatingSummary;
  hasMore: boolean;
  total: number;
}

export interface CreateReviewData {
  rating: number;
  title?: string;
  comment: string;
}

// ============================================================================
// API Functions
// ============================================================================

async function fetchReviews(
  courseId: string,
  page: number = 1,
  pageSize: number = 10,
  rating?: number
): Promise<ReviewsResponse> {
  const params = new URLSearchParams({
    page: String(page),
    pageSize: String(pageSize),
  });
  if (rating) {
    params.append('rating', String(rating));
  }

  const response = await api.get<ApiResponse<ReviewsResponse>>(
    `/education/courses/${courseId}/reviews?${params.toString()}`
  );
  return response.data.data;
}

async function fetchRatingSummary(courseId: string): Promise<RatingSummary> {
  const response = await api.get<ApiResponse<RatingSummary>>(
    `/education/courses/${courseId}/reviews/summary`
  );
  return response.data.data;
}

async function fetchMyReview(courseId: string): Promise<Review | null> {
  try {
    const response = await api.get<ApiResponse<Review>>(
      `/education/courses/${courseId}/reviews/my`
    );
    return response.data.data;
  } catch {
    return null;
  }
}

async function createReview(courseId: string, data: CreateReviewData): Promise<Review> {
  const response = await api.post<ApiResponse<Review>>(
    `/education/courses/${courseId}/reviews`,
    data
  );
  return response.data.data;
}

async function updateReview(
  courseId: string,
  reviewId: string,
  data: Partial<CreateReviewData>
): Promise<Review> {
  const response = await api.patch<ApiResponse<Review>>(
    `/education/courses/${courseId}/reviews/${reviewId}`,
    data
  );
  return response.data.data;
}

async function deleteReview(courseId: string, reviewId: string): Promise<void> {
  await api.delete(`/education/courses/${courseId}/reviews/${reviewId}`);
}

async function markReviewHelpful(courseId: string, reviewId: string): Promise<{ helpful: number }> {
  const response = await api.post<ApiResponse<{ helpful: number }>>(
    `/education/courses/${courseId}/reviews/${reviewId}/helpful`
  );
  return response.data.data;
}

async function reportReview(
  courseId: string,
  reviewId: string,
  reason: string
): Promise<void> {
  await api.post(`/education/courses/${courseId}/reviews/${reviewId}/report`, { reason });
}

// ============================================================================
// Hooks
// ============================================================================

/**
 * Hook to fetch course reviews with pagination
 */
export function useCourseReviews(courseId: string, rating?: number) {
  return useQuery<ReviewsResponse, Error>({
    queryKey: [...reviewKeys.list(courseId), { rating }],
    queryFn: () => fetchReviews(courseId, 1, 10, rating),
    enabled: !!courseId,
    staleTime: 60 * 1000, // 1 minute
  });
}

/**
 * Hook to fetch reviews with infinite scroll
 */
export function useInfiniteReviews(courseId: string, pageSize: number = 10, rating?: number) {
  return useInfiniteQuery<ReviewsResponse, Error>({
    queryKey: [...reviewKeys.infinite(courseId), { rating }],
    queryFn: ({ pageParam = 1 }) => fetchReviews(courseId, pageParam as number, pageSize, rating),
    getNextPageParam: (lastPage, allPages) => {
      if (lastPage.hasMore) {
        return allPages.length + 1;
      }
      return undefined;
    },
    initialPageParam: 1,
    enabled: !!courseId,
    staleTime: 60 * 1000,
  });
}

/**
 * Hook to fetch rating summary only
 */
export function useRatingSummary(courseId: string) {
  return useQuery<RatingSummary, Error>({
    queryKey: reviewKeys.summary(courseId),
    queryFn: () => fetchRatingSummary(courseId),
    enabled: !!courseId,
    staleTime: 5 * 60 * 1000, // 5 minutes
  });
}

/**
 * Hook to fetch user's review for a course
 */
export function useMyReview(courseId: string) {
  return useQuery<Review | null, Error>({
    queryKey: reviewKeys.myReview(courseId),
    queryFn: () => fetchMyReview(courseId),
    enabled: !!courseId,
    staleTime: 5 * 60 * 1000,
  });
}

/**
 * Hook to create a new review
 */
export function useSubmitReview() {
  const queryClient = useQueryClient();

  return useMutation<Review, Error, { courseId: string; data: CreateReviewData }>({
    mutationFn: ({ courseId, data }) => createReview(courseId, data),
    onSuccess: (review, { courseId }) => {
      // Update my review cache
      queryClient.setQueryData(reviewKeys.myReview(courseId), review);

      // Invalidate reviews list and summary
      queryClient.invalidateQueries({ queryKey: reviewKeys.list(courseId) });
      queryClient.invalidateQueries({ queryKey: reviewKeys.summary(courseId) });
      queryClient.invalidateQueries({ queryKey: reviewKeys.infinite(courseId) });
    },
  });
}

/**
 * Hook to update an existing review
 */
export function useUpdateReview() {
  const queryClient = useQueryClient();

  return useMutation<
    Review,
    Error,
    { courseId: string; reviewId: string; data: Partial<CreateReviewData> }
  >({
    mutationFn: ({ courseId, reviewId, data }) => updateReview(courseId, reviewId, data),
    onSuccess: (review, { courseId }) => {
      queryClient.setQueryData(reviewKeys.myReview(courseId), review);
      queryClient.invalidateQueries({ queryKey: reviewKeys.list(courseId) });
      queryClient.invalidateQueries({ queryKey: reviewKeys.summary(courseId) });
      queryClient.invalidateQueries({ queryKey: reviewKeys.infinite(courseId) });
    },
  });
}

/**
 * Hook to delete a review
 */
export function useDeleteReview() {
  const queryClient = useQueryClient();

  return useMutation<void, Error, { courseId: string; reviewId: string }>({
    mutationFn: ({ courseId, reviewId }) => deleteReview(courseId, reviewId),
    onSuccess: (_, { courseId }) => {
      queryClient.setQueryData(reviewKeys.myReview(courseId), null);
      queryClient.invalidateQueries({ queryKey: reviewKeys.list(courseId) });
      queryClient.invalidateQueries({ queryKey: reviewKeys.summary(courseId) });
      queryClient.invalidateQueries({ queryKey: reviewKeys.infinite(courseId) });
    },
  });
}

/**
 * Hook to mark a review as helpful
 */
export function useMarkHelpful() {
  const queryClient = useQueryClient();

  return useMutation<{ helpful: number }, Error, { courseId: string; reviewId: string }>({
    mutationFn: ({ courseId, reviewId }) => markReviewHelpful(courseId, reviewId),
    onSuccess: (_, { courseId }) => {
      // Invalidate to refresh helpful counts
      queryClient.invalidateQueries({ queryKey: reviewKeys.list(courseId) });
      queryClient.invalidateQueries({ queryKey: reviewKeys.infinite(courseId) });
    },
  });
}

/**
 * Hook to report a review
 */
export function useReportReview() {
  return useMutation<void, Error, { courseId: string; reviewId: string; reason: string }>({
    mutationFn: ({ courseId, reviewId, reason }) => reportReview(courseId, reviewId, reason),
  });
}

export default useCourseReviews;
