/**
 * Marketplace Service
 * API client for marketplace products, signal packs, advisory services, and subscriptions
 */

import { apiClient as api } from '../lib/apiClient';
import type {
  MarketplaceProductListItem,
  SignalPack,
  AdvisoryService,
  CourseProduct,
  ProductReview,
  UserSubscription,
  ConsultationBooking,
  MarketplaceFilters,
  PaginatedResponse,
  ApiResponse,
  ProductCategory,
  SellerProduct,
  SellerProductFilters,
  SellerStats,
  SellerSalesData,
  SellerPayoutInfo,
  CreateProductData,
  ProductDraft,
} from '../types/marketplace.types';

// ============================================================================
// Products (General)
// ============================================================================

export async function getProducts(
  filters?: MarketplaceFilters
): Promise<PaginatedResponse<MarketplaceProductListItem>> {
  const response = await api.get<ApiResponse<PaginatedResponse<MarketplaceProductListItem>>>(
    '/marketplace/products',
    { params: filters }
  );
  return response.data.data;
}

export async function getFeaturedProducts(limit = 6): Promise<MarketplaceProductListItem[]> {
  const response = await api.get<ApiResponse<MarketplaceProductListItem[]>>(
    '/marketplace/products/featured',
    { params: { limit } }
  );
  return response.data.data;
}

export async function getPopularProducts(limit = 6): Promise<MarketplaceProductListItem[]> {
  const response = await api.get<ApiResponse<MarketplaceProductListItem[]>>(
    '/marketplace/products/popular',
    { params: { limit } }
  );
  return response.data.data;
}

export async function getRelatedProducts(
  productId: string,
  limit = 4
): Promise<MarketplaceProductListItem[]> {
  const response = await api.get<ApiResponse<MarketplaceProductListItem[]>>(
    `/marketplace/products/${productId}/related`,
    { params: { limit } }
  );
  return response.data.data;
}

// ============================================================================
// Signal Packs
// ============================================================================

export async function getSignalPacks(
  filters?: MarketplaceFilters
): Promise<PaginatedResponse<MarketplaceProductListItem>> {
  const response = await api.get<ApiResponse<PaginatedResponse<MarketplaceProductListItem>>>(
    '/marketplace/signals',
    { params: filters }
  );
  return response.data.data;
}

export async function getSignalPackById(id: string): Promise<SignalPack> {
  const response = await api.get<ApiResponse<SignalPack>>(`/marketplace/signals/${id}`);
  return response.data.data;
}

export async function getSignalPackBySlug(slug: string): Promise<SignalPack> {
  const response = await api.get<ApiResponse<SignalPack>>(`/marketplace/signals/slug/${slug}`);
  return response.data.data;
}

export async function subscribeToSignalPack(
  packId: string,
  pricingId: string
): Promise<UserSubscription> {
  const response = await api.post<ApiResponse<UserSubscription>>(
    `/marketplace/signals/${packId}/subscribe`,
    { pricingId }
  );
  return response.data.data;
}

// ============================================================================
// Advisory Services
// ============================================================================

export async function getAdvisoryServices(
  filters?: MarketplaceFilters
): Promise<PaginatedResponse<MarketplaceProductListItem>> {
  const response = await api.get<ApiResponse<PaginatedResponse<MarketplaceProductListItem>>>(
    '/marketplace/advisory',
    { params: filters }
  );
  return response.data.data;
}

export async function getAdvisoryServiceById(id: string): Promise<AdvisoryService> {
  const response = await api.get<ApiResponse<AdvisoryService>>(`/marketplace/advisory/${id}`);
  return response.data.data;
}

export async function getAdvisoryServiceBySlug(slug: string): Promise<AdvisoryService> {
  const response = await api.get<ApiResponse<AdvisoryService>>(
    `/marketplace/advisory/slug/${slug}`
  );
  return response.data.data;
}

export async function getAdvisorAvailability(
  advisoryId: string,
  date: string
): Promise<{ slots: string[]; timezone: string }> {
  const response = await api.get<ApiResponse<{ slots: string[]; timezone: string }>>(
    `/marketplace/advisory/${advisoryId}/availability`,
    { params: { date } }
  );
  return response.data.data;
}

export async function bookConsultation(
  advisoryId: string,
  data: {
    serviceTypeId: string;
    scheduledAt: string;
    notes?: string;
  }
): Promise<ConsultationBooking> {
  const response = await api.post<ApiResponse<ConsultationBooking>>(
    `/marketplace/advisory/${advisoryId}/book`,
    data
  );
  return response.data.data;
}

// ============================================================================
// Course Products
// ============================================================================

