import { NextRequest, NextResponse } from "next/server";
import { Query } from "node-appwrite";

import { logAudit } from "@/lib/appwrite/audit";
import { DATABASE_ID, TABLES, type SubscriptionPayment } from "@/lib/appwrite/schema";
import { createAdminClient } from "@/lib/appwrite/server";
import {
  verifyShopierWebhookSignature,
  type ShopierWebhookOrder,
} from "@/lib/payments/shopier";

const PRO_VALIDITY_DAYS = 30;

export async function POST(req: NextRequest): Promise<NextResponse> {
  const signature = req.headers.get("Shopier-Signature") ?? "";
  const event = req.headers.get("Shopier-Event") ?? "";

  // Raw body'yi hem imza doğrulama hem de parse için kullan
  let rawBody: string;
  try {
    rawBody = await req.text();
  } catch {
    return NextResponse.json({ error: "invalid body" }, { status: 400 });
  }

  if (!verifyShopierWebhookSignature(signature, rawBody)) {
    console.error("[shopier/callback] signature mismatch", { event });
    return NextResponse.json({ error: "signature mismatch" }, { status: 403 });
  }

  // Yalnızca sipariş oluşturma eventini işle
  if (event !== "order.created") {
    return new NextResponse("OK", { status: 200 });
  }

  let order: ShopierWebhookOrder;
  try {
    order = JSON.parse(rawBody) as ShopierWebhookOrder;
  } catch {
    return NextResponse.json({ error: "invalid json" }, { status: 400 });
  }

  // Yalnızca ödenmiş siparişleri işle
  if (order.paymentStatus !== "paid") {
    return new NextResponse("OK", { status: 200 });
  }

  const buyerEmail = order.shippingInfo?.email ?? "";
  if (!buyerEmail) {
    console.error("[shopier/callback] no buyer email in order", order.id);
    return new NextResponse("OK", { status: 200 });
  }

  const { tablesDB } = createAdminClient();

  // Bekleyen Shopier ödemelerini al, email ile eşleştir
  const pendingResult = await tablesDB.listRows({
    databaseId: DATABASE_ID,
    tableId: TABLES.subscriptionPayments,
    queries: [
      Query.equal("provider", "shopier"),
      Query.equal("status", "pending"),
      Query.orderDesc("$createdAt"),
      Query.limit(20),
    ],
  });

  const pendingPayments = pendingResult.rows as unknown as SubscriptionPayment[];

  const payment = pendingPayments.find((p) => {
    try {
      const payload = JSON.parse(p.providerPayload ?? "{}") as { userEmail?: string };
      return payload.userEmail?.toLowerCase() === buyerEmail.toLowerCase();
    } catch {
      return false;
    }
  });

  if (!payment) {
    console.error("[shopier/callback] no matching pending payment for email", buyerEmail);
    // 200 döndür — Shopier'in retry yapmasını engelle, durumu logla
    return new NextResponse("OK", { status: 200 });
  }

  // Idempotency — zaten işlendiyse atla
  if (payment.status === "success" || payment.status === "failed") {
    return new NextResponse("OK", { status: 200 });
  }

  const now = new Date();
  const expires = new Date(now.getTime() + PRO_VALIDITY_DAYS * 24 * 60 * 60 * 1000);

  await tablesDB.updateRow(DATABASE_ID, TABLES.subscriptionPayments, payment.$id, {
    status: "success",
    processedAt: now.toISOString(),
    providerPayload: JSON.stringify({
      shopierOrderId: order.id,
      buyerEmail,
      total: order.totals?.total,
      currency: order.currency,
      dateCreated: order.dateCreated,
    }),
  });

  // Tenant planını aktive et
  const settingsResult = await tablesDB.listRows({
    databaseId: DATABASE_ID,
    tableId: TABLES.tenantSettings,
    queries: [Query.equal("tenantId", payment.tenantId), Query.limit(1)],
  });
  const settings = settingsResult.rows[0] as unknown as { $id: string } | undefined;

  if (settings) {
    await tablesDB.updateRow(DATABASE_ID, TABLES.tenantSettings, settings.$id, {
      plan: payment.plan,
      planStartedAt: now.toISOString(),
      planExpiresAt: expires.toISOString(),
      lastPaymentId: payment.$id,
    });
  }

  await logAudit({
    tenantId: payment.tenantId,
    userId: payment.createdBy,
    action: "update",
    entityType: "subscription_payment",
    entityId: payment.$id,
    changes: {
      provider: "shopier",
      status: "success",
      plan: payment.plan,
      shopierOrderId: order.id,
    },
  });

  return new NextResponse("OK", { status: 200 });
}
