import { createServerFn } from "@tanstack/react-start";
import { createClient } from "@supabase/supabase-js";
import { z } from "zod";
import type { Database } from "@/integrations/supabase/types";

function publicClient() {
  return createClient<Database>(
    process.env.SUPABASE_URL!,
    process.env.SUPABASE_PUBLISHABLE_KEY!,
    { auth: { storage: undefined, persistSession: false, autoRefreshToken: false } },
  );
}

export const listActivePlans = createServerFn({ method: "GET" }).handler(async () => {
  const sb = publicClient();
  const { data, error } = await sb
    .from("plans")
    .select("id,name,price_kes,duration_minutes,download_kbps,upload_kbps,device_limit,description,sort_order")
    .eq("is_active", true)
    .order("sort_order", { ascending: true });
  if (error) return { plans: [], error: error.message };
  return { plans: data ?? [], error: null as string | null };
});

const purchaseSchema = z.object({
  plan_id: z.string().uuid(),
  phone: z.string().regex(/^(?:\+?254|0)?7\d{8}$/, "Enter a valid Safaricom number"),
  mac_address: z.string().optional().nullable(),
});

function normalizePhone(raw: string): string {
  const digits = raw.replace(/\D/g, "");
  if (digits.startsWith("254")) return digits;
  if (digits.startsWith("0")) return "254" + digits.slice(1);
  if (digits.startsWith("7")) return "254" + digits;
  return digits;
}

export const initiatePurchase = createServerFn({ method: "POST" })
  .inputValidator((data: unknown) => purchaseSchema.parse(data))
  .handler(async ({ data }) => {
    const { supabaseAdmin } = await import("@/integrations/supabase/client.server");
    const phone = normalizePhone(data.phone);

    const { data: plan, error: planErr } = await supabaseAdmin
      .from("plans")
      .select("id, price_kes, duration_minutes, is_active")
      .eq("id", data.plan_id)
      .maybeSingle();

    if (planErr || !plan || !plan.is_active) {
      return { ok: false as const, error: "Plan unavailable" };
    }

    const { data: sub, error: subErr } = await supabaseAdmin
      .from("subscriptions")
      .insert({
        plan_id: plan.id,
        phone,
        mac_address: data.mac_address ?? null,
        status: "pending",
      })
      .select("id")
      .single();

    if (subErr || !sub) {
      return { ok: false as const, error: subErr?.message ?? "Could not start purchase" };
    }

    const { data: payment, error: payErr } = await supabaseAdmin
      .from("payments")
      .insert({
        subscription_id: sub.id,
        phone,
        amount_kes: plan.price_kes,
        provider: "mpesa",
        status: "pending",
      })
      .select("id")
      .single();

    if (payErr || !payment) {
      return { ok: false as const, error: payErr?.message ?? "Could not record payment" };
    }

    // Trigger M-Pesa STK Push. If not configured, leave payment pending for
    // manual reconciliation from the admin console.
    const { stkPush, isMpesaConfigured } = await import("@/lib/mpesa.server");
    let manual = false;
    if (isMpesaConfigured()) {
      const origin = process.env.PUBLIC_APP_URL || process.env.SUPABASE_URL?.replace(/\/$/, "") || "";
      // Prefer explicit PUBLIC_APP_URL; otherwise fall back to request origin
      const { getRequestHost } = await import("@tanstack/react-start/server");
      const host = (() => { try { return getRequestHost(); } catch { return ""; } })();
      const base = process.env.PUBLIC_APP_URL || (host ? `https://${host}` : origin);
      const result = await stkPush({
        phone,
        amount: plan.price_kes,
        reference: `SUB${sub.id.slice(0, 8)}`,
        description: "BVANNY WiFi",
        callbackUrl: `${base}/api/public/mpesa/callback`,
      });
      if (result.ok) {
        await supabaseAdmin
          .from("payments")
          .update({
            checkout_request_id: result.checkout_request_id,
            merchant_request_id: result.merchant_request_id,
          })
          .eq("id", payment.id);
      } else if (!result.soft) {
        return { ok: false as const, error: result.error };
      } else {
        manual = true;
      }
    } else {
      manual = true;
    }

    return {
      ok: true as const,
      subscription_id: sub.id,
      payment_id: payment.id,
      phone,
      manual,
    };
  });

export const getPaymentStatus = createServerFn({ method: "GET" })
  .inputValidator((data: unknown) => z.object({ payment_id: z.string().uuid() }).parse(data))
  .handler(async ({ data }) => {
    const { supabaseAdmin } = await import("@/integrations/supabase/client.server");
    const { data: row, error } = await supabaseAdmin
      .from("payments")
      .select("status, subscription_id")
      .eq("id", data.payment_id)
      .maybeSingle();
    if (error || !row) return { status: "unknown" as const };
    return { status: row.status, subscription_id: row.subscription_id };
  });
