import prisma from '../config/database';

export class SmartSalesService {
  /**
   * 1. FREQUENTLY BOUGHT TOGETHER (FBT)
   * Returns primary book + 2 complementary titles with combo discount
   */
  static async getFrequentlyBoughtTogether(bookId: string) {
    const primaryBook = await prisma.book.findUnique({
      where: { id: bookId },
      include: {
        bookAuthors: { include: { author: true } },
        bookCategories: { include: { category: true } },
        images: { where: { isPrimary: true }, take: 1 },
      },
    });

    if (!primaryBook) {
      throw new Error('Book not found');
    }

    const categoryIds = primaryBook.bookCategories.map((c) => c.categoryId);
    const authorIds = primaryBook.bookAuthors.map((a) => a.authorId);

    // Find complementary candidate books in related category or by related author
    const complementaryCandidates = await prisma.book.findMany({
      where: {
        id: { not: bookId },
        isActive: true,
        OR: [
          { bookCategories: { some: { categoryId: { in: categoryIds } } } },
          { bookAuthors: { some: { authorId: { in: authorIds } } } },
        ],
      },
      include: {
        bookAuthors: { include: { author: true } },
        bookCategories: { include: { category: true } },
        images: { where: { isPrimary: true }, take: 1 },
      },
      take: 2,
      orderBy: [{ ratingAverage: 'desc' }, { isBestseller: 'desc' }],
    });

    // If fewer than 2 found in same category, grab popular books
    if (complementaryCandidates.length < 2) {
      const more = await prisma.book.findMany({
        where: {
          id: { notIn: [bookId, ...complementaryCandidates.map((c) => c.id)] },
          isActive: true,
        },
        include: {
          bookAuthors: { include: { author: true } },
          bookCategories: { include: { category: true } },
          images: { where: { isPrimary: true }, take: 1 },
        },
        take: 2 - complementaryCandidates.length,
        orderBy: { isFeatured: 'desc' },
      });
      complementaryCandidates.push(...more);
    }

    const allBooks = [primaryBook, ...complementaryCandidates];

    // Compute pricing
    const individualTotal = allBooks.reduce(
      (sum, b) => sum + Number(b.discountPrice || b.price),
      0
    );
    const comboDiscountPercentage = 12; // 12% extra savings on 3-book bundle
    const comboDiscountAmount = Math.round(
      (individualTotal * comboDiscountPercentage) / 100
    );
    const comboTotalPrice = individualTotal - comboDiscountAmount;

    return {
      primaryBookId: bookId,
      booksCount: allBooks.length,
      individualTotal,
      comboTotalPrice,
      comboDiscountPercentage,
      comboSavings: comboDiscountAmount,
      badgeText: `Buy All ${allBooks.length} Together & Save ₹${comboDiscountAmount}`,
      items: allBooks.map((b, idx) => ({
        id: b.id,
        title: b.title,
        slug: b.slug,
        authorName: b.bookAuthors[0]?.author.name || 'Indian Author',
        categoryName: b.bookCategories[0]?.category.name || 'General',
        price: Number(b.price),
        discountPrice: b.discountPrice ? Number(b.discountPrice) : null,
        effectivePrice: Number(b.discountPrice || b.price),
        coverImage: b.coverImage || b.images[0]?.url || null,
        binding: b.binding || b.format || 'Hardcover',
        isPrimary: idx === 0,
      })),
    };
  }

  /**
   * 2. BUNDLE & COMBO OFFERS
   */
  static async getBundlesAndCombos(isCombo?: boolean) {
    const where: any = { isActive: true };
    if (typeof isCombo === 'boolean') {
      where.isCombo = isCombo;
    }

    const bundles = await prisma.productBundle.findMany({
      where,
      include: {
        items: {
          include: {
            book: {
              include: {
                bookAuthors: { include: { author: true } },
                images: { where: { isPrimary: true }, take: 1 },
              },
            },
          },
          orderBy: { sortOrder: 'asc' },
        },
      },
      orderBy: { createdAt: 'desc' },
    });

    // Fallback seed curated bundles if table empty
    if (bundles.length === 0) {
      return this.getCuratedFallbackBundles();
    }

    return bundles.map((b) => ({
      id: b.id,
      title: b.title,
      slug: b.slug,
      description: b.description,
      coverImage: b.coverImage,
      originalPrice: Number(b.originalPrice),
      bundlePrice: Number(b.bundlePrice),
      discountPercentage: b.discountPercentage,
      savings: Number(b.originalPrice) - Number(b.bundlePrice),
      badgeText: b.badgeText,
      isCombo: b.isCombo,
      itemsCount: b.items.length,
      inStock: b.items.every((i) => i.book.stock >= i.quantity),
      items: b.items.map((i) => ({
        bookId: i.book.id,
        title: i.book.title,
        slug: i.book.slug,
        author: i.book.bookAuthors[0]?.author.name || 'Indian Author',
        price: Number(i.book.price),
        coverImage: i.book.coverImage || i.book.images[0]?.url || null,
        quantity: i.quantity,
      })),
    }));
  }

