import { Controller, Get, Post } from '@nestjs/common';
import { PrismaService } from '../common/prisma.service';
import { ShopifyService } from './shopify.service';
import { getMerchant } from '../common/core';
import { OrderAttributionService } from '../orders/order-attribution.service';

@Controller('shopify')
export class ShopifyController {
  constructor(
    private prisma: PrismaService,
    private shopify: ShopifyService,
    private attribution: OrderAttributionService,
  ) {}

  /** Connection status — verifies THIS store's token by calling the store. */
  @Get('status')
  async status() {
    const m = await getMerchant(this.prisma);
    if (!m.shopifyAccessToken) return { configured: false, shop: m.shop };
    try {
      const info = await this.shopify.shopInfo(m.shop, m.shopifyAccessToken);
      return { configured: true, connected: true, shop: m.shop, shopName: info.name };
    } catch (e) {
      return { configured: true, connected: false, shop: m.shop, error: (e as Error).message };
    }
  }

  /** Create real Shopify discount codes for every active affiliate's coupon (PRD 4.6). */
  @Post('push-coupons')
  async pushCoupons() {
    const m = await getMerchant(this.prisma);
    if (!m.shopifyAccessToken) {
      return { ok: false, created: 0, failed: 0, message: 'Store not connected yet — open the app once from your Shopify admin and try again.' };
    }
    const affs = await this.prisma.affiliate.findMany({
      where: { merchantId: m.id, status: 'ACTIVE', couponCode: { not: null } },
    });
    let created = 0;
    const errors: string[] = [];
    for (const a of affs) {
      try {
        const type = a.couponDiscountType === 'FIXED' ? 'FIXED' : 'PERCENT';
        const value = Number(a.couponDiscountValue ?? 10);
        await this.shopify.createDiscountCode(a.couponCode!, type, value, {
          usageLimit: a.couponMaxRedemptions,
          oncePerCustomer: a.couponUsageLimitPerCustomer != null && a.couponUsageLimitPerCustomer <= 1,
          minOrderValue: a.couponMinOrderValue != null ? Number(a.couponMinOrderValue) : null,
          shop: m.shop,
          token: m.shopifyAccessToken,
        });
        created++;
      } catch (e) {
        errors.push(`${a.couponCode}: ${(e as Error).message}`);
      }
    }
    return { ok: true, created, failed: errors.length, errors: errors.slice(0, 5) };
  }

  /**
   * Manual backstop: pull recent orders and run the SAME attribution the
   * orders/create webhook uses. Real-time attribution happens on the webhook;
   * this catches anything missed (webhook downtime, pre-install orders).
   */
  @Post('sync-orders')
  async syncOrders() {
    const m = await getMerchant(this.prisma);
    if (!m.shopifyAccessToken) {
      return { ok: false, message: 'Store not connected yet — open the app once from your Shopify admin and try again.' };
    }
    let orders;
    try {
      orders = await this.shopify.listOrders(100, m.shop, m.shopifyAccessToken);
    } catch (e) {
      return { ok: false, message: (e as Error).message };
    }
    let attributed = 0;
    let skipped = 0;
    for (const o of orders) {
      const r = await this.attribution.attribute(m, {
        id: String(o.id),
        email: o.email,
        subtotal: Number(o.subtotal_price) || 0,
        total: Number(o.total_price) || 0,
        discountCodes: (o.discount_codes ?? []).map((d) => d.code),
        lineItems: o.line_items ?? [],
        tags: o.tags ?? [],
        clickId: null, // sync path has no click_id — real-time webhook carries it
      });
      if (r.status === 'attributed') attributed++;
      else skipped++;
    }
    return { ok: true, fetched: orders.length, attributed, skipped };
  }
}
