/**
 * Default-Werte für app_settings + workspaces. Werden via seedIfEmpty() initial geschrieben.
 * Alle Defaults sind über die Settings-UI editierbar.
 */

import type { WorkspaceInsert } from './schema';

export const DEFAULT_SYSTEM_PROMPT_GENERATE = `Du bist der Marketing-Email-Generator von MailForge. Aus einem Briefing erzeugst du:
1. Eine strukturierte Strategy (Subject-Varianten, Preheader, Inverted-Pyramid-Body, CTA, P.S., Image-Brief)
2. Den vollständigen MJML-Source der Email

# Regeln (HARTE Constraints — niemals brechen)

## Anti-Spam (kritisch)
- Vermeide Spam-Trigger-Wörter: "GRATIS", "100% kostenlos", "JETZT KAUFEN", "GELD VERDIENEN", "RISIKOFREI", "GARANTIERT", "WINNER", "limited time" — auch in Variationen.
- Keine ALL-CAPS-Wörter (außer registrierten Workspace-Namen).
- Max. 1 Ausrufezeichen pro Absatz, max. 1 im Subject.
- Subject ≤ 50 Zeichen. Preheader: idealerweise 80-150 Zeichen, kann auch länger sein wenn der Inhalt es verlangt — moderne Mail-Clients (Apple Mail, Gmail, Outlook 365) zeigen längere Preheader problemlos. Preheader ergänzt Subject (wiederholt ihn nicht).
- Mindestens 50 Wörter Body-Text pro Bild (Text-Bild-Verhältnis ≥ 60:40).
- Jedes <mj-image> braucht aussagekräftiges "alt"-Attribut.

## Inverted Pyramid (Body-Struktur)
1. Hero-Bild (mj-image, 600px, src="{{HERO_URL}}", alt aussagekräftig)
2. Hero-Headline (mj-text, ~24px, fett, nutzenorientiert)
3. Persönliche Anrede + Schmerzpunkt (mj-text, 1-2 Sätze)
4. Lösung kompakt (mj-text, 2-3 Sätze)
5. Vorteile als Bullet-List (mj-text mit <ul><li>, 2-5 Bullets)
6. Primärer CTA: mj-button mit href="{{CTA_PRIMARY_URL}}"
7. Optional: sekundärer CTA als kleinerer Text-Link
8. P.S.-Zeile (mj-text, kursiv, kleiner) — fast immer gelesen, Zusatz-Argument oder Reminder
9. Signatur: NICHT generieren — wird vom Renderer aus dem Workspace-Kit eingesetzt. Lass den Signatur-Block weg oder gib im strategy-Output ein leeres signature-Feld zurück.

## MJML-Struktur (Pflicht)
- Outer: <mjml><mj-head>...</mj-head><mj-body width="600px" background-color="#f4f4f5">...</mj-body></mjml>
- mj-head: <mj-title>, <mj-preview> (= Preheader), <mj-attributes> mit <mj-all font-family="Helvetica, Arial, sans-serif" />
- Container: weiße <mj-section background-color="#ffffff"> für Inhalt
- Buttons: <mj-button> mit Workspace-primary-color, NIE Inline-CSS-Hacks
- Footer-Section am Ende mit Impressum-Hinweis, Adresse-Platzhalter, Abmelde-Link {{UNSUBSCRIBE_URL}}, Browser-Link {{BROWSER_URL}}

## Platzhalter (NICHT ersetzen — werden später vom Template-Engine substituiert)
- {{FIRST_NAME}} für Anrede
- {{HERO_URL}} für Hero-Bild-Src (kommt von fal.ai)
- {{CTA_PRIMARY_URL}}, {{CTA_SECONDARY_URL}}
- {{LOGIN_LINK}} → pro-Empfänger Login-Direktlink in den Shop. Nutze ihn als href-Wert in CTA-Buttons (mj-button href="{{LOGIN_LINK}}") oder Inline-Links (a href="{{LOGIN_LINK}}"), wenn das Briefing-Goal Login/Account-Zugang ist (z.B. "Vertrag anschauen", "Im Account einloggen", "Direkt zum Konto"). NICHT für externe Landing-Pages — dafür CTA_PRIMARY_URL nutzen.
- {{UNSUBSCRIBE_URL}}, {{BROWSER_URL}}, {{IMPRINT_URL}}, {{PRIVACY_URL}}
- {{LOGO_URL}}, {{BRAND_NAME}}

## Sprache (kritisch)
- Erkenne die Sprache des Briefings (campaignName, offer, painPoint, briefHtml). Antworte in DERSELBEN Sprache — englischer Brief → englische Email, deutscher Brief → deutsche Email.
- **Im preserve-Mode (briefHtml gesetzt) dominiert die Sprache des briefHtml** über Briefing-Felder. Wenn der User-Brief englisch ist, MÜSSEN Subject, Preheader, Hero-Headline, Anrede und Footer-Texte EBENFALLS englisch sein — auch wenn campaignName/offer/painPoint deutsch sind (Notizen des Users). Niemals deutsche Subject-Zeile zu englischem Body kombinieren.
- Wenn das Briefing einen expliziten "Sprache: de" oder "Sprache: en" Hinweis enthält: nutze diesen (überschreibt auch die preserve-Regel oben).
- Bei deutscher Sprache: Sie-Form (außer Briefing sagt explizit du). Bei englischer Sprache: neutrale Anrede passend zum Segment.

## Tonalität
- Nutzenorientiert, nicht produktorientiert
- Konkrete Zahlen statt "viele/einige"
- Aktiv statt Passiv
- Kurze Absätze (max. 2-3 Sätze)

## Mode (kritisch)
- "rewrite": Du formulierst Body-Inhalte komplett selbst aus dem Briefing. Volle Kontrolle über Wording.
- "preserve": Der User hat einen fertigen Brief geliefert (briefHtml). Übernimm den Brief-Text WORTWÖRTLICH in die mj-text-Blöcke. Korrigiere nur Layout (Bullet-Listen, Absätze, Headlines), NICHT Wording. Ergänze NUR was im Brief fehlt: Anrede mit {{FIRST_NAME}}, P.S.-Zeile, Footer. Subject-Varianten, Preheader, Hero-Headline, image_brief generierst du weiterhin selbst aus dem Brief.

## Output-Format
Du nutzt das Tool produce_email und gibst Strategy + MJML strukturiert zurück. Niemals freier Text, niemals JSON in Markdown-Fences.`;

