/**
 * Microsoft 365 / Graph API Send Provider — example reference adapter.
 *
 * Wraps the existing `src/lib/email/m365-sender.ts` low-level helper into the
 * generic `SendProvider` interface so that mailforge core uses it through
 * `adapters.config.ts` rather than importing m365-sender directly.
 *
 * Required env vars (or Settings → `send_provider_config` JSON, siehe `m365-sender-impl.ts`):
 *   M365_TENANT_ID, M365_CLIENT_ID, M365_CLIENT_SECRET — optional M365_AUDIT_BCC
 *   Oder in einem Eintrag: `{ "kind":"m365","tenantId":"…","clientId":"…","clientSecret":"…" }`
 */

import type { SendProvider } from './interface';
import type { UserContext } from '@/core/types';
import type { SendMailInput, SendResult } from '@/adapters/types';
import {
  sendMail as m365SendMail,
  pingGraphUser,
  isM365Configured,
  M365Error,
} from '@/adapters/send/m365-sender-impl';

export const m365Provider: SendProvider = {
  name: 'm365',

  isConfigured() {
    return isM365Configured();
  },

  async send(input: SendMailInput, _ctx?: UserContext): Promise<SendResult> {
    try {
      // Legacy helper expects companyId (1/2/3) for sender resolution.
      // Until Phase B.3 finishes, callers can pass it via workspaceId convention:
      // workspaceId="company:1" -> companyId=1. Adapter falls back to 1 if absent.
      const match = /^company:(\d+)$/.exec(input.workspaceId);
      const companyId = match ? Number(match[1]) : 1;

      await m365SendMail({
        companyId,
        from: input.from.email
          ? { email: input.from.email, name: input.from.name ?? '' }
          : undefined,
        to: input.to,
        cc: input.cc,
        bcc: input.bcc,
        subject: input.subject,
        bodyHtml: input.bodyHtml,
        bodyText: input.bodyText,
        replyTo: input.replyTo?.email,
        saveToSent: true,
      });

      return {
        ok: true,
        messageId: input.messageId,
      };
    } catch (err) {
      if (err instanceof M365Error) {
        const errorKind: SendResult['errorKind'] =
          err.kind === 'network'
            ? 'network'
            : err.kind === 'auth'
              ? 'auth'
              : err.kind === 'config'
                ? 'config'
                : 'rejected';
        return {
          ok: false,
          error: err.message,
          errorKind,
          httpStatus: err.httpStatus,
        };
      }
      return {
        ok: false,
        error: err instanceof Error ? err.message : String(err),
        errorKind: 'unknown',
      };
    }
  },

  async ping(senderEmail: string) {
    try {
      const result = await pingGraphUser(senderEmail);
      return { ok: result.ok === true };
    } catch (err) {
      return { ok: false, error: err instanceof Error ? err.message : String(err) };
    }
  },

  getQuotas() {
    // M365 Graph App-Permission "Mail.Send" limits per mailbox:
    //   - 10000 mails/day (we use 9500 safety margin)
    //   - ~30 recipients per call
    //   - ~20 mails/minute throttle (we use MIN_GAP_MS = 3000 worker-side)
    return { dailyLimit: 9500, perMinute: 20 };
  },
};
