/**
 * BillingDataView
 * 
 * Unified billing page with internal tabs:
 * - Tab "Übersicht": Balance cards + Usage summary for the user
 * - Tab "Statistik": Dashboard with time-series charts and breakdowns
 * - Tab "Transaktionen": Transaction table with FormGeneratorTable
 */

import React, { useState, useEffect, useMemo, useCallback } from 'react';
import { FormGeneratorTable, ColumnConfig } from '../../components/FormGenerator/FormGeneratorTable';
import { FormGeneratorReport } from '../../components/FormGenerator/FormGeneratorReport';
import type { ReportSection, ReportFilterState, ReportChartDataPoint } from '../../components/FormGenerator/FormGeneratorReport';
import api from '../../api';
import { useBilling, type BillingBalance } from '../../hooks/useBilling';
import { UserTransaction } from '../../api/billingApi';
import styles from './Billing.module.css';

// ============================================================================
// HELPER: Currency formatter
// ============================================================================

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

// ============================================================================
// TYPES
// ============================================================================

interface ViewStatistics {
  totalCost: number;
  transactionCount: number;
  costByProvider: Record<string, number>;
  costByModel: Record<string, number>;
  costByFeature: Record<string, number>;
  costByMandate: Record<string, number>;
  timeSeries: Array<{ date: string; cost: number; count: number }>;
}

// ============================================================================
// BALANCE CARD COMPONENT
// ============================================================================

interface BalanceCardProps {
  balance: BillingBalance;
}

const BalanceCard: React.FC<BalanceCardProps> = ({ balance }) => {
  const _getBillingModelLabel = (model: string) => {
    switch (model) {
      case 'PREPAY_MANDATE': return 'Prepaid (Mandant)';
      case 'PREPAY_USER': return 'Prepaid (Benutzer)';
      case 'CREDIT_POSTPAY': return 'Kredit';
      case 'UNLIMITED': return 'Unlimited';
      default: return model;
    }
  };
  
  return (
    <div className={`${styles.balanceCard} ${balance.isWarning ? styles.warning : ''}`}>
      <div className={styles.balanceHeader}>
        <h3 className={styles.mandateName}>{balance.mandateName}</h3>
        <span className={styles.billingModel}>{_getBillingModelLabel(balance.billingModel)}</span>
      </div>
      <div className={styles.balanceAmount}>
        {_formatCurrency(balance.balance)}
      </div>
      {balance.isWarning && (
        <div className={styles.warningBadge}>
          Niedriges Guthaben
        </div>
      )}
    </div>
  );
};

// ============================================================================
// TAB NAVIGATION COMPONENT
// ============================================================================

type TabType = 'overview' | 'statistics' | 'transactions';

interface TabNavProps {
  activeTab: TabType;
  onTabChange: (tab: TabType) => void;
}

const TabNav: React.FC<TabNavProps> = ({ activeTab, onTabChange }) => {
  const _navLinkStyle = (isActive: boolean) => ({
    padding: '8px 16px',
    textDecoration: 'none',
    borderRadius: '4px',
    backgroundColor: isActive ? 'var(--color-primary, #3b82f6)' : 'transparent',
    color: isActive ? 'white' : 'var(--color-text, #e0e0e0)',
    fontWeight: isActive ? 600 : 400,
    cursor: 'pointer',
    border: 'none',
    fontSize: '14px',
  });

  return (
    <nav style={{
      display: 'flex',
      gap: '8px',
      marginBottom: '24px',
      borderBottom: '1px solid var(--color-border, #333)',
      paddingBottom: '8px'
    }}>
      <button onClick={() => onTabChange('overview')} style={_navLinkStyle(activeTab === 'overview')}>
        Übersicht
      </button>
      <button onClick={() => onTabChange('statistics')} style={_navLinkStyle(activeTab === 'statistics')}>
        Statistik
      </button>
      <button onClick={() => onTabChange('transactions')} style={_navLinkStyle(activeTab === 'transactions')}>
        Transaktionen
      </button>
    </nav>
  );
};

// ============================================================================
// HELPERS: Convert viewStats to ReportSection arrays
// ============================================================================

