/**
 * Billing Admin Page
 * 
 * Admin-Seite für Billing-Verwaltung (SysAdmin only).
 * - Settings verwalten
 * - Guthaben aufladen
 * - Konten übersicht
 */

import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useBillingAdmin, type BillingSettings, type AccountSummary, type MandateUserSummary } from '../../hooks/useBilling';
import type { CheckoutCreateRequest } from '../../api/billingApi';
import { useUserMandates, type Mandate as UserMandateRow } from '../../hooks/useUserMandates';
import { useCurrentUser } from '../../hooks/useUsers';
import { SubscriptionTab } from './SubscriptionTab';
import api from '../../api';
import { getUserDataCache } from '../../utils/userCache';
import { useLanguage } from '../../providers/language/LanguageContext';
import styles from './Billing.module.css';

type AdminTabType = 'subscription' | 'settings' | 'credit';

const _formatCurrency = (amount: number) => {
  return new Intl.NumberFormat('de-CH', {
    style: 'currency',
    currency: 'CHF'
  }).format(amount);
};

const _mandateDisplayLabel = (m: UserMandateRow): string => {
  return m.label || m.name || m.id;
};

// ============================================================================
// MANDATE SELECTOR
// ============================================================================

interface MandateSelectorProps {
  mandates: UserMandateRow[];
  loading: boolean;
  selectedMandateId: string | null;
  onSelect: (mandateId: string) => void;
}

const MandateSelector: React.FC<MandateSelectorProps> = ({
  mandates,
  loading,
  selectedMandateId,
  onSelect,
}) => {
  const { t } = useLanguage();
  return (
  <div className={styles.formGroup}>
    <label>{t('Mandant auswählen')}</label>
    <select
      className={styles.select}
      value={selectedMandateId || ''}
      onChange={e => onSelect(e.target.value)}
      disabled={loading}
    >
      <option value="">{t('Mandant wählen')}</option>
      {mandates.map(mandate => (
        <option key={mandate.id} value={mandate.id}>
          {_mandateDisplayLabel(mandate)}
        </option>
      ))}
    </select>
  </div>
  );
};

// ============================================================================
// SETTINGS EDITOR
// ============================================================================

interface SettingsEditorProps {
  settings: BillingSettings | null;
  onSave: (settings: Partial<BillingSettings>) => Promise<void>;
  loading: boolean;
}