  /**
   * 3. DYNAMIC COMBO TIER DISCOUNT ENGINE
   * (Buy 2 Get 10%, Buy 3 Get 15%, Buy 5+ Get 25%)
   */
  static calculateTierDiscount(itemQuantity: number, subtotal: number) {
    let discountPercentage = 0;
    let badgeText = '';
    let nextTier: { neededQuantity: number; discountPercentage: number } | null = null;

    if (itemQuantity >= 5) {
      discountPercentage = 25;
      badgeText = '25% Volume Tier Discount Applied (5+ Books)';
    } else if (itemQuantity >= 3) {
      discountPercentage = 15;
      badgeText = '15% Trio Discount Applied (3+ Books)';
      nextTier = { neededQuantity: 5 - itemQuantity, discountPercentage: 25 };
    } else if (itemQuantity >= 2) {
      discountPercentage = 10;
      badgeText = '10% Pair Discount Applied (2 Books)';
      nextTier = { neededQuantity: 3 - itemQuantity, discountPercentage: 15 };
    } else {
      nextTier = { neededQuantity: 2 - itemQuantity, discountPercentage: 10 };
    }

    const discountAmount = Math.round((subtotal * discountPercentage) / 100);
    const finalTotal = subtotal - discountAmount;

    return {
      itemQuantity,
      subtotal,
      discountPercentage,
      discountAmount,
      finalTotal,
      badgeText: badgeText || undefined,
      nextTierMessage: nextTier
        ? `Add ${nextTier.neededQuantity} more book(s) to unlock ${nextTier.discountPercentage}% OFF entire order!`
        : 'Maximum 25% Volume Tier Discount unlocked!',
      tiers: [
        { minQuantity: 2, discountPercentage: 10, label: 'Buy 2 Get 10% OFF' },
        { minQuantity: 3, discountPercentage: 15, label: 'Buy 3 Get 15% OFF' },
        { minQuantity: 5, discountPercentage: 25, label: 'Buy 5+ Get 25% OFF' },
      ],
    };
  }

  /**
   * 4. FLASH DEALS & LIGHTNING SALES
   */
  static async getFlashDeals() {
    const now = new Date();
    const deals = await prisma.flashDeal.findMany({
      where: {
        isActive: true,
        startsAt: { lte: now },
        endsAt: { gte: now },
      },
      include: {
        book: {
          include: {
            bookAuthors: { include: { author: true } },
            images: { where: { isPrimary: true }, take: 1 },
          },
        },
      },
      orderBy: { discountPercentage: 'desc' },
    });

    if (deals.length === 0) {
      return this.getCuratedFallbackFlashDeals();
    }

    return deals.map((deal) => {
      const remainingMs = Math.max(0, deal.endsAt.getTime() - now.getTime());
      const stockRemaining = Math.max(0, deal.stockLimit - deal.soldCount);
      const claimedPercentage = Math.min(100, Math.round((deal.soldCount / deal.stockLimit) * 100));

      return {
        id: deal.id,
        bookId: deal.bookId,
        title: deal.book.title,
        slug: deal.book.slug,
        authorName: deal.book.bookAuthors[0]?.author.name || 'Indian Author',
        coverImage: deal.book.coverImage || deal.book.images[0]?.url || null,
        dealPrice: Number(deal.dealPrice),
        originalPrice: Number(deal.originalPrice),
        discountPercentage: deal.discountPercentage,
        badgeText: deal.badgeText || 'Flash Deal',
        startsAt: deal.startsAt,
        endsAt: deal.endsAt,
        remainingMilliseconds: remainingMs,
        stockLimit: deal.stockLimit,
        soldCount: deal.soldCount,
        stockRemaining,
        claimedPercentage,
      };
    });
  }