function _recordToChartData(record: Record<string, number>): ReportChartDataPoint[] {
  return Object.entries(record)
    .sort((a, b) => b[1] - a[1])
    .map(([key, value]) => ({ key: key || '—', value }));
}

function _buildOverviewSections(viewStats: ViewStatistics): ReportSection[] {
  const topProvider = Object.entries(viewStats.costByProvider).sort((a, b) => b[1] - a[1])[0];
  const topModel = Object.entries(viewStats.costByModel || {}).sort((a, b) => b[1] - a[1])[0];
  const topFeature = Object.entries(viewStats.costByFeature).sort((a, b) => b[1] - a[1])[0];

  return [
    {
      type: 'kpiGrid',
      items: [
        {
          label: 'Gesamtkosten',
          value: _formatCurrency(viewStats.totalCost),
          subtitle: `${viewStats.transactionCount} Transaktionen`
        },
        {
          label: 'Anbieter',
          value: Object.keys(viewStats.costByProvider).length,
          subtitle: topProvider ? `Top: ${topProvider[0]}` : 'Keine Nutzung'
        },
        {
          label: 'Modelle',
          value: Object.keys(viewStats.costByModel || {}).length,
          subtitle: topModel ? `Top: ${topModel[0]}` : 'Keine Nutzung'
        },
        {
          label: 'Features',
          value: Object.keys(viewStats.costByFeature).length,
          subtitle: topFeature ? `Top: ${topFeature[0]}` : 'Keine Nutzung'
        }
      ]
    },
    {
      type: 'horizontalBar',
      title: 'Kosten nach Anbieter',
      data: _recordToChartData(viewStats.costByProvider),
      formatValue: _formatCurrency,
      span: 'half' as const
    },
    {
      type: 'horizontalBar',
      title: 'Kosten nach Modell',
      data: _recordToChartData(viewStats.costByModel || {}),
      formatValue: _formatCurrency,
      span: 'half' as const
    },
    {
      type: 'horizontalBar',
      title: 'Kosten nach Feature',
      data: _recordToChartData(viewStats.costByFeature),
      formatValue: _formatCurrency,
      span: 'half' as const
    }
  ];
}

function _buildStatisticsSections(viewStats: ViewStatistics): ReportSection[] {
  // Convert timeSeries to barChart data
  const timeSeriesData: ReportChartDataPoint[] = viewStats.timeSeries.map(ts => ({
    key: ts.date,
    value: ts.cost
  }));

  const avgCost = viewStats.transactionCount > 0 
    ? viewStats.totalCost / viewStats.transactionCount 
    : 0;

  return [
    {
      type: 'barChart',
      title: 'Kostenentwicklung',
      data: timeSeriesData,
      formatValue: _formatCurrency,
      span: 'full' as const
    },
    {
      type: 'pieChart',
      title: 'Verteilung nach Anbieter',
      data: _recordToChartData(viewStats.costByProvider),
      formatValue: _formatCurrency,
      donut: true,
      span: 'half' as const
    },
    {
      type: 'pieChart',
      title: 'Verteilung nach Modell',
      data: _recordToChartData(viewStats.costByModel || {}),
      formatValue: _formatCurrency,
      donut: true,
      span: 'half' as const
    },
    {
      type: 'pieChart',
      title: 'Verteilung nach Feature',
      data: _recordToChartData(viewStats.costByFeature),
      formatValue: _formatCurrency,
      donut: true,
      span: 'half' as const
    },
    {
      type: 'horizontalBar',
      title: 'Kosten nach Mandant',
      data: _recordToChartData(viewStats.costByMandate),
      formatValue: _formatCurrency,
      span: 'half' as const
    },
    {
      type: 'table',
      title: 'Zusammenfassung',
      span: 'half' as const,
      columns: [
        { key: 'metric', label: 'Kennzahl' },
        { key: 'value', label: 'Wert', align: 'right' as const }
      ],
      rows: [
        { metric: 'Gesamtkosten', value: _formatCurrency(viewStats.totalCost) },
        { metric: 'Transaktionen', value: String(viewStats.transactionCount) },
        { metric: 'Durchschnitt / Transaktion', value: _formatCurrency(avgCost) },
        { metric: 'Anbieter', value: String(Object.keys(viewStats.costByProvider).length) },
        { metric: 'Modelle', value: String(Object.keys(viewStats.costByModel || {}).length) },
        { metric: 'Features', value: String(Object.keys(viewStats.costByFeature).length) },
        { metric: 'Mandanten', value: String(Object.keys(viewStats.costByMandate).length) }
      ]
    }
  ];
}

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

