"use server";

import { revalidatePath } from "next/cache";
import { prisma } from "@/lib/db";
import { currentUser } from "@/lib/charts";
import { audit, requireAdmin as requireAdminGuard } from "@/lib/admin-guard";
import { headers } from "next/headers";

export type RequestUpgradeInput = {
  contact?: string;
  note?: string;
};

export type RequestUpgradeResult = { ok: true; requestId: string } | { ok: false; error: string };

/**
 * User-facing: submit a manual upgrade request from /pricing.
 *
 * Idempotent enough — if the user already has an open PENDING request,
 * we return that existing one instead of duplicating.
 */
export async function requestUpgrade(input: RequestUpgradeInput): Promise<RequestUpgradeResult> {
  const me = await currentUser();
  if (!me) {
    return { ok: false, error: "Bạn cần đăng nhập trước khi yêu cầu nâng cấp." };
  }

  // Already premium?
  const u = await prisma.user.findUnique({
    where: { id: me.id },
    select: { plan: true },
  });
  if (u?.plan === "PREMIUM") {
    return { ok: false, error: "Tài khoản của bạn đã ở gói Premium." };
  }

  const existing = await prisma.upgradeRequest.findFirst({
    where: { userId: me.id, status: "PENDING" },
  });
  if (existing) {
    return { ok: true, requestId: existing.id };
  }

  const created = await prisma.upgradeRequest.create({
    data: {
      userId: me.id,
      targetPlan: "PREMIUM",
      contact: input.contact?.trim() || null,
      note: input.note?.trim() || null,
      amountVnd: 99000,
    },
  });

  return { ok: true, requestId: created.id };
}

export type AdminApproveResult = { ok: true } | { ok: false; error: string };

async function requireAdmin() {
  const a = await requireAdminGuard();
  return { userId: a.userId, name: a.name };
}

/**
 * Admin: approve an upgrade request — flip user to PREMIUM, mark
 * the request resolved, audit log.
 */
export async function approveUpgrade(requestId: string): Promise<AdminApproveResult> {
  let admin;
  try {
    admin = await requireAdmin();
  } catch (e) {
    return { ok: false, error: e instanceof Error ? e.message : "Không có quyền." };
  }

  const ip = (await headers()).get("x-forwarded-for")?.split(",")[0]?.trim() ?? null;

  const req = await prisma.upgradeRequest.findUnique({
    where: { id: requestId },
    include: { user: { select: { email: true, plan: true } } },
  });
  if (!req) return { ok: false, error: "Không tìm thấy yêu cầu." };
  if (req.status !== "PENDING") {
    return { ok: false, error: `Yêu cầu đã được xử lý (${req.status}).` };
  }

  await prisma.$transaction([
    prisma.user.update({
      where: { id: req.userId },
      data: { plan: req.targetPlan },
    }),
    prisma.upgradeRequest.update({
      where: { id: requestId },
      data: {
        status: "APPROVED",
        resolvedAt: new Date(),
        resolvedBy: admin.userId,
      },
    }),
  ]);

  await audit({
    actorId: admin.userId,
    actorName: admin.name,
    action: "upgrade.approve",
    target: requestId,
    metadata: {
      userId: req.userId,
      email: req.user.email,
      from: req.user.plan,
      to: req.targetPlan,
    },
    ipAddress: ip ?? undefined,
  });

  revalidatePath("/admin/billing");
  return { ok: true };
}

export async function rejectUpgrade(
  requestId: string,
  reason?: string
): Promise<AdminApproveResult> {
  let admin;
  try {
    admin = await requireAdmin();
  } catch (e) {
    return { ok: false, error: e instanceof Error ? e.message : "Không có quyền." };
  }

  const ip = (await headers()).get("x-forwarded-for")?.split(",")[0]?.trim() ?? null;

  const req = await prisma.upgradeRequest.findUnique({ where: { id: requestId } });
  if (!req) return { ok: false, error: "Không tìm thấy yêu cầu." };
  if (req.status !== "PENDING") {
    return { ok: false, error: `Yêu cầu đã được xử lý (${req.status}).` };
  }

  await prisma.upgradeRequest.update({
    where: { id: requestId },
    data: {
      status: "REJECTED",
      resolvedAt: new Date(),
      resolvedBy: admin.userId,
      note:
        [req.note, reason?.trim() ? `[admin] ${reason.trim()}` : null]
          .filter(Boolean)
          .join("\n\n") || null,
    },
  });

  await audit({
    actorId: admin.userId,
    actorName: admin.name,
    action: "upgrade.reject",
    target: requestId,
    metadata: { reason: reason ?? null },
    ipAddress: ip ?? undefined,
  });

  revalidatePath("/admin/billing");
  return { ok: true };
}
