/**
 * Merges mandate core fields with billing settings for SysAdmin mandate forms.
 * Billing is stored separately (BillingSettings); attributes API only exposes Mandate model fields.
 */

import type { AttributeDefinition } from '../components/FormGenerator/FormGeneratorForm';
import type { BillingSettings, BillingSettingsUpdate } from '../api/billingApi';

export const mandateBillingFieldNames = [
  'billingModel',
  'defaultUserCredit',
  'warningThresholdPercent',
  'notifyOnWarning',
  'notifyEmails',
] as const;

export type MandateBillingFieldName = (typeof mandateBillingFieldNames)[number];

/** FormGenerator attribute definitions for mandate billing (appended after /api/attributes/Mandate). */
export function getMandateBillingFormAttributes(): AttributeDefinition[] {
  return [
    {
      name: 'billingModel',
      type: 'select',
      label: 'Abrechnungsmodell',
      description: 'Vorauszahlung auf Mandanten- oder Benutzerkonten.',
      required: false,
      default: 'PREPAY_MANDATE',
      editable: true,
      order: 100,
      options: [
        { value: 'PREPAY_MANDATE', label: 'Vorauszahlung (Mandanten-Guthaben)' },
        { value: 'PREPAY_USER', label: 'Vorauszahlung pro Benutzer' },
      ],
    },
    {
      name: 'defaultUserCredit',
      type: 'float',
      label: 'Startguthaben neuem Benutzer (CHF)',
      description:
        'Nur relevant bei PREPAY_USER (u. a. Root-Mandant). Sonst meist 0.',
      required: false,
      default: 0,
      editable: true,
      order: 101,
    },
    {
      name: 'warningThresholdPercent',
      type: 'float',
      label: 'Warnschwelle (%)',
      description: 'Benachrichtigung, wenn das Guthaben unter diesem Prozentsatz fällt.',
      required: false,
      default: 10,
      editable: true,
      order: 102,
    },
    {
      name: 'notifyOnWarning',
      type: 'checkbox',
      label: 'Bei Warnung benachrichtigen',
      required: false,
      default: true,
      editable: true,
      order: 103,
    },
    {
      name: 'notifyEmails',
      type: 'textarea',
      label: 'Benachrichtigungs-E-Mails',
      description: 'Eine Adresse pro Zeile oder durch Komma/Semikolon getrennt.',
      required: false,
      default: '',
      editable: true,
      order: 104,
      minRows: 2,
      maxRows: 6,
    },
  ];
}

function _parseNotifyEmailsInput(val: unknown): string[] {
  if (Array.isArray(val)) {
    return val.map(String).map(s => s.trim()).filter(Boolean);
  }
  if (typeof val !== 'string') {
    return [];
  }
  return val
    .split(/[\n,;]+/)
    .map(s => s.trim())
    .filter(Boolean);
}

/** Build initial form values: mandate row + billing settings (notifyEmails as multi-line string). */
function _normalizeBillingModelUi(raw: string | undefined): BillingSettings['billingModel'] {
  if (raw === 'PREPAY_USER') return 'PREPAY_USER';
  return 'PREPAY_MANDATE';
}

export function mergeBillingIntoMandateFormData(
  mandate: Record<string, unknown>,
  settings: BillingSettings | null
): Record<string, unknown> {
  if (!settings) {
    return {
      ...mandate,
      billingModel: 'PREPAY_MANDATE',
      defaultUserCredit: 0,
      warningThresholdPercent: 10,
      notifyOnWarning: true,
      notifyEmails: '',
    };
  }
  return {
    ...mandate,
    billingModel: _normalizeBillingModelUi(settings.billingModel),
    defaultUserCredit: Number(settings.defaultUserCredit ?? 0),
    warningThresholdPercent: Number(settings.warningThresholdPercent ?? 10),
    notifyOnWarning: settings.notifyOnWarning ?? true,
    notifyEmails: (settings.notifyEmails || []).join('\n'),
  };
}

/** Split form submit payload into mandate PUT body and billing POST body. */
export function splitMandateAndBillingFromForm(
  formData: Record<string, unknown>
): { mandatePayload: Record<string, unknown>; billingUpdate: BillingSettingsUpdate } {
  const mandatePayload: Record<string, unknown> = {};
  if ('name' in formData) mandatePayload.name = formData.name;
  if ('label' in formData) mandatePayload.label = formData.label;
  if ('enabled' in formData) mandatePayload.enabled = formData.enabled;

  const billingUpdate: BillingSettingsUpdate = {};
  if ('billingModel' in formData && formData.billingModel !== undefined && formData.billingModel !== '') {
    billingUpdate.billingModel = formData.billingModel as BillingSettingsUpdate['billingModel'];
  }
  {
    const raw = formData.defaultUserCredit;
    const n =
      raw === undefined || raw === null || raw === ''
        ? 0
        : Number(raw);
    if (!Number.isNaN(n)) {
      billingUpdate.defaultUserCredit = n;
    }
  }
  if (
    'warningThresholdPercent' in formData &&
    formData.warningThresholdPercent !== undefined &&
    formData.warningThresholdPercent !== ''
  ) {
    const n = Number(formData.warningThresholdPercent);
    if (!Number.isNaN(n)) billingUpdate.warningThresholdPercent = n;
  }
  if ('notifyOnWarning' in formData) {
    billingUpdate.notifyOnWarning = Boolean(formData.notifyOnWarning);
  }
  if ('notifyEmails' in formData) {
    billingUpdate.notifyEmails = _parseNotifyEmailsInput(formData.notifyEmails);
  }

  return { mandatePayload, billingUpdate };
}
