import { createServerFn } from "@tanstack/react-start";
import { z } from "zod";
import { requireExtSupabaseAuth } from "@/integrations/external-supabase/auth-middleware";
import { supabaseExtAdmin } from "@/integrations/external-supabase/client.server";

async function ensureAdmin(userId: string) {
  const { data, error } = await supabaseExtAdmin
    .from("user_roles")
    .select("role")
    .eq("user_id", userId)
    .eq("role", "admin")
    .maybeSingle();
  if (error) throw new Error(error.message);
  if (!data) throw new Error("Forbidden: admin only");
}

export const checkIsAdmin = createServerFn({ method: "GET" })
  .middleware([requireExtSupabaseAuth])
  .handler(async ({ context }) => {
    const { data } = await supabaseExtAdmin
      .from("user_roles")
      .select("role")
      .eq("user_id", context.userId)
      .eq("role", "admin")
      .maybeSingle();
    return { isAdmin: !!data };
  });

export const getDashboardStats = createServerFn({ method: "GET" })
  .middleware([requireExtSupabaseAuth])
  .handler(async ({ context }) => {
    await ensureAdmin(context.userId);
    const { data: orders } = await supabaseExtAdmin
      .from("orders")
      .select("id, status, total_bdt, customer_email, created_at, order_number, package_name, quantity, total_credits")
      .order("created_at", { ascending: false });

    const all = orders ?? [];
    const byStatus = (s: string) => all.filter((o: any) => o.status === s);
    const revenue = all
      .filter((o: any) => o.status === "delivered" || o.status === "verified")
      .reduce((sum: number, o: any) => sum + (o.total_bdt || 0), 0);
    const customers = new Set(all.map((o: any) => o.customer_email)).size;

    return {
      total: all.length,
      pending: byStatus("pending").length,
      verified: byStatus("verified").length,
      delivered: byStatus("delivered").length,
      rejected: byStatus("rejected").length,
      revenue,
      customers,
      recent: all.slice(0, 10),
    };
  });

export const listOrders = createServerFn({ method: "GET" })
  .middleware([requireExtSupabaseAuth])
  .inputValidator((input: { status?: string; search?: string } | undefined) =>
    z
      .object({ status: z.string().optional(), search: z.string().optional() })
      .parse(input ?? {}),
  )
  .handler(async ({ context, data }) => {
    await ensureAdmin(context.userId);
    let q = supabaseExtAdmin.from("orders").select("*").order("created_at", { ascending: false }).limit(500);
    if (data.status && data.status !== "all") q = q.eq("status", data.status as any);
    if (data.search) q = q.ilike("customer_email", `%${data.search}%`);
    const { data: rows, error } = await q;
    if (error) throw new Error(error.message);
    return rows ?? [];
  });

export const updateOrderStatus = createServerFn({ method: "POST" })
  .middleware([requireExtSupabaseAuth])
  .inputValidator((input: { id: string; status: "pending" | "verified" | "delivered" | "rejected" }) =>
    z.object({
      id: z.string().uuid(),
      status: z.enum(["pending", "verified", "delivered", "rejected"]),
    }).parse(input),
  )
  .handler(async ({ context, data }) => {
    await ensureAdmin(context.userId);
    const patch: any = { status: data.status, updated_at: new Date().toISOString() };
    if (data.status === "delivered") patch.delivered_at = new Date().toISOString();
    const { error } = await supabaseExtAdmin.from("orders").update(patch).eq("id", data.id);
    if (error) throw new Error(error.message);
    return { ok: true };
  });

export const listPackages = createServerFn({ method: "GET" })
  .middleware([requireExtSupabaseAuth])
  .handler(async ({ context }) => {
    await ensureAdmin(context.userId);
    const { data, error } = await supabaseExtAdmin
      .from("packages")
      .select("*")
      .order("sort_order", { ascending: true });
    if (error) throw new Error(error.message);
    return data ?? [];
  });

const packageSchema = z.object({
  id: z.string().uuid().optional(),
  name: z.string().min(1).max(255),
  credits: z.number().int().min(1),
  price_bdt: z.number().int().min(1),
  description: z.string().max(1000).optional().nullable(),
  is_active: z.boolean(),
  sort_order: z.number().int().default(0),
});

