import "server-only";
import { betterAuth } from "better-auth";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { magicLink } from "better-auth/plugins";
import { appDb, schema } from "./appdb";
import { grantCredits, DENEME_KREDISI } from "./credits";
import { magicLinkEpostasi } from "./eposta";
import { epostaGonder } from "./eposta-gonder";

/**
 * Verify URL'ini maile konacak onay sayfası URL'ine çevirir. Doğrulama linki
 * GET'lendiği anda token'ı tüketen tek kullanımlık bir uçtur; mail güvenlik
 * tarayıcıları (SafeLinks vb.) ve tarayıcı ön-yüklemeleri linki kullanıcıdan
 * önce "ziyaret edip" token'ı yakıyordu. Maildeki link bu yüzden token'ı
 * tüketmeyen /giris/dogrula sayfasına gider; verify ancak oradaki butonla
 * tetiklenir.
 */
function onaySayfasiUrl(verifyUrl: string): string {
  const kaynak = new URL(verifyUrl);
  const hedef = new URL("/giris/dogrula", kaynak.origin);
  hedef.search = kaynak.search;
  return hedef.toString();
}

async function sendMagicLinkEmail(email: string, url: string) {
  if (process.env.NODE_ENV !== "production") {
    // Dev paneli "anında giriş" için son üretilen linki yakalar (bkz.
    // src/lib/dev/actions.ts) — panel onay adımını atlayıp doğrudan verify
    // URL'ine gittiği için ham link saklanır. Prod'da asla çalışmaz.
    (globalThis as { __sonMagicLink?: string }).__sonMagicLink = url;
  }
  const mailLinki = onaySayfasiUrl(url);
  if (!process.env.RESEND_API_KEY) {
    // Dev fallback: Resend anahtarı yoksa linki terminale yaz
    console.log(`\n[giris] Magic link for ${email}:\n${mailLinki}\n`);
    return;
  }
  // Gönderim hatası better-auth'a fırlatılır — aksi halde kullanıcı
  // "gönderildi" ekranını görür ama mail hiç çıkmaz.
  await epostaGonder(email, magicLinkEpostasi(mailLinki));
}

export const auth = betterAuth({
  baseURL: process.env.BETTER_AUTH_URL ?? "http://localhost:3000",
  secret: process.env.BETTER_AUTH_SECRET,
  database: drizzleAdapter(appDb, {
    provider: "sqlite",
    schema: {
      user: schema.user,
      session: schema.session,
      account: schema.account,
      verification: schema.verification,
    },
  }),
  session: {
    // Session'ı imzalı cookie'de önbelle: her istekte session tablosu
    // sorgusu yapılmaz. Kredi/paket tazeliği getCurrentUser()'daki ayrı
    // user sorgusuyla korunur (src/lib/session.ts).
    cookieCache: { enabled: true, maxAge: 5 * 60 },
  },
  user: {
    additionalFields: {
      creditBalance: { type: "number", defaultValue: 0, input: false },
      hasPaket: { type: "boolean", defaultValue: false, input: false },
    },
  },
  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_CLIENT_ID ?? "",
      clientSecret: process.env.GOOGLE_CLIENT_SECRET ?? "",
    },
  },
  plugins: [
    magicLink({
      // Varsayılan 5 dk, mail gecikmesi + onay adımı için 15 dk'ya çıkarıldı.
      // Süreyi değiştirirken e-posta metnini (src/lib/eposta.ts) ve giriş
      // ekranındaki "gönderildi" mesajını (giris-form.tsx) da güncelle.
      expiresIn: 900,
      sendMagicLink: async ({ email, url }) => {
        await sendMagicLinkEmail(email, url);
      },
    }),
  ],
  databaseHooks: {
    user: {
      create: {
        after: async (newUser) => {
          // refId = userId → UNIQUE(reason, refId) ile tek seferlik
          await grantCredits({
            userId: newUser.id,
            delta: DENEME_KREDISI,
            reason: "trial_grant",
            refId: newUser.id,
          });
        },
      },
    },
  },
});

export type Session = typeof auth.$Infer.Session;