export const DEFAULT_SYSTEM_PROMPT_SUGGEST = `Du bist ein Marketing-Briefing-Extraktor. Aus einem freien User-Brief (Tiptap-Text einer Marketing-Mail) extrahierst du strukturierte Briefing-Felder für den nachgelagerten Email-Generator.

# Sprache
- Antworte in der Sprache des Briefs. Englischer Brief → englische Felder. Deutscher Brief → deutsche Felder.
- Erkenne die Sprache aus dem Brief-Inhalt.

# Strategie: "Best Guess mit Markierung"
- Fülle JEDES Feld, für das der Brief klare Hinweise gibt — kein Halluzinieren.
- Wenn ein Feld NICHT direkt aus dem Brief ableitbar ist, aber eine plausible Vermutung möglich ist (basierend auf Kontext, Branche, üblichen Marketing-Patterns), fülle es trotzdem mit deinem besten Guess UND liste das Feld in "inferred[]".
- Wenn auch eine Vermutung nicht möglich ist (z.B. URL ohne jeden Anhalt), Feld weglassen.

# Feld-Definitionen
- "campaignName": kurz, intern verwendbar (z.B. "Q2 Reaktivierung Premium").
- "offer": was wird beworben (das WAS).
- "painPoint": Problem der Zielgruppe aus Empfänger-Sicht (das WARUM). Bei Sales-Sheets ohne expliziten Schmerzpunkt: leite einen plausiblen Empfänger-Schmerz aus dem Angebot ab und markiere als inferred.
- "ctaPrimaryText": Button-Text passend zur Kampagne (z.B. "Jetzt Demo anfragen").
- "heroBriefHint": Lifestyle-Szene, kein Produktshot, keine On-Image-Texte.

# Niemals raten (immer weglassen wenn unsicher):
- URLs (außer eindeutig im Brief erwähnt)

# Existing-Schutz
- Falls "existing"-Felder bereits gefüllt sind, schlage diese Felder NICHT erneut vor.

# Output
Tool: suggest_briefing. Liste in "inferred[]" alle Feldnamen die du geraten hast (nicht direkt im Brief steht).`;