const SettingsEditor: React.FC<SettingsEditorProps> = ({ settings, onSave, loading }) => {
  const { t } = useLanguage();
  const [formData, setFormData] = useState({
    warningThresholdPercent: Number(settings?.warningThresholdPercent ?? 10),
    notifyOnWarning: settings?.notifyOnWarning ?? true,
    autoRechargeEnabled: settings?.autoRechargeEnabled ?? false,
    rechargeAmountCHF: Number(settings?.rechargeAmountCHF ?? 10),
    rechargeMaxPerMonth: Number(settings?.rechargeMaxPerMonth ?? 3),
  });
  const [saving, setSaving] = useState(false);
  const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null);
  
  useEffect(() => {
    if (settings) {
      setFormData({
        warningThresholdPercent: Number(settings.warningThresholdPercent ?? 10),
        notifyOnWarning: settings.notifyOnWarning ?? true,
        autoRechargeEnabled: settings.autoRechargeEnabled ?? false,
        rechargeAmountCHF: Number(settings.rechargeAmountCHF ?? 10),
        rechargeMaxPerMonth: Number(settings.rechargeMaxPerMonth ?? 3),
      });
    }
  }, [settings]);
  
  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setSaving(true);
    setMessage(null);
    
    try {
      await onSave(formData);
      setMessage({ type: 'success', text: t('Einstellungen gespeichert!') });
    } catch (err: any) {
      setMessage({ type: 'error', text: err.message || t('Fehler beim Speichern') });
    } finally {
      setSaving(false);
    }
  };
  
  return (
    <div className={styles.adminSection}>
      <h3>{t('Billing-Einstellungen')}</h3>
      
      {message && (
        <div className={message.type === 'success' ? styles.successMessage : styles.errorMessage}>
          {message.text}
        </div>
      )}
      
      <form onSubmit={handleSubmit}>
        <div className={styles.formRow}>
          <div className={styles.formGroup}>
            <label>{t('Warnschwelle (%)')}</label>
            <input 
              type="number"
              className={styles.input}
              value={formData.warningThresholdPercent}
              onChange={(e) => setFormData(prev => ({ ...prev, warningThresholdPercent: Number(e.target.value) }))}
              min="0"
              max="100"
              step="1"
            />
          </div>
        </div>
        
        <div className={styles.formRow}>
          <div className={styles.formGroup}>
            <label>&nbsp;</label>
            <label style={{ display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' }}>
              <input 
                type="checkbox"
                checked={formData.notifyOnWarning}
                onChange={(e) => setFormData(prev => ({ ...prev, notifyOnWarning: e.target.checked }))}
              />
              {t('Bei Warnung benachrichtigen')}
            </label>
          </div>
        </div>

        <div className={styles.formRow}>
          <div className={styles.formGroup} style={{ gridColumn: '1 / -1' }}>
            <label style={{ display: 'flex', alignItems: 'center', gap: '8px', cursor: 'pointer' }}>
              <input
                type="checkbox"
                checked={formData.autoRechargeEnabled}
                onChange={(e) => setFormData(prev => ({ ...prev, autoRechargeEnabled: e.target.checked }))}
              />
              {t('Auto-Nachladung (KI-Guthaben bei niedrigem Stand)')}
            </label>
          </div>
        </div>
        {formData.autoRechargeEnabled && (
          <div className={styles.formRow}>
            <div className={styles.formGroup}>
              <label>{t('Betrag pro Nachladung (CHF)')}</label>
              <input
                type="number"
                className={styles.input}
                value={formData.rechargeAmountCHF}
                onChange={(e) =>
                  setFormData(prev => ({ ...prev, rechargeAmountCHF: Number(e.target.value) }))
                }
                min="0.01"
                step="0.01"
              />
            </div>
            <div className={styles.formGroup}>
              <label>{t('Max. Nachladungen / Monat')}</label>
              <input
                type="number"
                className={styles.input}
                value={formData.rechargeMaxPerMonth}
                onChange={(e) =>
                  setFormData(prev => ({ ...prev, rechargeMaxPerMonth: Math.max(0, Math.floor(Number(e.target.value))) }))
                }
                min="0"
                step="1"
              />
            </div>
          </div>
        )}
        
        <button 
          type="submit" 
          className={`${styles.button} ${styles.buttonPrimary}`}
          disabled={saving || loading}
        >
          {saving ? t('Speichern…') : t('Einstellungen speichern')}
        </button>
      </form>
    </div>
  );
};

// ============================================================================
// CREDIT ADDER
// ============================================================================

interface CreditAdderProps {
  onAddCredit: (userId: string | undefined, amount: number, description: string) => Promise<any>;
}

const CreditAdder: React.FC<CreditAdderProps> = ({ onAddCredit }) => {
  const { t } = useLanguage();
  const [amount, setAmount] = useState<string>('');
  const [description, setDescription] = useState<string>(t('Manuelle Buchung durch Admin'));
  const [saving, setSaving] = useState(false);
  const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null);
  
  const _handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    const numAmount = parseFloat(amount);
    if (!numAmount || numAmount === 0) {
      setMessage({ type: 'error', text: t('Betrag darf nicht null sein') });
      return;
    }
    
    setSaving(true);
    setMessage(null);
    
    try {
      await onAddCredit(undefined, numAmount, description);
      const label = numAmount > 0
        ? t('{betrag} erfolgreich gutgeschrieben.', { betrag: _formatCurrency(numAmount) })
        : t('{betrag} erfolgreich abgezogen.', { betrag: _formatCurrency(Math.abs(numAmount)) });
      setMessage({ type: 'success', text: label });
      setAmount('');
    } catch (err: any) {
      setMessage({ type: 'error', text: err.message || t('Fehler bei der Buchung') });
    } finally {
      setSaving(false);
    }
  };
  
  return (
    <div className={styles.adminSection}>
      <h3>{t('Guthaben manuell verwalten')}</h3>
      
      {message && (
        <div className={message.type === 'success' ? styles.successMessage : styles.errorMessage}>
          {message.text}
        </div>
      )}
      
      <form onSubmit={_handleSubmit}>
        <div className={styles.formRow}>
          <div className={styles.formGroup}>
            <label>{t('Betrag (CHF)')}</label>
            <input
              type="number"
              className={styles.input}
              value={amount}
              onChange={(e) => setAmount(e.target.value)}
              placeholder={t('z.B. 50 oder -20')}
              step="0.01"
              required
            />
          </div>
          <div className={styles.formGroup}>
            <label>{t('Beschreibung')}</label>
            <input
              type="text"
              className={styles.input}
              value={description}
              onChange={(e) => setDescription(e.target.value)}
              placeholder={t('Beschreibung der Gutschrift')}
            />
          </div>
        </div>
        
        <button 
          type="submit" 
          className={`${styles.button} ${styles.buttonPrimary}`}
          disabled={saving || !amount}
        >
          {saving ? t('Wird verbucht…') : (parseFloat(amount) < 0 ? t('Guthaben abziehen') : t('Guthaben aufladen'))}
        </button>
      </form>
    </div>
  );
};