export const upsertPackage = createServerFn({ method: "POST" })
  .middleware([requireExtSupabaseAuth])
  .inputValidator((input: unknown) => packageSchema.parse(input))
  .handler(async ({ context, data }) => {
    await ensureAdmin(context.userId);
    if (data.id) {
      const { error } = await supabaseExtAdmin
        .from("packages")
        .update({ ...data, updated_at: new Date().toISOString() })
        .eq("id", data.id);
      if (error) throw new Error(error.message);
    } else {
      const { id: _ignore, ...insert } = data;
      const { error } = await supabaseExtAdmin.from("packages").insert(insert);
      if (error) throw new Error(error.message);
    }
    return { ok: true };
  });

export const deletePackage = createServerFn({ method: "POST" })
  .middleware([requireExtSupabaseAuth])
  .inputValidator((input: { id: string }) => z.object({ id: z.string().uuid() }).parse(input))
  .handler(async ({ context, data }) => {
    await ensureAdmin(context.userId);
    const { error } = await supabaseExtAdmin.from("packages").delete().eq("id", data.id);
    if (error) throw new Error(error.message);
    return { ok: true };
  });

export const listCustomers = createServerFn({ method: "GET" })
  .middleware([requireExtSupabaseAuth])
  .handler(async ({ context }) => {
    await ensureAdmin(context.userId);
    const { data, error } = await supabaseExtAdmin
      .from("orders")
      .select("customer_email, whatsapp, total_bdt, status, created_at");
    if (error) throw new Error(error.message);
    const map = new Map<string, { email: string; whatsapp: string | null; orders: number; spend: number; last: string }>();
    for (const o of data ?? []) {
      const e = (o as any).customer_email as string;
      const cur = map.get(e) ?? { email: e, whatsapp: (o as any).whatsapp ?? null, orders: 0, spend: 0, last: (o as any).created_at };
      cur.orders += 1;
      if ((o as any).status === "delivered" || (o as any).status === "verified") cur.spend += (o as any).total_bdt || 0;
      if ((o as any).created_at > cur.last) cur.last = (o as any).created_at;
      if (!cur.whatsapp && (o as any).whatsapp) cur.whatsapp = (o as any).whatsapp;
      map.set(e, cur);
    }
    return Array.from(map.values()).sort((a, b) => (a.last < b.last ? 1 : -1));
  });

export const getTelegramSettings = createServerFn({ method: "GET" })
  .middleware([requireExtSupabaseAuth])
  .handler(async ({ context }) => {
    await ensureAdmin(context.userId);
    const { data } = await supabaseExtAdmin
      .from("telegram_settings")
      .select("admin_chat_id, is_enabled, bot_username, connected_at, bot_token")
      .eq("id", 1)
      .maybeSingle();
    return {
      admin_chat_id: data?.admin_chat_id ?? "",
      is_enabled: data?.is_enabled ?? false,
      bot_username: data?.bot_username ?? "",
      connected_at: data?.connected_at ?? null,
      has_token: !!data?.bot_token,
    };
  });

export const saveTelegramSettings = createServerFn({ method: "POST" })
  .middleware([requireExtSupabaseAuth])
  .inputValidator((input: { bot_token: string; admin_chat_id: string }) =>
    z.object({
      bot_token: z.string().min(10).max(255),
      admin_chat_id: z.string().min(1).max(50),
    }).parse(input),
  )
  .handler(async ({ context, data }) => {
    await ensureAdmin(context.userId);
    // verify with getMe
    const meRes = await fetch(`https://api.telegram.org/bot${data.bot_token}/getMe`);
    const me = await meRes.json();
    if (!me.ok) throw new Error("Invalid bot token");

    // send test message
    await fetch(`https://api.telegram.org/bot${data.bot_token}/sendMessage`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        chat_id: data.admin_chat_id,
        text: "✅ দেশি কোর্স admin dashboard connected!",
      }),
    });

    const { error } = await supabaseExtAdmin.from("telegram_settings").upsert({
      id: 1,
      bot_token: data.bot_token,
      admin_chat_id: data.admin_chat_id,
      bot_username: me.result?.username ?? null,
      is_enabled: true,
      connected_at: new Date().toISOString(),
      updated_at: new Date().toISOString(),
    });
    if (error) throw new Error(error.message);
    return { ok: true, username: me.result?.username };
  });

export const disconnectTelegram = createServerFn({ method: "POST" })
  .middleware([requireExtSupabaseAuth])
  .handler(async ({ context }) => {
    await ensureAdmin(context.userId);
    const { error } = await supabaseExtAdmin
      .from("telegram_settings")
      .update({ is_enabled: false, bot_token: null, updated_at: new Date().toISOString() })
      .eq("id", 1);
    if (error) throw new Error(error.message);
    return { ok: true };
  });