import { cert, getApp, getApps, initializeApp } from "firebase-admin/app";
import { getMessaging } from "firebase-admin/messaging";
import { env } from "../config/env.js";

type NativePushResult =
  | { ok: true; messageId: string }
  | { ok: false; reason: string; code?: string };

function getFirebaseApp() {
  if (
    env.FIREBASE_SERVICE_ACCOUNT_JSON.trim().length === 0 &&
    (env.FIREBASE_PROJECT_ID.trim().length === 0 ||
      env.FIREBASE_CLIENT_EMAIL.trim().length === 0 ||
      env.FIREBASE_PRIVATE_KEY.trim().length === 0)
  ) {
    return null;
  }

  if (getApps().length > 0) {
    return getApp();
  }

  const credentials =
    env.FIREBASE_SERVICE_ACCOUNT_JSON.trim().length > 0
      ? JSON.parse(env.FIREBASE_SERVICE_ACCOUNT_JSON)
      : {
          projectId: env.FIREBASE_PROJECT_ID,
          clientEmail: env.FIREBASE_CLIENT_EMAIL,
          privateKey: env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, "\n")
        };

  return initializeApp({
    credential: cert(credentials)
  });
}

export function isNativePushConfigured() {
  return getFirebaseApp() !== null;
}

export async function sendNativePush(
  token: string,
  payload: {
    title: string;
    body: string;
    data?: Record<string, string>;
  }
): Promise<NativePushResult> {
  const app = getFirebaseApp();
  if (!app) {
    return { ok: false, reason: "Firebase is not configured", code: "messaging/not-configured" };
  }

  try {
    const messageId = await getMessaging(app).send({
      token,
      notification: {
        title: payload.title,
        body: payload.body
      },
      data: payload.data,
      android: {
        priority: "high",
        notification: {
          channelId: "signals",
          clickAction: "OPEN_SIGNAL"
        }
      },
      apns: {
        payload: {
          aps: {
            sound: "default"
          }
        }
      }
    });

    return { ok: true, messageId };
  } catch (error) {
    const details = error as { code?: string; message?: string };
    return {
      ok: false,
      reason: details.message || "Native push delivery failed",
      code: details.code
    };
  }
}