export async function getCourseProducts(
  filters?: MarketplaceFilters
): Promise<PaginatedResponse<MarketplaceProductListItem>> {
  const response = await api.get<ApiResponse<PaginatedResponse<MarketplaceProductListItem>>>(
    '/marketplace/courses',
    { params: filters }
  );
  return response.data.data;
}

export async function getCourseProductById(id: string): Promise<CourseProduct> {
  const response = await api.get<ApiResponse<CourseProduct>>(`/marketplace/courses/${id}`);
  return response.data.data;
}

export async function getCourseProductBySlug(slug: string): Promise<CourseProduct> {
  const response = await api.get<ApiResponse<CourseProduct>>(`/marketplace/courses/slug/${slug}`);
  return response.data.data;
}

// ============================================================================
// Reviews
// ============================================================================

export async function getProductReviews(
  productId: string,
  productType: ProductCategory,
  params?: { page?: number; pageSize?: number; sortBy?: 'newest' | 'helpful' | 'rating' }
): Promise<PaginatedResponse<ProductReview>> {
  const response = await api.get<ApiResponse<PaginatedResponse<ProductReview>>>(
    `/marketplace/${productType}/${productId}/reviews`,
    { params }
  );
  return response.data.data;
}

export async function createReview(
  productId: string,
  productType: ProductCategory,
  data: { rating: number; title?: string; comment: string }
): Promise<ProductReview> {
  const response = await api.post<ApiResponse<ProductReview>>(
    `/marketplace/${productType}/${productId}/reviews`,
    data
  );
  return response.data.data;
}

export async function markReviewHelpful(reviewId: string): Promise<void> {
  await api.post(`/marketplace/reviews/${reviewId}/helpful`);
}

// ============================================================================
// Subscriptions
// ============================================================================

export async function getMySubscriptions(): Promise<UserSubscription[]> {
  const response = await api.get<ApiResponse<UserSubscription[]>>('/marketplace/subscriptions');
  return response.data.data;
}

export async function getSubscriptionById(id: string): Promise<UserSubscription> {
  const response = await api.get<ApiResponse<UserSubscription>>(`/marketplace/subscriptions/${id}`);
  return response.data.data;
}

export async function cancelSubscription(id: string): Promise<UserSubscription> {
  const response = await api.post<ApiResponse<UserSubscription>>(
    `/marketplace/subscriptions/${id}/cancel`
  );
  return response.data.data;
}

export async function renewSubscription(
  id: string,
  pricingId: string
): Promise<UserSubscription> {
  const response = await api.post<ApiResponse<UserSubscription>>(
    `/marketplace/subscriptions/${id}/renew`,
    { pricingId }
  );
  return response.data.data;
}

// ============================================================================
// Bookings
// ============================================================================

export async function getMyBookings(): Promise<ConsultationBooking[]> {
  const response = await api.get<ApiResponse<ConsultationBooking[]>>('/marketplace/bookings');
  return response.data.data;
}

export async function getBookingById(id: string): Promise<ConsultationBooking> {
  const response = await api.get<ApiResponse<ConsultationBooking>>(`/marketplace/bookings/${id}`);
  return response.data.data;
}

export async function cancelBooking(id: string): Promise<ConsultationBooking> {
  const response = await api.post<ApiResponse<ConsultationBooking>>(
    `/marketplace/bookings/${id}/cancel`
  );
  return response.data.data;
}

// ============================================================================
// Seller Products
// ============================================================================

export async function getSellerProducts(
  filters?: SellerProductFilters
): Promise<PaginatedResponse<SellerProduct>> {
  const response = await api.get<ApiResponse<PaginatedResponse<SellerProduct>>>(
    '/marketplace/seller/products',
    { params: filters }
  );
  return response.data.data;
}

export async function getSellerProductById(id: string): Promise<SellerProduct> {
  const response = await api.get<ApiResponse<SellerProduct>>(
    `/marketplace/seller/products/${id}`
  );
  return response.data.data;
}

export async function updateSellerProduct(
  id: string,
  data: Partial<SellerProduct>
): Promise<SellerProduct> {
  const response = await api.patch<ApiResponse<SellerProduct>>(
    `/marketplace/seller/products/${id}`,
    data
  );
  return response.data.data;
}

export async function toggleProductStatus(
  id: string,
  status: 'active' | 'inactive'
): Promise<SellerProduct> {
  const response = await api.patch<ApiResponse<SellerProduct>>(
    `/marketplace/seller/products/${id}/status`,
    { status }
  );
  return response.data.data;
}

export async function deleteSellerProduct(id: string): Promise<void> {
  await api.delete(`/marketplace/seller/products/${id}`);
}