  /**
   * 5. UPSELLING RECOMMENDATIONS
   * Suggests Deluxe Hardcover / Leatherbound / Complete Commentary upgrades
   */
  static async getUpsellRecommendations(bookId: string) {
    const book = await prisma.book.findUnique({
      where: { id: bookId },
      include: {
        variants: { where: { isActive: true } },
        bookAuthors: { include: { author: true } },
        bookCategories: { include: { category: true } },
      },
    });

    if (!book) return [];

    const upsells: any[] = [];

    // Check if Hardcover variant exists when current is Paperback
    const hardcoverVariant = book.variants.find((v) => v.format === 'HARDCOVER');
    if (hardcoverVariant && book.binding !== 'Hardcover') {
      const priceDelta = Number(hardcoverVariant.price) - Number(book.discountPrice || book.price);
      upsells.push({
        type: 'HARDCOVER_UPGRADE',
        badge: 'Recommended Collector Upgrade',
        title: `${book.title} (Hardcover Deluxe Edition)`,
        price: Number(hardcoverVariant.price),
        priceDifference: `+₹${Math.max(0, priceDelta)}`,
        reason: 'Archival acid-free paper, gold foil embossed spine, and permanent thread-sewn binding.',
        variantId: hardcoverVariant.id,
        format: 'HARDCOVER',
      });
    }

    // Check for multi-volume commentary sets in same category
    const categoryId = book.bookCategories[0]?.categoryId;
    if (categoryId) {
      const criticalEdition = await prisma.book.findFirst({
        where: {
          id: { not: bookId },
          isActive: true,
          bookCategories: { some: { categoryId } },
          price: { gt: book.price },
        },
        include: {
          bookAuthors: { include: { author: true } },
          images: { where: { isPrimary: true }, take: 1 },
        },
        orderBy: { price: 'desc' },
      });

      if (criticalEdition) {
        upsells.push({
          type: 'CRITICAL_COMMENTARY_SET',
          badge: 'Scholarly Multi-Volume Edition',
          title: criticalEdition.title,
          slug: criticalEdition.slug,
          price: Number(criticalEdition.price),
          coverImage: criticalEdition.coverImage || criticalEdition.images[0]?.url,
          author: criticalEdition.bookAuthors[0]?.author.name,
          reason: 'Complete unabridged Sanskrit-English exegesis with exhaustive word-index and philological notes.',
          format: criticalEdition.binding || 'Hardcover Set',
        });
      }
    }

    return upsells;
  }

  /**
   * 6. CROSS-SELLING FOR CART & CHECKOUT
   */
  static async getCrossSellRecommendations(cartBookIds: string[], limit = 4) {
    const crossSells = await prisma.book.findMany({
      where: {
        id: { notIn: cartBookIds.length > 0 ? cartBookIds : ['none'] },
        isActive: true,
        isFeatured: true,
      },
      include: {
        bookAuthors: { include: { author: true } },
        bookCategories: { include: { category: true } },
        images: { where: { isPrimary: true }, take: 1 },
      },
      take: limit,
      orderBy: { ratingAverage: 'desc' },
    });

    return crossSells.map((b) => ({
      id: b.id,
      title: b.title,
      slug: b.slug,
      price: Number(b.price),
      discountPrice: b.discountPrice ? Number(b.discountPrice) : null,
      coverImage: b.coverImage || b.images[0]?.url || null,
      authorName: b.bookAuthors[0]?.author.name || 'Indian Author',
      categoryName: b.bookCategories[0]?.category.name || 'General',
      format: b.format || b.binding || 'Book',
    }));
  }

  /**
   * 7. FESTIVAL CAMPAIGNS & PROMOTIONAL EVENTS
   */
  static async getActiveCampaigns() {
    const now = new Date();
    const campaigns = await prisma.campaign.findMany({
      where: {
        isActive: true,
        startsAt: { lte: now },
        endsAt: { gte: now },
      },
      orderBy: { startsAt: 'desc' },
    });

    if (campaigns.length === 0) {
      return [
        {
          id: 'camp-default',
          title: 'Vedic Heritage Literary Festival 2026',
          slug: 'vedic-heritage-festival-2026',
          description: 'Special 15% discount across all sacred scriptures, Upanishad commentaries, and Sanskrit manuscripts.',
          bannerUrl: 'https://images.unsplash.com/photo-1544716278-ca5e3f4abd8c?w=1200&auto=format&fit=crop&q=80',
          themeColor: '#701a08',
          couponCode: 'VEDIC15',
          discountPercent: 15,
          targetCategory: 'Vedas & Upanishads',
          startsAt: now,
          endsAt: new Date(now.getTime() + 14 * 24 * 60 * 60 * 1000),
          isActive: true,
        },
      ];
    }

    return campaigns;
  }