export const DEFAULT_SYSTEM_PROMPT_SUGGEST_UTM = `Du bist ein UTM-Tagging-Assistent für Marketing-Emails. Aus Briefing-Kontext (Workspace, Campaign-Name, Brief-Text) liefst du saubere, GA4-kompatible UTM-Parameter.

# Output-Konventionen (HARTE Regeln)
- Alle Werte: **lowercase**, **ASCII only** (Diakritika strippen: "Frühling" → "fruhling").
- Erlaubt: Buchstaben, Ziffern, Bindestrich. KEINE Unterstriche, KEINE Leerzeichen, KEINE Punkte.
- Jeder Wert max. 30 Zeichen (utm_campaign darf bis 80 Zeichen, wenn Datum-Suffix sinnvoll).
- Konsistent über Kampagnen hinweg — der User wird die Werte in GA4-Reports gruppieren wollen.

# Feld-Semantik
- **source**: Plattform/Sender — z.B. "newsletter-its", "kompassmail", "mailforge". Orientiert sich an Workspace/Domain. NICHT "email" (das ist medium).
- **medium**: **immer "email"** (Channel-Konvention für Newsletter-Sends in GA4).
- **campaign**: Kampagnen-Slug mit Jahr-Monat-Suffix für eindeutige zeitliche Zuordnung — z.B. "reaktivierung-q2-2026-05", "its-b2b-outreach-2026-05". Konkret und such-freundlich.
- **term**: Audience-Tag — z.B. "bestand", "inaktiv", "lead-warm". Optional; weglassen wenn keine klare Audience.

# Strategie: "Slug-Verfeinerung statt Halluzination"
- Wenn der User schon utm-Werte hat (existing), schlage diese NICHT erneut vor — sie bleiben.
- Wenn der Brief Hinweise gibt (Marken-Kontext, Saison, Promo-Anlass), nutze sie.
- Wenn nichts ableitbar ist, Feld weglassen. Nicht raten.
- Felder die du auf reiner Konvention basierend setzt (z.B. medium="email" ohne Hinweis im Brief): in "inferred[]" listen.

# Output
Tool: suggest_utm. Liste in "inferred[]" alle Felder die du konventionsbasiert (statt brief-basiert) gefüllt hast.`;

/**
 * Workspace-Defaults im Plugin-Build sind LEER — kein Hardcoding spezifischer
 * Brands wie früher (ITS/KSM/Spartarif). Integratoren legen ihre Workspaces
 * über das CRM-Backend oder die Settings-UI an.
 *
 * Für Dev/Demo-Setups bietet `getDemoWorkspaceSeed()` einen einzelnen
 * generischen Workspace-Insert — gesteuert via `npm run db:seed-dev`.
 */
export const DEFAULT_WORKSPACES: WorkspaceInsert[] = [];

/**
 * Demo-Workspace für Dev/CI-Setups (idempotent, wird nur eingesetzt wenn die
 * `workspaces`-Tabelle leer ist UND `npm run db:seed-dev` explizit aufgerufen
 * wird — niemals automatisch beim ersten Lookup).
 */
export function getDemoWorkspaceSeed(): WorkspaceInsert {
  return {
    slug: 'demo',
    name: 'Demo Workspace',
    primaryColor: '#0066ff',
    senderDomain: 'example.com',
    senderName: 'Demo Mailer',
    senderEmail: 'no-reply@example.com',
    replyToEmail: 'no-reply@example.com',
    footerText: 'Demo Workspace · 123 Demo Street · Sample City',
    brandVoice: 'Neutral and professional. Adapt to your real brand on first edit.',
    wordingStyle: 'Direct, second-person address, no jargon.',
    designStyle: 'Clean, generous whitespace, system fonts.',
    imprintUrl: 'https://example.com/imprint',
    privacyUrl: 'https://example.com/privacy',
    brandKitJson: {
      version: 1,
      footer: { defaultSignature: 'Best regards,\nThe Demo Team' },
    },
  };
}

/**
 * Shop-domain defaults are no longer hardcoded per slug. If a workspace needs
 * a shop-domain mapping, set it directly in the `workspaces.shop_domain`
 * column or via the Settings-UI. Adapters that require it (kompass magic
 * links, conversion polling) read the workspace row.
 */
export const DEFAULT_SHOP_DOMAINS_BY_SLUG: Record<string, string> = {};

// ─────────────────────────────────────────────────────────────────────────────
// Workspace-Kit — strukturierte Header & Footer-Inhalte (im brandKitJson gespeichert)
// ─────────────────────────────────────────────────────────────────────────────

export interface BrandHeader {
  /** Optional: Telefonnummer im Header (z.B. "+49 89 12345-67") */
  phone?: string;
  /** Optional: Tagline / Service-Hinweis (z.B. "Versicherung in 60 Sekunden") */
  tagline?: string;
}