// ============================================================================
// Seller Stats
// ============================================================================

export async function getSellerStats(): Promise<SellerStats> {
  const response = await api.get<ApiResponse<SellerStats>>(
    '/marketplace/seller/stats'
  );
  return response.data.data;
}

export async function getSellerSales(
  period: '7d' | '30d' | '90d' | '1y'
): Promise<SellerSalesData[]> {
  const response = await api.get<ApiResponse<SellerSalesData[]>>(
    '/marketplace/seller/sales',
    { params: { period } }
  );
  return response.data.data;
}

export async function getSellerPayouts(): Promise<SellerPayoutInfo> {
  const response = await api.get<ApiResponse<SellerPayoutInfo>>(
    '/marketplace/seller/payouts'
  );
  return response.data.data;
}

export async function getSellerEarnings(
  period: '7d' | '30d' | '90d' | '1y'
): Promise<{
  total: number;
  byProduct: { productId: string; productName: string; earnings: number }[];
  trend: number;
}> {
  const response = await api.get<ApiResponse<{
    total: number;
    byProduct: { productId: string; productName: string; earnings: number }[];
    trend: number;
  }>>('/marketplace/seller/earnings', { params: { period } });
  return response.data.data;
}

// ============================================================================
// Product Creation
// ============================================================================

export async function createProduct(data: CreateProductData): Promise<SellerProduct> {
  const response = await api.post<ApiResponse<SellerProduct>>(
    '/marketplace/seller/products',
    data
  );
  return response.data.data;
}

export async function saveProductDraft(
  data: Partial<CreateProductData>
): Promise<ProductDraft> {
  const response = await api.post<ApiResponse<ProductDraft>>(
    '/marketplace/seller/drafts',
    data
  );
  return response.data.data;
}

export async function updateProductDraft(
  id: string,
  data: Partial<CreateProductData>
): Promise<ProductDraft> {
  const response = await api.patch<ApiResponse<ProductDraft>>(
    `/marketplace/seller/drafts/${id}`,
    data
  );
  return response.data.data;
}

export async function publishDraft(draftId: string): Promise<SellerProduct> {
  const response = await api.post<ApiResponse<SellerProduct>>(
    `/marketplace/seller/drafts/${draftId}/publish`
  );
  return response.data.data;
}

export async function deleteProductDraft(id: string): Promise<void> {
  await api.delete(`/marketplace/seller/drafts/${id}`);
}

export async function uploadProductImage(file: File): Promise<{ url: string }> {
  const formData = new FormData();
  formData.append('image', file);
  const response = await api.post<ApiResponse<{ url: string }>>(
    '/marketplace/seller/upload',
    formData,
    { headers: { 'Content-Type': 'multipart/form-data' } }
  );
  return response.data.data;
}

export async function validateCoupon(
  code: string,
  productId?: string
): Promise<{
  isValid: boolean;
  discountPercent?: number;
  discountAmount?: number;
  message?: string;
}> {
  const response = await api.post<ApiResponse<{
    isValid: boolean;
    discountPercent?: number;
    discountAmount?: number;
    message?: string;
  }>>('/marketplace/coupons/validate', { code, productId });
  return response.data.data;
}

// ============================================================================
// Export service object
// ============================================================================

export const marketplaceService = {
  // Products
  getProducts,
  getFeaturedProducts,
  getPopularProducts,
  getRelatedProducts,

  // Signal Packs
  getSignalPacks,
  getSignalPackById,
  getSignalPackBySlug,
  subscribeToSignalPack,

  // Advisory Services
  getAdvisoryServices,
  getAdvisoryServiceById,
  getAdvisoryServiceBySlug,
  getAdvisorAvailability,
  bookConsultation,

  // Course Products
  getCourseProducts,
  getCourseProductById,
  getCourseProductBySlug,

  // Reviews
  getProductReviews,
  createReview,
  markReviewHelpful,

  // Subscriptions
  getMySubscriptions,
  getSubscriptionById,
  cancelSubscription,
  renewSubscription,

  // Bookings
  getMyBookings,
  getBookingById,
  cancelBooking,

  // Seller Products
  getSellerProducts,
  getSellerProductById,
  updateSellerProduct,
  toggleProductStatus,
  deleteSellerProduct,

  // Seller Stats
  getSellerStats,
  getSellerSales,
  getSellerPayouts,
  getSellerEarnings,

  // Product Creation
  createProduct,
  saveProductDraft,
  updateProductDraft,
  publishDraft,
  deleteProductDraft,
  uploadProductImage,
  validateCoupon,
};