  // --- Fallback Curations ---
  private static getCuratedFallbackBundles() {
    return [
      {
        id: 'bundle-prasthanatrayi',
        title: 'Prasthanatrayi Deluxe Triple Crown Set (Gita, Upanishads & Brahma Sutras)',
        slug: 'prasthanatrayi-deluxe-triple-crown-set',
        description: 'The foundational triad of Indian philosophy in unabridged Sanskrit text and exhaustive English critical commentary.',
        coverImage: '/assets/books/placeholder.jpg',
        originalPrice: 3499,
        bundlePrice: 2699,
        discountPercentage: 23,
        savings: 800,
        badgeText: 'Ultimate Vedic Triad • Save ₹800',
        isCombo: false,
        itemsCount: 3,
        inStock: true,
        items: [
          { bookId: 'b1', title: 'Srimad Bhagavad Gita Critical Edition', author: 'Vyasa', price: 999, quantity: 1 },
          { bookId: 'b2', title: 'The Principal Upanishads (Complete 10 Major Exegeses)', author: 'Dr. S. Radhakrishnan', price: 1499, quantity: 1 },
          { bookId: 'b3', title: 'Brahma Sutras with Sankara Bhashya', author: 'Swami Gambhirananda', price: 1001, quantity: 1 },
        ],
      },
      {
        id: 'bundle-epics',
        title: 'Great Indian Epics Collector Set (Mahabharata + Ramayana)',
        slug: 'great-indian-epics-collector-set',
        description: 'Complete unexpurgated translations of Valmiki Ramayana and Vyasa Mahabharata with comprehensive character genealogical charts.',
        coverImage: '/assets/books/placeholder.jpg',
        originalPrice: 2899,
        bundlePrice: 2199,
        discountPercentage: 24,
        savings: 700,
        badgeText: 'Epics Box Set • Save 24%',
        isCombo: true,
        itemsCount: 2,
        inStock: true,
        items: [
          { bookId: 'b4', title: 'The Mahabharata (Unabridged 10 Volumes in 2 Parts)', author: 'Dr. Bibek Debroy', price: 1699, quantity: 1 },
          { bookId: 'b5', title: 'The Valmiki Ramayana Critical Translation', author: 'Dr. Bibek Debroy', price: 1200, quantity: 1 },
        ],
      },
    ];
  }

  private static getCuratedFallbackFlashDeals() {
    const now = new Date();
    const endsAt = new Date(now.getTime() + 18 * 60 * 60 * 1000 + 45 * 60 * 1000); // 18h 45m left
    return [
      {
        id: 'flash-1',
        bookId: 'deal-gita-deluxe',
        title: 'Srimad Bhagavad Gita (Deluxe Sanskrit-English Hardbound)',
        slug: 'srimad-bhagavad-gita-deluxe',
        authorName: 'Swami Swarupananda',
        coverImage: '/assets/books/placeholder.jpg',
        dealPrice: 599,
        originalPrice: 1199,
        discountPercentage: 50,
        badgeText: '50% FLASH SALE',
        startsAt: now,
        endsAt,
        remainingMilliseconds: endsAt.getTime() - now.getTime(),
        stockLimit: 100,
        soldCount: 78,
        stockRemaining: 22,
        claimedPercentage: 78,
      },
      {
        id: 'flash-2',
        bookId: 'deal-ayurveda',
        title: 'Charaka Samhita (Authentic 4-Volume Ayurvedic Corpus)',
        slug: 'charaka-samhita-4-volume-set',
        authorName: 'Dr. R.K. Sharma',
        coverImage: '/assets/books/placeholder.jpg',
        dealPrice: 1899,
        originalPrice: 3200,
        discountPercentage: 40,
        badgeText: '40% LIMITED DEAL',
        startsAt: now,
        endsAt,
        remainingMilliseconds: endsAt.getTime() - now.getTime(),
        stockLimit: 50,
        soldCount: 41,
        stockRemaining: 9,
        claimedPercentage: 82,
      },
    ];
  }
}
