import { api } from "@/lib/api";
import type {
  AdapterResult,
  CommercialProduct,
  CommercialWorkspaceSnapshot,
  SetupChecklistItem,
  TrialState,
} from "../types";
import { resolveProductLaunchUrl } from "../types";
import { evaluateDomainPolicy } from "./policies";
import { loadCommercialUsage } from "./usage";
import { commercialGet, commercialPost } from "./http";

function computeTrial(sub: {
  status?: string | null;
  trial_ends_at?: string | null;
} | null): TrialState | null {
  if (!sub?.status) return null;
  const active = sub.status === "trialing";
  let days_remaining: number | null = null;
  if (sub.trial_ends_at) {
    const end = new Date(sub.trial_ends_at).getTime();
    days_remaining = Math.max(0, Math.ceil((end - Date.now()) / 86400000));
  }
  return { active, days_remaining, ends_at: sub.trial_ends_at ?? null, quotas: [] };
}

/**
 * Entitlement check — Commercial Runtime only. Safe deny when unavailable.
 */
export async function checkFeatureAccess(
  tenantId: string,
  featureKey: string
): Promise<import("../types").EntitlementCheckResult> {
  const commercial = await commercialPost<{
    has_access?: boolean;
    allowed?: boolean;
    reason?: string | null;
    required_plan?: string | null;
    required_capability?: string | null;
    required_bundle?: string | null;
  }>("/api/v1/commercial/entitlements/check", {
    tenant_id: tenantId,
    feature_key: featureKey,
    capability_code: featureKey,
  });
  if (commercial.ok) {
    const allowed = Boolean(commercial.data.has_access ?? commercial.data.allowed);
    return {
      has_access: allowed,
      reason: commercial.data.reason ?? null,
      required_plan: commercial.data.required_plan ?? null,
      required_capability: commercial.data.required_capability ?? null,
      required_bundle: commercial.data.required_bundle ?? null,
    };
  }
  return {
    has_access: false,
    reason: commercial.message || "بررسی entitlement در دسترس نیست",
    unavailable: true,
  };
}

export async function loadWorkspaceSnapshot(): Promise<
  AdapterResult<CommercialWorkspaceSnapshot | null>
> {
  try {
    const tenantCtx = await api.tenantContext.current();
    const tenantId = tenantCtx.tenant.id;

    const dash = await commercialGet<{
      subscription?: {
        status?: string | null;
        plan_code?: string | null;
        bundle_code?: string | null;
        trial_ends_at?: string | null;
      } | null;
      pinned_product_codes?: string[];
      recent_product_codes?: string[];
      quick_actions?: CommercialWorkspaceSnapshot["quick_actions"];
      locked_features?: CommercialWorkspaceSnapshot["locked_features"];
      workspace_health?: string | null;
      checklist_completion_percent?: number | null;
      product_codes?: string[];
      capability_codes?: string[];
      bundle_code?: string | null;
    }>(`/api/v1/commercial/dashboard?tenant_id=${encodeURIComponent(tenantId)}`);

    const commercialSub = dash.ok ? dash.data.subscription ?? null : null;
    const status =
      commercialSub?.status ?? tenantCtx.subscription_status ?? null;
    const trial = computeTrial(commercialSub);
    const usage = await loadCommercialUsage(tenantId);
    if (trial && usage.availability === "ready") {
      trial.quotas = usage.data;
    }

    const domainEval = await evaluateDomainPolicy({
      tenant_id: tenantId,
      subscription_status: status,
    });

    const pinned = dash.ok ? dash.data.pinned_product_codes ?? [] : [];
    const recent = dash.ok ? dash.data.recent_product_codes ?? [] : [];
    const quick = dash.ok ? dash.data.quick_actions ?? [] : [];

    const domainData = domainEval.data;
    const params = domainData.parameters || {};

    const snapshot: CommercialWorkspaceSnapshot = {
      tenant_id: tenantId,
      tenant_name: tenantCtx.tenant.name,
      slug: tenantCtx.tenant.slug,
      status: tenantCtx.tenant.status,
      plan_name: commercialSub?.plan_code ?? tenantCtx.plan_name,
      subscription_status: status,
      onboarding_completed: tenantCtx.tenant.onboarding_completed,
      primary_domain: tenantCtx.primary_domain,
      domains: tenantCtx.domains.map((d) => ({
        id: d.id,
        domain: d.domain,
        domain_type: d.domain_type,
        is_verified: d.is_verified,
      })),
      role: tenantCtx.role,
      trial,
      custom_domain_unlocked: Boolean(domainData.custom_domain_allowed),
      domain_policy: {
        ...domainData,
        ssl_ready:
          domainData.ssl_ready ??
          (typeof params.ssl_ready === "boolean" ? params.ssl_ready : undefined),
        dns_instructions:
          domainData.dns_instructions ??
          (Array.isArray(params.dns_instructions)
            ? (params.dns_instructions as NonNullable<
                CommercialWorkspaceSnapshot["domain_policy"]
              >["dns_instructions"])
            : undefined),
        verification_state:
          domainData.verification_state ??
          (typeof params.verification_state === "string" ? params.verification_state : null),
      },
      pinned_product_codes: pinned,
      recent_product_codes: recent,
      quick_actions: quick,
      product_codes: dash.ok ? dash.data.product_codes ?? [] : [],
      capability_codes: dash.ok ? dash.data.capability_codes ?? [] : [],
      bundle_code: dash.ok
        ? dash.data.bundle_code ?? commercialSub?.bundle_code ?? null
        : commercialSub?.bundle_code ?? null,
      locked_features: dash.ok ? dash.data.locked_features ?? [] : [],
      workspace_health: dash.ok ? dash.data.workspace_health ?? null : null,
      checklist_completion_percent: dash.ok
        ? dash.data.checklist_completion_percent ?? null
        : null,
    };

    return { availability: "ready", data: snapshot, source: "commercial.runtime" };
  } catch (err) {
    return {
      availability: "error",
      data: null,
      message: err instanceof Error ? err.message : "خطا در بارگذاری workspace",
      source: "none",
    };
  }
}

/** Checklist from discovered products' launch metadata — no hardcoded product list. */
export function buildSetupChecklist(
  products: CommercialProduct[],
  opts?: { installedCodes?: string[] }
): SetupChecklistItem[] {
  const installed = new Set(opts?.installedCodes ?? []);
  const fromProducts = products
    .filter((p) => p.visibility !== "hidden")
    .map((p) => ({
      id: `product:${p.product_code}`,
      label: p.display_name,
      href: resolveProductLaunchUrl(p),
      product_code: p.product_code,
      done: installed.has(p.product_code),
      required: false,
    }));

  const workspaceActions =
    products.length === 0
      ? [
          { id: "workspace", label: "Workspace", href: "/dashboard", required: true },
          { id: "billing", label: "Billing", href: "/billing", required: false },
        ]
      : [];

  return [...workspaceActions, ...fromProducts];
}