export const BillingDataView: React.FC = () => {
  const [activeTab, setActiveTab] = useState<TabType>('overview');
  
  // Scope filter: 'personal' | 'all' | mandateId
  const [selectedScope, setSelectedScope] = useState<string>('personal');
  
  // Dashboard state (for Overview tab)
  const { 
    balances, 
    loading: dashboardLoading, 
  } = useBilling();

  // All user balances (for admin overview cards)
  const [allUserBalances, setAllUserBalances] = useState<any[]>([]);
  const [allUserBalancesLoading, setAllUserBalancesLoading] = useState(false);
  
  // Statistics state (shared by Overview and Statistics tabs)
  const [viewStats, setViewStats] = useState<ViewStatistics | null>(null);
  const [statsLoading, setStatsLoading] = useState(false);
  
  // Transactions state (for Transactions tab)
  const [transactions, setTransactions] = useState<UserTransaction[]>([]);
  const [transactionsLoading, setTransactionsLoading] = useState(false);
  const [transactionsError, setTransactionsError] = useState<string | null>(null);
  const [transactionsPagination, setTransactionsPagination] = useState<any>(null);

  // Load all user balances for admin overview
  const _loadAllUserBalances = useCallback(async () => {
    try {
      setAllUserBalancesLoading(true);
      const response = await api.get('/api/billing/view/users/balances');
      setAllUserBalances(Array.isArray(response.data) ? response.data : []);
    } catch {
      setAllUserBalances([]);
    } finally {
      setAllUserBalancesLoading(false);
    }
  }, []);

  // Load aggregated statistics from the view/statistics route
  const _loadViewStatistics = useCallback(async (period: string, year: number, month?: number) => {
    try {
      setStatsLoading(true);
      const params: any = { period, year };
      if (period === 'day' && month) {
        params.month = month;
      }
      // Apply scope filter
      if (selectedScope === 'personal') {
        params.scope = 'personal';
      } else if (selectedScope !== 'all') {
        params.scope = 'mandate';
        params.mandateId = selectedScope;
      } else {
        params.scope = 'all';
      }
      const response = await api.get('/api/billing/view/statistics', { params });
      setViewStats(response.data);
    } catch (err: any) {
      console.error('Failed to load statistics:', err);
      setViewStats(null);
    } finally {
      setStatsLoading(false);
    }
  }, [selectedScope]);

  // Handle filter changes from FormGeneratorReport (user changes period/year/month)
  const _handleStatsFilterChange = useCallback((filterState: ReportFilterState) => {
    const period = filterState.period || 'month';
    const year = filterState.year || new Date().getFullYear();
    const month = filterState.month;
    _loadViewStatistics(period, year, month);
  }, [_loadViewStatistics]);

  // Initial data load: load statistics when overview or statistics tab becomes active
  useEffect(() => {
    if (activeTab === 'overview' || activeTab === 'statistics') {
      _loadViewStatistics('month', new Date().getFullYear());
    }
    if (activeTab === 'overview') {
      _loadAllUserBalances();
    }
  }, [activeTab, _loadViewStatistics, _loadAllUserBalances, selectedScope]);

  // Load transactions with pagination support
  const _loadTransactions = useCallback(async (paginationParams?: any) => {
    try {
      setTransactionsLoading(true);
      setTransactionsError(null);
      
      const params: any = {};
      // Only serialize if it's a plain pagination object (not a React event or other non-serializable object)
      if (paginationParams && typeof paginationParams === 'object' && 'page' in paginationParams) {
        const { page, pageSize, sortBy, sortDirection, search, filters } = paginationParams;
        params.pagination = JSON.stringify({ page, pageSize, sortBy, sortDirection, search, filters });
      }
      
      const response = await api.get('/api/billing/view/users/transactions', { params });
      const data = response.data;
      
      // Handle PaginatedResponse format: { items: [...], pagination: {...} }
      if (data && typeof data === 'object' && 'items' in data) {
        setTransactions(Array.isArray(data.items) ? data.items : []);
        if (data.pagination) {
          setTransactionsPagination(data.pagination);
        }
      } else {
        // Backward compatibility: plain array response
        setTransactions(Array.isArray(data) ? data : []);
      }
    } catch (err: any) {
      console.error('Failed to load transactions:', err);
      setTransactionsError(err.response?.data?.detail || err.message || 'Fehler beim Laden der Transaktionen');
    } finally {
      setTransactionsLoading(false);
    }
  }, []);

  // Load transactions when switching to transactions tab
  useEffect(() => {
    if (activeTab === 'transactions') {
      _loadTransactions();
    }
  }, [activeTab, _loadTransactions]);

  // hookData for FormGeneratorTable
  const transactionsHookData = useMemo(() => ({
    refetch: _loadTransactions,
    pagination: transactionsPagination ? {
      totalPages: transactionsPagination.totalPages,
      totalItems: transactionsPagination.totalItems,
    } : undefined,
  }), [_loadTransactions, transactionsPagination]);

  // Table column definitions
  const columns: ColumnConfig[] = useMemo(() => [
    { key: 'createdAt', label: 'Datum', type: 'timestamp' as any, sortable: true, width: 160 },
    { key: 'mandateName', label: 'Mandant', type: 'text' as any, sortable: true, filterable: true, searchable: true, width: 150 },
    { key: 'userName', label: 'Benutzer', type: 'text' as any, sortable: true, filterable: true, searchable: true, width: 150 },
    { key: 'transactionType', label: 'Typ', type: 'text' as any, sortable: true, filterable: true, width: 100 },
    { key: 'description', label: 'Beschreibung', type: 'text' as any, searchable: true, width: 250 },
    { key: 'aicoreProvider', label: 'Anbieter', type: 'text' as any, sortable: true, filterable: true, width: 120 },
    { key: 'aicoreModel', label: 'Modell', type: 'text' as any, sortable: true, filterable: true, width: 150 },
    { key: 'featureCode', label: 'Feature', type: 'text' as any, sortable: true, filterable: true, width: 120 },
    { key: 'amount', label: 'Betrag (CHF)', type: 'number' as any, sortable: true, width: 120 },
  ], []);

  // Build report sections based on current data
  const overviewSections = useMemo<ReportSection[]>(() => {
    if (!viewStats) return [];
    return _buildOverviewSections(viewStats);
  }, [viewStats]);

  const statisticsSections = useMemo<ReportSection[]>(() => {
    if (!viewStats) return [];
    return _buildStatisticsSections(viewStats);
  }, [viewStats]);

  // Period selector config (shared between overview and statistics)
  const periodSelectorConfig = useMemo(() => ({
    periods: ['month' as const, 'day' as const],
    defaultPeriod: 'month' as const,
    showYear: true,
    showMonth: true,
    defaultYear: new Date().getFullYear(),
    defaultMonth: new Date().getMonth() + 1
  }), []);

  // Build scope options from balances (mandates the user has access to)
  const scopeOptions = useMemo(() => {
    const options: Array<{ value: string; label: string }> = [
      { value: 'personal', label: 'Meine Kosten' },
    ];
    // Add mandate options from balances
    const seen = new Set<string>();
    for (const b of balances) {
      if (!seen.has(b.mandateId)) {
        seen.add(b.mandateId);
        options.push({ value: b.mandateId, label: `Mandant: ${b.mandateName}` });
      }
    }
    options.push({ value: 'all', label: 'Alle (RBAC)' });
    return options;
  }, [balances]);

  return (
    <div className={styles.billingDashboard}>
      <header className={styles.pageHeader}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <div>
            <h1>Billing</h1>
            <p className={styles.subtitle}>Guthaben, Statistiken und Transaktionen</p>
          </div>
          {activeTab !== 'transactions' && (
            <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
              <label style={{ fontSize: '13px', opacity: 0.7 }}>Ansicht:</label>
              <select
                className={styles.select || ''}
                value={selectedScope}
                onChange={(e) => setSelectedScope(e.target.value)}
              >
                {scopeOptions.map(opt => (
                  <option key={opt.value} value={opt.value}>{opt.label}</option>
                ))}
              </select>
            </div>
          )}
        </div>
      </header>

      <TabNav activeTab={activeTab} onTabChange={setActiveTab} />

      {/* ================================================================ */}
      {/* Tab: Übersicht (My Overview) */}
      {/* ================================================================ */}
      {activeTab === 'overview' && (() => {
        // Filter balances and user accounts by scope
        const filteredBalances = selectedScope === 'personal' || selectedScope === 'all'
          ? balances
          : balances.filter(b => b.mandateId === selectedScope);
        
        const filteredUserBalances = selectedScope === 'personal'
          ? [] // personal view: only own balance cards, no other users
          : selectedScope === 'all'
            ? allUserBalances
            : allUserBalances.filter(ub => ub.mandateId === selectedScope);

        return (
          <>
            {/* Balance Cards - own balances */}
            <section className={styles.section}>
              <h2 className={styles.sectionTitle}>Mein Guthaben</h2>
              {dashboardLoading ? (
                <div className={styles.loadingPlaceholder}>Lade Guthaben...</div>
              ) : filteredBalances.length === 0 ? (
                <div className={styles.noData}>Keine Abrechnungskonten vorhanden</div>
              ) : (
                <div className={styles.balanceGrid}>
                  {filteredBalances.map((balance) => (
                    <BalanceCard key={balance.mandateId} balance={balance} />
                  ))}
                </div>
              )}
            </section>

            {/* All User Balance Cards (mandate/all scope) */}
            {filteredUserBalances.length > 0 && (
              <section className={styles.section}>
                <h2 className={styles.sectionTitle}>Benutzer-Guthaben</h2>
                {allUserBalancesLoading ? (
                  <div className={styles.loadingPlaceholder}>Lade Benutzer-Guthaben...</div>
                ) : (
                  <div className={styles.balanceGrid}>
                    {filteredUserBalances.map((ub, idx) => (
                      <div key={`${ub.userId}-${ub.mandateId}-${idx}`} className={styles.balanceCard}>
                        <div className={styles.balanceHeader}>
                          <h3 className={styles.mandateName}>{ub.userName || ub.userId?.slice(0, 8)}</h3>
                          <span className={styles.billingModel}>{ub.mandateName}</span>
                        </div>
                        <div className={styles.balanceAmount}>
                          {_formatCurrency(ub.balance || 0)}
                        </div>
                      </div>
                    ))}
                  </div>
                )}
              </section>
            )}

            {/* Usage Statistics via FormGeneratorReport */}
            <section className={styles.section}>
              <FormGeneratorReport
                title={selectedScope === 'personal' ? 'Meine Nutzung' : 'Nutzungsübersicht'}
                loading={statsLoading}
                sections={overviewSections}
                noDataMessage="Keine Statistiken verfügbar"
                currencyCode="CHF"
              />
            </section>
          </>
        );
      })()}

      {/* ================================================================ */}
      {/* Tab: Statistik (Dashboard) */}
      {/* ================================================================ */}
      {activeTab === 'statistics' && (
        <section className={styles.section}>
          <FormGeneratorReport
            title="Nutzungsstatistik"
            subtitle="Detaillierte Analyse der AI-Nutzung"
            periodSelector={periodSelectorConfig}
            onFilterChange={_handleStatsFilterChange}
            loading={statsLoading}
            sections={statisticsSections}
            noDataMessage="Keine Statistiken verfügbar"
            currencyCode="CHF"
          />
        </section>
      )}

      {/* ================================================================ */}
      {/* Tab: Transaktionen */}
      {/* ================================================================ */}
      {activeTab === 'transactions' && (
        <div style={{ display: 'flex', flexDirection: 'column', flex: 1, minHeight: '500px' }}>
          {transactionsError && (
            <div className={styles.errorMessage}>
              {transactionsError}
            </div>
          )}

          <FormGeneratorTable
            data={transactions}
            columns={columns}
            apiEndpoint="/api/billing/view/users/transactions"
            loading={transactionsLoading}
            pagination={true}
            pageSize={25}
            searchable={true}
            filterable={true}
            sortable={true}
            selectable={false}
            emptyMessage="Keine Transaktionen vorhanden"
            onRefresh={_loadTransactions}
            hookData={transactionsHookData}
          />
        </div>
      )}
    </div>
  );
};

export default BillingDataView;