// ============================================================================
// ACCOUNTS OVERVIEW
// ============================================================================

interface AccountsOverviewProps {
  accounts: AccountSummary[];
  /** Kept for call-site compatibility; only mandate pool accounts are shown. */
  users?: MandateUserSummary[];
  loading: boolean;
}

const AccountsOverview: React.FC<AccountsOverviewProps> = ({ accounts, loading }) => {
  const { t } = useLanguage();
  const formatCurrency = (amount: number) => {
    return new Intl.NumberFormat('de-CH', {
      style: 'currency',
      currency: 'CHF'
    }).format(amount);
  };

  const poolAccounts = useMemo(() => accounts.filter((a) => !a.userId), [accounts]);

  if (loading) {
    return <div className={styles.loadingPlaceholder}>{t('Lade Konten…')}</div>;
  }
  
  if (accounts.length === 0) {
    return <div className={styles.noData}>{t('Keine Konten vorhanden')}</div>;
  }

  if (poolAccounts.length === 0) {
    return <div className={styles.noData}>{t('Kein Mandanten-Konto vorhanden')}</div>;
  }
  
  return (
    <div className={styles.adminSection}>
      <h3>{t('Konten')}</h3>
      <div className={styles.accountsGrid}>
        {poolAccounts.map((account) => (
          <div key={account.id} className={styles.accountCard}>
            <h4>{t('Mandanten-Konto')}</h4>
            <div className={styles.accountInfo}>
              <span>{t('Guthaben:')} <strong>{formatCurrency(account.balance)}</strong></span>
              <span>{t('Status:')} {account.enabled ? t('Aktiv') : t('Deaktiviert')}</span>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
};

// ============================================================================
// MANDATE ADMIN — STRIPE TOP-UP (same URL as SysAdmin billing admin)
// ============================================================================

interface MandateStripeTopUpProps {
  mandateId: string;
  createCheckout: (
    checkoutRequest: CheckoutCreateRequest,
    targetMandateId?: string
  ) => Promise<{ redirectUrl?: string } | null>;
}

const MandateStripeTopUp: React.FC<MandateStripeTopUpProps> = ({ mandateId, createCheckout }) => {
  const { t } = useLanguage();
  const [amount, setAmount] = useState('');
  const [busy, setBusy] = useState(false);
  const [localMsg, setLocalMsg] = useState<string | null>(null);

  const _handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    const n = parseFloat(amount);
    if (!n || n <= 0) {
      setLocalMsg('Betrag muss positiv sein');
      return;
    }
    setBusy(true);
    setLocalMsg(null);
    try {
      const currentUser = getUserDataCache();
      const currentUrl = new URL(window.location.href);
      currentUrl.searchParams.delete('success');
      currentUrl.searchParams.delete('canceled');
      currentUrl.searchParams.delete('session_id');
      currentUrl.hash = '';
      const returnUrl = `${currentUrl.origin}${currentUrl.pathname}${currentUrl.search}`;
      const result = await createCheckout(
        { userId: currentUser?.id, amount: n, returnUrl },
        mandateId
      );
      if (result?.redirectUrl) {
        window.location.href = result.redirectUrl;
      }
    } catch (err: unknown) {
      const msg = err instanceof Error ? err.message : t('Checkout fehlgeschlagen');
      setLocalMsg(msg);
      setBusy(false);
    }
  };

  return (
    <div className={styles.adminSection}>
      <h3>{t('Guthaben via Stripe aufladen')}</h3>
      <p style={{ fontSize: '13px', color: 'var(--text-secondary, #64748b)', marginTop: 0 }}>
        {t('Sie werden zu Stripe weitergeleitet. Nach erfolgreicher Zahlung kehren Sie hierher zurück.')}
      </p>
      {localMsg && <div className={styles.errorMessage}>{localMsg}</div>}
      <form onSubmit={_handleSubmit}>
        <div className={styles.formRow}>
          <div className={styles.formGroup}>
            <label>{t('Betrag (CHF)')}</label>
            <input
              type="number"
              className={styles.input}
              value={amount}
              onChange={e => setAmount(e.target.value)}
              placeholder={t('z. B. 50 oder -20')}
              min="0.01"
              step="0.01"
              required
            />
          </div>
        </div>
        <button
          type="submit"
          className={`${styles.button} ${styles.buttonPrimary}`}
          disabled={busy || !amount}
        >
          {busy ? t('Weiterleitung…') : t('Mit Stripe bezahlen')}
        </button>
      </form>
    </div>
  );
};

// ============================================================================
// MAIN COMPONENT
// ============================================================================

export const BillingAdmin: React.FC = () => {
  const { t } = useLanguage();
  const [searchParams, setSearchParams] = useSearchParams();
  const { user: currentUser } = useCurrentUser();
  const isSysAdmin = currentUser?.isSysAdmin === true;

  const [selectedMandateId, setSelectedMandateId] = useState<string | null>(
    searchParams.get('mandate') || null
  );
  const [mandateList, setMandateList] = useState<UserMandateRow[]>([]);
  const [mandatesLoading, setMandatesLoading] = useState(true);

  const { fetchMandates } = useUserMandates();
  const {
    settings,
    accounts,
    users,
    loading,
    saveSettings,
    addCredit,
    loadAccounts,
    createCheckout,
  } = useBillingAdmin(selectedMandateId || undefined);
  
  const handleMandateSelect = (mandateId: string) => {
    setSelectedMandateId(mandateId || null);
  };
  
  const handleSaveSettings = useCallback(async (settingsUpdate: Partial<BillingSettings>) => {
    if (!selectedMandateId) return;
    await saveSettings(settingsUpdate);
  }, [selectedMandateId, saveSettings]);
  
  const _handleAddCredit = useCallback(async (userId: string | undefined, amount: number, description: string) => {
    if (!selectedMandateId) throw new Error('Mandant nicht ausgewählt');
    const result = await addCredit({ userId, amount, description });
    if (!result) throw new Error('Gutschrift konnte nicht erstellt werden');
    await loadAccounts();
    return result;
  }, [selectedMandateId, addCredit, loadAccounts, t]);

  useEffect(() => {
    let cancelled = false;
    (async () => {
      setMandatesLoading(true);
      try {
        const data = await fetchMandates();
        if (!cancelled) {
          setMandateList(Array.isArray(data) ? data : []);
        }
      } finally {
        if (!cancelled) setMandatesLoading(false);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [fetchMandates]);

  useEffect(() => {
    if (!isSysAdmin && mandateList.length === 1 && selectedMandateId === null) {
      setSelectedMandateId(mandateList[0].id);
    }
  }, [isSysAdmin, mandateList, selectedMandateId]);

  const [stripeReturnMessage, setStripeReturnMessage] = useState<{
    type: 'success' | 'error';
    text: string;
  } | null>(null);
  const successParam = searchParams.get('success');
  const canceledParam = searchParams.get('canceled');
  const sessionIdParam = searchParams.get('session_id');

  const _initialAdminTab = (searchParams.get('tab') as AdminTabType) || 'subscription';
  const [adminTab, setAdminTab] = useState<AdminTabType>(
    ['subscription', 'settings', 'credit'].includes(_initialAdminTab) ? _initialAdminTab : 'subscription'
  );
  const [subscriptionTabKey, setSubscriptionTabKey] = useState(0);

  useEffect(() => {
    if (adminTab === 'subscription' || searchParams.get('tab') === 'subscription') return;

    let cancelled = false;

    const _confirmCheckoutIfNeeded = async () => {
      if (successParam !== 'true') {
        if (canceledParam === 'true' && !cancelled) {
          setStripeReturnMessage({ type: 'error', text: t('Zahlung abgebrochen.') });
        }
        return;
      }

      if (!sessionIdParam) {
        if (!cancelled) {
          setStripeReturnMessage({
            type: 'success',
            text: t('Zahlung erfolgreich. Guthaben wird gutgeschrieben.'),
          });
        }
        if (selectedMandateId) await loadAccounts(selectedMandateId);
        return;
      }

      try {
        await api.post('/api/billing/checkout/confirm', { sessionId: sessionIdParam });
        if (!cancelled) {
          setStripeReturnMessage({
            type: 'success',
            text: t('Zahlung erfolgreich. Guthaben wurde verbucht.'),
          });
        }
      } catch (err: unknown) {
        const detail = (err as { response?: { data?: { detail?: string } } })?.response?.data?.detail;
        if (!cancelled) {
          setStripeReturnMessage({
            type: 'error',
            text:
              detail ||
              t('Zahlung erfolgreich, aber Verbuchung konnte nicht bestätigt werden.'),
          });
        }
      } finally {
        if (selectedMandateId) await loadAccounts(selectedMandateId);
      }
    };

    _confirmCheckoutIfNeeded();

    return () => {
      cancelled = true;
    };
  }, [adminTab, successParam, canceledParam, sessionIdParam, selectedMandateId, loadAccounts, t]);

  const _clearStripeParams = useCallback(() => {
    searchParams.delete('success');
    searchParams.delete('canceled');
    searchParams.delete('session_id');
    searchParams.delete('mandate');
    setSearchParams(searchParams, { replace: true });
    setStripeReturnMessage(null);
  }, [searchParams, setSearchParams]);

  const showStripeForMandateAdmin = !!selectedMandateId && !!settings;

  const _tabStyle = (isActive: boolean) => ({
    padding: '8px 16px',
    textDecoration: 'none',
    borderRadius: '4px',
    backgroundColor: isActive ? 'var(--primary-color, #F25843)' : 'transparent',
    color: isActive ? 'white' : 'var(--color-text, #e0e0e0)',
    fontWeight: isActive ? 600 : 400,
    cursor: 'pointer',
    border: 'none',
    fontSize: '14px',
  });

  return (
    <div className={styles.billingDashboard}>
      <header className={styles.pageHeader}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
          <div>
            <h1>{t('Abrechnung')}</h1>
            <p className={styles.subtitle}>
              {t('Abonnement, Einstellungen und Guthaben pro Mandant')}
            </p>
          </div>
        </div>
      </header>

      {stripeReturnMessage && (
        <div
          className={
            stripeReturnMessage.type === 'success' ? styles.successMessage : styles.errorMessage
          }
          style={{ marginBottom: '1rem' }}
        >
          <div style={{ display: 'flex', justifyContent: 'space-between', gap: '12px', alignItems: 'center' }}>
            <span>{stripeReturnMessage.text}</span>
            <button type="button" className={styles.button} onClick={_clearStripeParams}>
              {t('OK')}
            </button>
          </div>
        </div>
      )}

      <section className={styles.section}>
        <MandateSelector
          mandates={mandateList}
          loading={mandatesLoading}
          selectedMandateId={selectedMandateId}
          onSelect={handleMandateSelect}
        />
      </section>

      {selectedMandateId ? (
        <>
          <nav style={{
            display: 'flex',
            gap: '8px',
            marginBottom: '24px',
            borderBottom: '1px solid var(--color-border, #333)',
            paddingBottom: '8px',
          }}>
            <button onClick={() => { setAdminTab('subscription'); setSubscriptionTabKey(k => k + 1); }} style={_tabStyle(adminTab === 'subscription')}>
              {t('Abonnement')}
            </button>
            <button onClick={() => setAdminTab('settings')} style={_tabStyle(adminTab === 'settings')}>
              {t('Einstellungen')}
            </button>
            <button onClick={() => setAdminTab('credit')} style={_tabStyle(adminTab === 'credit')}>
              {t('Guthaben aufladen')}
            </button>
          </nav>

          {adminTab === 'settings' && (
            <SettingsEditor
              settings={settings}
              onSave={handleSaveSettings}
              loading={loading}
            />
          )}

          {adminTab === 'credit' && (
            <>
              {isSysAdmin && (
                <CreditAdder
                  onAddCredit={_handleAddCredit}
                />
              )}

              {showStripeForMandateAdmin && (
                <MandateStripeTopUp mandateId={selectedMandateId} createCheckout={createCheckout} />
              )}

              <AccountsOverview accounts={accounts} users={users} loading={loading} />
            </>
          )}

          {adminTab === 'subscription' && (
            <SubscriptionTab key={subscriptionTabKey} mandateId={selectedMandateId} />
          )}
        </>
      ) : (
        <div className={styles.noData}>{t('Bitte wählen Sie einen Mandanten aus.')}</div>
      )}
    </div>
  );
};

export default BillingAdmin;
