import "reflect-metadata";
import { injectable } from "inversify";
import { getPayload } from "payload";
import type { SanitizedConfig } from "payload";
import {
  NoopTracer,
  NoopLogger,
  type ITracer,
  type ILogger,
} from "@repo/core-shared/instrumentation";

import type { ISiteSettingsRepository } from "../../application/repositories/site-settings.repository.interface";
import type { SiteSettings } from "../../entities/models/site-settings";

type PayloadSiteSettings = {
  siteName?: string | null;
  siteDescription?: string | null;
};

const FEATURE = "marketing-pages" as const;
const REPO = "site-settings" as const;

@injectable()
export class SiteSettingsRepository implements ISiteSettingsRepository {
  private config: SanitizedConfig;
  private tracer: ITracer;
  private logger: ILogger;

  constructor(
    config: SanitizedConfig,
    tracer: ITracer = new NoopTracer(),
    logger: ILogger = new NoopLogger(),
  ) {
    this.config = config;
    this.tracer = tracer;
    this.logger = logger;
  }

  async getSiteSettings(): Promise<SiteSettings> {
    return this.tracer.startSpan(
      { name: "site-settings.getSiteSettings", op: "repository", attributes: {} },
      async (span) => {
        try {
          const payload = await getPayload({ config: this.config });
          const doc = (await payload.findGlobal({
            slug: "site-settings",
            overrideAccess: true,
          })) as PayloadSiteSettings;
          span.setAttribute("found", true);
          return {
            siteName: doc.siteName ?? "My App",
            siteDescription: doc.siteDescription ?? undefined,
          };
        } catch (err) {
          this.logger.captureException(err, {
            tags: { feature: FEATURE, repo: REPO, method: "getSiteSettings" },
          });
          span.setStatus("error", err instanceof Error ? err.message : String(err));
          throw err;
        }
      },
    );
  }
}