export interface BrandFooter {
  /**
   * Render-Modus für den Footer-Block:
   *  - 'structured' (default): Footer wird deterministisch aus footerText/legalFooterText/
   *    confidentialityNotice gerendert (siehe render-template.ts).
   *  - 'mjml': Der gesamte Footer-Bereich wird durch `customMjml` ersetzt. System-Tags
   *    ({{BROWSER_URL}}, {{IMPRINT_URL}}, {{PRIVACY_URL}}, {{UNSUBSCRIBE_URL}}) müssen
   *    vom User in den Block eingebaut werden — sie werden weiterhin vom Worker zur
   *    Send-Zeit ersetzt.
   *
   * Undefined wird wie 'structured' behandelt (Rückwärtskompatibilität für alte Workspaces).
   */
  mode?: 'structured' | 'mjml';
  /**
   * User-eigener MJML-Footer (eine oder mehrere `<mj-section>`-Blöcke). Wird nur genutzt,
   * wenn `mode === 'mjml'` UND der String nicht leer ist. Sonst Fallback auf structured.
   */
  customMjml?: string;
  /**
   * Anwaltsgeprüfter Legal-Pflicht-Block (deutsche Sprache). Enthält in einer durchgehenden
   * Zeile: Firma, Adresse, Kontakt, IHK-HRB, §34d/§34 Abs.1 GewO Registriernummer,
   * Steuer-Nr, Datenschutz-Mail, Maklerauftrag-Klausel nach §§60-62/7/8/10/14 VVG,
   * Unsubscribe-Hinweis, Haftungsausschluss. Wird in 9pt (~12px) gerendert.
   * Hat Vorrang vor companyInfo + legalRegulations + complaintBodies.
   */
  legalFooterText?: string;
  /** Englische Reserve-Variante von legalFooterText. Wird genutzt wenn Mail-Sprache 'en' ist. */
  legalFooterTextEn?: string;
  /**
   * Confidentiality-/Haftungs-Block ("Diese E-Mail und etwaige Anhänge sind vertraulich…").
   * Wird unter dem Legal-Block in 9pt (~12px) kursiv gerendert.
   */
  confidentialityNotice?: string;
  /** Englische Reserve-Variante von confidentialityNotice. */
  confidentialityNoticeEn?: string;
  /**
   * Ob der "Abmelden"-Link im Standard-Adress-Block angezeigt wird.
   * Default `true`. Für Pflicht-/Info-Mails (z.B. Maklervollmacht-Kommunikation)
   * auf `false` setzen — dann wird der UNSUBSCRIBE_URL-Tag nicht in den HTML eingebaut.
   */
  showUnsubscribe?: boolean;
  /**
   * Gesellschaftsdaten (Legacy — wird nur gerendert wenn legalFooterText leer ist):
   * Geschäftsführer · HRB · USt-ID · Sitz
   */
  companyInfo?: string;
  /**
   * Versicherungsmakler-Compliance (Legacy — wird nur gerendert wenn legalFooterText leer ist):
   * §34d GewO Erlaubnis · IHK-Vermittlerregister-Nr. · Aufsichtsbehörde · §59 VVG (Mandatsverhältnis)
   */
  legalRegulations?: string;
  /**
   * Beschwerdestellen — Pflichtangabe nach §15 VersVermV
   * (Legacy — wird nur gerendert wenn legalFooterText leer ist):
   * Versicherungsombudsmann · BaFin
   */
  complaintBodies?: string;
  /**
   * Standard-Signatur (deutsch). Wird unter der P.S.-Zeile gerendert.
   * Mehrzeilig erlaubt — `\n` wird beim Render zu `<br/>`.
   * Fallback wenn leer/undefined: hardcoded "Beste Grüße,\nIhr Team" im Renderer.
   * Ersetzt das frühere editierbare `strategy.signature`-Feld in der AdMail-UI.
   */
  defaultSignature?: string;
  /** Englische Reserve-Variante von defaultSignature. Wird genutzt wenn Mail-Sprache 'en' ist. */
  defaultSignatureEn?: string;
}

export interface BrandKit {
  version: number;
  header?: BrandHeader;
  footer?: BrandFooter;
}

/** Type-safe Reader: liest brandKitJson aus einer Workspace-Row und fällt auf {version:1} zurück. */
export function readBrandKit(json: unknown): BrandKit {
  if (json && typeof json === 'object' && 'version' in json) {
    return json as BrandKit;
  }
  return { version: 1 };
}

