import type { SubscriptionPlan, SubscriptionStatus } from "@app/shared-types";
import { resolvePlanFromProductId } from "./entitlements.js";

/**
 * Butiksverifiering (spec §47, Del 13). Backend verifierar ALLTID köpet mot
 * butiken – klientens kvitto är bara ett påstående (spec §61.14).
 *
 * PRODUKTIONSINTEGRATION (implementeras i fas 7, se docs/utvecklingsfaser.md):
 * - Apple: App Store Server API v2 – verifiera JWS-signaturen i signedTransaction
 *   mot Apples publika nycklar, kontrollera bundleId + environment.
 * - Google: Play Developer API purchases.subscriptionsv2.get med service account.
 *
 * Dev/CI: APP_STORE_MODE=sandbox accepterar särskilt formaterade
 * sandbox-payloads så att hela flödet kan testas end-to-end utan butikskonton.
 */

export interface VerifiedPurchase {
  provider: "apple" | "google";
  productId: string;
  plan: SubscriptionPlan;
  originalTransactionId: string;
  status: SubscriptionStatus;
  purchasedAt: Date;
  expiresAt: Date;
}

export type StoreVerificationResult =
  { ok: true; purchase: VerifiedPurchase } | { ok: false; error: string };

export interface StoreVerifierConfig {
  mode: "production" | "sandbox";
  appleBundleId?: string | undefined;
  googlePackageName?: string | undefined;
}

export class StoreVerifier {
  constructor(private readonly cfg: StoreVerifierConfig) {}

  async verifyApple(signedTransaction: string): Promise<StoreVerificationResult> {
    if (this.cfg.mode === "sandbox") {
      return parseSandboxPayload("apple", signedTransaction);
    }
    // TODO(fas 7): App Store Server API v2 JWS-verifiering.
    return {
      ok: false,
      error:
        "Apple-verifiering i produktionsläge är inte konfigurerad ännu. " +
        "Kräver APPLE_ISSUER_ID/KEY_ID/PRIVATE_KEY (se docs/subscriptions.md).",
    };
  }

  async verifyGoogle(
    packageName: string,
    productId: string,
    purchaseToken: string,
  ): Promise<StoreVerificationResult> {
    if (this.cfg.mode === "sandbox") {
      return parseSandboxPayload("google", purchaseToken, productId);
    }
    if (this.cfg.googlePackageName && packageName !== this.cfg.googlePackageName) {
      return { ok: false, error: `Fel paketnamn: ${packageName}` };
    }
    // TODO(fas 7): Play Developer API purchases.subscriptionsv2.
    return {
      ok: false,
      error:
        "Google-verifiering i produktionsläge är inte konfigurerad ännu. " +
        "Kräver GOOGLE_SERVICE_ACCOUNT_JSON (se docs/subscriptions.md).",
    };
  }
}

/**
 * Sandbox-payload: JSON i klartext:
 * {"productId":"<iosBundleId>.family_monthly","originalTransactionId":"sandbox-1","expiresInDays":30}
 */
function parseSandboxPayload(
  provider: "apple" | "google",
  payload: string,
  fallbackProductId?: string,
): StoreVerificationResult {
  try {
    const data = JSON.parse(payload) as {
      productId?: string;
      originalTransactionId?: string;
      expiresInDays?: number;
    };
    const productId = data.productId ?? fallbackProductId;
    if (!productId) return { ok: false, error: "sandbox-payload saknar productId" };
    const plan = resolvePlanFromProductId(productId);
    if (!plan || plan === "free") {
      return { ok: false, error: `Okänt productId: ${productId}` };
    }
    const now = new Date();
    return {
      ok: true,
      purchase: {
        provider,
        productId,
        plan,
        originalTransactionId: data.originalTransactionId ?? `sandbox-${Date.now()}`,
        status: "active",
        purchasedAt: now,
        expiresAt: new Date(now.getTime() + (data.expiresInDays ?? 30) * 86_400_000),
      },
    };
  } catch {
    return { ok: false, error: "Ogiltig sandbox-payload (förväntar JSON)" };
  }
}
