import "server-only";

import { createHash, randomUUID } from "crypto";
import { getManagedMembersByOwnerEmail } from "@/lib/mail-automation";
import {
  countMailBillingSeatsFromManagedMembers,
  createMailBillingPreview,
} from "@/lib/mail-billing";

export const TOSS_CONFIRM_API_URL = "https://api.tosspayments.com/v1/payments/confirm";
const TOSS_DOCS_TEST_CLIENT_KEY = "test_ck_D5GePWvyJnrK0W0k6q8gLzN97Eoq";
const TOSS_DOCS_TEST_SECRET_KEY = "test_sk_zXLkKEypNArWmo50nX3lmeaxYG5R";

export type TossPaymentsKeySource = "docs-test" | "env";

export type TossBillingCheckoutSession = {
  amount: number;
  billableSeats: number;
  clientKey: string;
  clientKeySource: TossPaymentsKeySource;
  customerKey: string;
  estimatedMonthlyCost: number;
  failUrl: string;
  hasSecretKey: boolean;
  orderId: string;
  orderName: string;
  secretKeySource: TossPaymentsKeySource;
  successUrl: string;
  usesFallbackAmount: boolean;
};

export function getTossPaymentsClientKey() {
  const value = process.env.NEXT_PUBLIC_TOSS_PAYMENTS_CLIENT_KEY?.trim();
  return value ? value : TOSS_DOCS_TEST_CLIENT_KEY;
}

export function getTossPaymentsClientKeySource(): TossPaymentsKeySource {
  const value = process.env.NEXT_PUBLIC_TOSS_PAYMENTS_CLIENT_KEY?.trim();
  return value ? "env" : "docs-test";
}

export function getTossPaymentsSecretKey() {
  const value = process.env.TOSS_PAYMENTS_SECRET_KEY?.trim();
  return value ? value : TOSS_DOCS_TEST_SECRET_KEY;
}

export function getTossPaymentsSecretKeySource(): TossPaymentsKeySource {
  const value = process.env.TOSS_PAYMENTS_SECRET_KEY?.trim();
  return value ? "env" : "docs-test";
}

export async function buildTossBillingCheckoutSession(input: {
  email: string;
  origin: string;
}): Promise<TossBillingCheckoutSession> {
  const members = await getManagedMembersByOwnerEmail(input.email).catch(() => []);
  const preview = createMailBillingPreview(
    countMailBillingSeatsFromManagedMembers(members.length),
  );
  const origin = input.origin.replace(/\/$/, "");

  return {
    amount: preview.chargeAmount,
    billableSeats: preview.billableSeats,
    clientKey: getTossPaymentsClientKey(),
    clientKeySource: getTossPaymentsClientKeySource(),
    customerKey: createTossCustomerKey(input.email),
    estimatedMonthlyCost: preview.estimatedMonthlyCost,
    failUrl: `${origin}/payments/toss/fail`,
    hasSecretKey: Boolean(getTossPaymentsSecretKey()),
    orderId: createTossOrderId(),
    orderName:
      `성장플랜 ${preview.billableSeats}명`,
    secretKeySource: getTossPaymentsSecretKeySource(),
    successUrl: `${origin}/payments/toss/success`,
    usesFallbackAmount: preview.usesFallbackAmount,
  };
}

export async function getExpectedTossBillingAmountByEmail(email: string) {
  const members = await getManagedMembersByOwnerEmail(email).catch(() => []);
  return createMailBillingPreview(
    countMailBillingSeatsFromManagedMembers(members.length),
  );
}

export function encodeTossSecretKey(secretKey: string) {
  return Buffer.from(`${secretKey}:`).toString("base64");
}

function createTossCustomerKey(email: string) {
  return `om_${createHash("sha256").update(email).digest("base64url").slice(0, 24)}`;
}

function createTossOrderId() {
  return `om_${Date.now()}_${randomUUID().replace(/-/g, "").slice(0, 18)}`;
}