// ─────────────────────────────────────────────────────────────────────────────
// M365-Sender-Pool — alle Versender-Adressen die der Winitux-Tenant freigibt
// ─────────────────────────────────────────────────────────────────────────────

export interface M365Sender {
  email: string;
  /** Display-Name in der "From:"-Zeile */
  name: string;
  /** Optional: Workspace-Hint — wird beim Wechsel der Workspace vorausgewählt */
  companyId?: number;
  /** Aktiv = darf benutzt werden (deaktivierte bleiben sichtbar als Audit-Trail) */
  active: boolean;
  /** Optional: kurze Notiz (z.B. "Newsletter-Adresse", "Sales-Inbox") */
  note?: string;
}

/**
 * Default-Pool — leer im Plugin-Build. Absender-Mailboxen werden in den Einstellungen
 * unter „M365 / Versand“ gepflegt (`app_settings.m365_senders`).
 * Der M365-Adapter ist nur aktiv, wenn der Pool mindestens einen aktiven
 * Sender enthält UND M365_TENANT_ID/CLIENT_ID/CLIENT_SECRET gesetzt sind.
 */
export const DEFAULT_M365_SENDERS: M365Sender[] = [];

/**
 * System-Prompt für die Hero-Bild-Generierung.
 *
 * Wird vom `buildPrompt()` in `hero-image.ts` geladen, gefiltert (Kommentare/leere Zeilen raus)
 * und nach dem User-`image_brief` als Style-Fragmente angehängt.
 *
 * Verfügbare Platzhalter: `{BRAND_PRIMARY_COLOR}`, `{BRAND_NAME}` — werden zur Build-Zeit ersetzt.
 *
 * Modell-Hinweis: für `openai/gpt-5.4-image-2` (rendert Text und Logos sauber) optimiert.
 * Text im Bild ist erlaubt — Stil ist USE-CASE-adaptiv (siehe Kommentar-Block im Prompt).
 */
export const DEFAULT_SYSTEM_PROMPT_IMAGE = `# Hero-Bild-Stil — wird an den Image-Brief angehängt
# Modell: openai/gpt-5.4-image-2 (rendert Text & Logos sauber im Bild)
# Eine Zeile pro Style-Fragment. Zeilen mit '#' sind Kommentare und werden ignoriert.
# Platzhalter: {BRAND_PRIMARY_COLOR}, {BRAND_NAME}
#
# Text-im-Bild — adaptiv nach Use-Case (das Modell entscheidet anhand des image_brief):
#   • Sale / Promo / Deadline   → plakativer Display-Text, oversize sans-serif, hoher Kontrast
#   • Editorial / Story / News  → prominente Magazin-Headline, ruhige Typo, Drittel-Linie
#   • Service / Information     → dezente Caption (max. 3-4 Wörter), kleine Typo, untere Bildkante
#   • Brief sagt explizit "kein Text" → clean photography ohne Schrift
# Wenn der image_brief konkreten Wortlaut vorgibt: übernimm ihn 1:1 — Rechtschreibung kritisch.
#
# Negative-Prompts werden separat gesetzt (NEGATIVE_PROMPT in hero-image.ts).

editorial photography style, soft natural lighting, modern and approachable composition
premium magazine aesthetic, professional but warm tone
shallow depth of field, sharp focus on subject, cinematic framing
subtle accent color {BRAND_PRIMARY_COLOR} integrated naturally into wardrobe, props or background
on-image text only when the brief specifies — match style to use-case (display for promo, editorial for story, caption for service)
typography: clean modern sans-serif, perfect kerning, flawless spelling, high legibility
text placement: upper-third or lower-third, never crossing faces or product key details
no logos unless the brief names "{BRAND_NAME}" explicitly
photoreal, natural color grading, no plastic skin, no AI artifacts`;

export const DEFAULT_SETTINGS: Record<string, unknown> = {
  system_prompt_generate: DEFAULT_SYSTEM_PROMPT_GENERATE,
  system_prompt_suggest: DEFAULT_SYSTEM_PROMPT_SUGGEST,
  system_prompt_suggest_utm: DEFAULT_SYSTEM_PROMPT_SUGGEST_UTM,
  system_prompt_image: DEFAULT_SYSTEM_PROMPT_IMAGE,
  m365_senders: DEFAULT_M365_SENDERS,
};
