import { useState, useEffect } from 'react';
import api from './lib/api.js';
import axios from 'axios';
import FormModal from './components/FormModal.jsx';
import ConfirmModal from './components/ConfirmModal.jsx';
import Pagination from './components/Pagination.jsx';
import PageHeader from './components/PageHeader.jsx';
import PageHeaderActions from './components/PageHeaderActions.jsx';
import FormField from './components/FormField.jsx';
import ServerAutocompleteInput from './components/ServerAutocompleteInput.jsx';
import PurposeSelectInput, { PURPOSES as PURPOSE_OPTIONS } from './components/PurposeSelectInput.jsx';
import ErrorAlert from './components/ErrorAlert.jsx';
import { 
  IconPlus, 
  IconEdit, 
  IconTrash, 
  IconCheck, 
  IconDatabase,
  IconRefresh,
  IconAlertTriangle,
  IconCalendar,
  IconCreditCard,
  IconCurrencyDollar,
  IconExternalLink,
  IconSearch,
  IconFilter,
  IconDownload,
  IconUpload,
  IconEye,
  IconEyeOff,
  IconHistory,
  IconChevronUp,
  IconChevronDown,
  IconX,
  IconChecks,
  IconServer,
  IconClock,
  IconLayoutGrid,
  IconList
} from '@tabler/icons-react';
import BulkActionsBar from './components/BulkActionsBar.jsx';
import { BillingCard } from './components/billing/index.js';

function BillingManager() {
  const [billingData, setBillingData] = useState([]);
  const [servers, setServers] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');
  const [success, setSuccess] = useState('');
  const [searchTerm, setSearchTerm] = useState('');
  const [currentPage, setCurrentPage] = useState(1);
  const [sortField, setSortField] = useState('nextPaymentDate');
  const [sortOrder, setSortOrder] = useState('asc');
  const [filterStatus, _setFilterStatus] = useState('');
  const [filterUrgency, setFilterUrgency] = useState('');
  const [viewMode, setViewMode] = useState('cards'); // 'cards' | 'table'
  const [activeTab, setActiveTab] = useState('subscriptions'); // 'subscriptions' | 'payments'
  const pageSize = 15;

  // Модальные окна
  const [showAddModal, setShowAddModal] = useState(false);
  const [showEditModal, setShowEditModal] = useState(false);
  const [showDeleteModal, setShowDeleteModal] = useState(false);
  const [selectedItem, setSelectedItem] = useState(null);
  const [editingItem, setEditingItem] = useState({});

  // Модалка добавления платежа
  const [showPaymentModal, setShowPaymentModal] = useState(false);
  const [paymentDraft, setPaymentDraft] = useState({
    serverId: '',
    date: '',
    amount: 0,
    currency: 'USD',
    note: ''
  });
  const [editingPayment, setEditingPayment] = useState(null);
  const [showDeletePaymentModal, setShowDeletePaymentModal] = useState(false);
  const [paymentToDelete, setPaymentToDelete] = useState(null);
  const [_futureDateConfirm, _setFutureDateConfirm] = useState(false);

  // История платежей
  const [paymentSearchTerm, _setPaymentSearchTerm] = useState('');
  const [_paymentSortField, _setPaymentSortField] = useState('date');
  const [_paymentSortOrder, _setPaymentSortOrder] = useState('desc');
  const [_selectedPayments, _setSelectedPayments] = useState(new Set());
  const [_paymentPage, _setPaymentPage] = useState(1);
  const paymentPageSize = 10;

  // Курсы валют
  const [exchangeRates, setExchangeRates] = useState({
    USD: 1,
    EUR: 1,
    RUB: 1
  });
  const [_ratesLoading, setRatesLoading] = useState(false);

  // Новый элемент
  const [newItem, setNewItem] = useState({
    hostName: '',
    purpose: '',
    country: '',
    provider: '',
    loginUrl: '',
    monthlyCost: 0,
    monthlyCostCurrency: 'USD',
    nextPaymentDate: '',
    lastPaymentDate: '',
    lastPaymentAmount: 0,
    lastPaymentCurrency: 'USD',
    status: 'active',
    notes: '',
    serverId: '',
  });

  useEffect(() => {
    const controller = new AbortController();
    const signal = controller.signal;
    fetchBillingData(signal);
    fetchExchangeRates(signal);
    fetchServers(signal);
    return () => controller.abort();
  }, []);

  // Автоматическая синхронизация: добавляем серверы без записей в биллинге
  useEffect(() => {
    if (servers.length === 0 || loading) return;
    
    setBillingData((prev) => {
      const existingServerIds = new Set(
        prev.map(b => b.serverId).filter(Boolean)
      );
      
      // Находим серверы без записей в биллинге (исключаем входные роутеры)
      const serversToAdd = servers.filter(server => 
        server.id && 
        !existingServerIds.has(server.id) &&
        server.type !== 'home' // Входные роутеры не попадают в биллинг
      );
      
      if (serversToAdd.length === 0) return prev;
      
      // Создаём записи с флагом _external
      const newItems = serversToAdd.map(server => ({
        id: `billing-${server.id}-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
        hostName: server.dns || server.ip,
        purpose: '',
        country: server.country || '',
        provider: server.provider || '',
        loginUrl: '',
        monthlyCost: 0,
        monthlyCostCurrency: 'USD',
        nextPaymentDate: '',
        lastPaymentDate: '',
        lastPaymentAmount: 0,
        lastPaymentCurrency: 'USD',
        status: 'active',
        notes: '',
        serverId: server.id,
        payments: [],
        _external: true, // флаг "не заполнен"
      }));
      
      return [...prev, ...newItems];
    });
  }, [servers, loading]);


  const fetchExchangeRates = async (abortSignal) => {
    setRatesLoading(true);
    const opts = abortSignal ? { signal: abortSignal } : {};
    try {
      // Основной источник: ЦБ РФ (base = RUB)
      const cbr = await axios.get('https://www.cbr-xml-daily.ru/latest.js', opts);
      const rubPerUsd = cbr.data && cbr.data.rates?.USD ? 1 / Number(cbr.data.rates.USD) : null;
      const rubPerEur = cbr.data && cbr.data.rates?.EUR ? 1 / Number(cbr.data.rates.EUR) : null;

      if (rubPerUsd) {
        const eurPerUsd = rubPerEur ? rubPerUsd / rubPerEur : 1;
        setExchangeRates({
          USD: 1,
          EUR: eurPerUsd,  // сколько EUR за 1 USD
          RUB: rubPerUsd   // сколько RUB за 1 USD
        });
        return;
      }
    } catch (error) {
      if (error?.name === 'CanceledError' || error?.name === 'AbortError' || error?.code === 'ERR_CANCELED') return;
      console.warn('ЦБ недоступен, пробуем резервный источник:', error?.message);
    }

    try {
      // Резервный источник: open.er-api
      const response = await axios.get('https://open.er-api.com/v6/latest/USD', opts);
      const rates = response.data?.rates || {};
      setExchangeRates({
        USD: 1,
        EUR: rates.EUR || 1,
        RUB: rates.RUB || 1
      });
    } catch (error) {
      if (error?.name === 'CanceledError' || error?.name === 'AbortError' || error?.code === 'ERR_CANCELED') return;
      console.error('Ошибка при загрузке курсов валют:', error);
      // Фолбек на разумные значения
      setExchangeRates({ USD: 1, EUR: 1.05, RUB: 95 });
    } finally {
      setRatesLoading(false);
    }
  };

  const fetchServers = async (abortSignal) => {
    const opts = abortSignal ? { signal: abortSignal } : {};
    try {
      const res = await api.get(`/servers`, opts);
      setServers(Array.isArray(res.data) ? res.data : []);
    } catch (error) {
      if (error?.name === 'CanceledError' || error?.name === 'AbortError' || error?.code === 'ERR_CANCELED') return;
      console.error('Ошибка при загрузке серверов:', error);
    }
  };

  const fetchBillingData = async (abortSignal) => {
    setLoading(true);
    const opts = abortSignal ? { signal: abortSignal } : {};
    try {
      const response = await api.get(`/billing`, opts);
      const rates = exchangeRates; // из closure, на первой загрузке может быть {1,1,1} — для USD достаточно
      const toRUB = (amt, ccy) => {
        if (!amt) return 0;
        const rub = Number(rates.RUB) || 1;
        if (!ccy || ccy === 'RUB') return amt;
        if (ccy === 'USD') return amt * rub;
        const c = Number(rates[ccy]);
        return c ? (amt / c) * rub : amt * rub;
      };
      const normalized = (response.data || []).map((item, idx) => {
        const payments = Array.isArray(item.payments)
          ? item.payments
          : (item.lastPaymentDate && item.lastPaymentAmount
              ? [{ date: item.lastPaymentDate, amount: item.lastPaymentAmount, currency: item.lastPaymentCurrency || 'USD', note: 'Импортировано' }]
              : []
            );
        const merged = { id: item.id ?? String(idx + 1), payments, ...item };
        if (payments.length > 0) {
          const last = payments.slice().sort((a, b) => new Date(b.date) - new Date(a.date))[0];
          if (last?.date) {
            const current = new Date(item.nextPaymentDate || 0);
            const now = new Date();
            if (current < now || !item.nextPaymentDate) {
              const costRUB = toRUB(item.monthlyCost || 0, item.monthlyCostCurrency || 'USD');
              const amtRUB = toRUB(last.amount, last.currency || 'USD');
              const months = costRUB > 0 ? Math.max(1, Math.floor(amtRUB / costRUB)) : 1;
              const d = new Date(last.date);
              d.setMonth(d.getMonth() + months);
              merged.nextPaymentDate = d.toISOString().slice(0, 10);
            }
          }
        }
        return merged;
      });
      setBillingData(normalized);
      setError('');
    } catch (err) {
      if (err?.name === 'CanceledError' || err?.name === 'AbortError' || err?.code === 'ERR_CANCELED') return;
      console.error('Ошибка при загрузке данных биллинга:', err);
      setError('Ошибка при загрузке данных');
      setBillingData([]);
    } finally {
      setLoading(false);
    }
  };

  const handleSaveChanges = async () => {
    setLoading(true);
    try {
      // Убираем служебное поле _external перед сохранением
      const payload = billingData.map(({ _external: _ext, ...rest }) => rest);
      await api.post(`/billing`, { domains: payload });
      // После сохранения снимаем флаг _external со всех записей
      setBillingData(prev => prev.map(item => ({ ...item, _external: false })));
      setSuccess('Данные успешно сохранены');
      setTimeout(() => setSuccess(''), 3000);
    } catch (err) {
      console.error('Ошибка при сохранении:', err);
      setError(`Ошибка при сохранении данных: ${err.response?.data || err.message}`);
      setTimeout(() => setError(''), 5000);
    } finally {
      setLoading(false);
    }
  };

  // Карта серверов для быстрой привязки
  const serversById = new Map(
    (servers || []).filter(s => s && s.id).map(s => [s.id, s])
  );

  // Конвертация в рубли
  const convertToRUB = (amount, currency) => {
    if (!amount) return 0;
    const rubPerUsd = Number(exchangeRates.RUB) || 1;
    if (!currency || currency === 'RUB') return amount;
    if (currency === 'USD') return amount * rubPerUsd;
    const ccyPerUsd = Number(exchangeRates[currency]);
    if (!ccyPerUsd || ccyPerUsd === 0) return amount;
    return (amount / ccyPerUsd) * rubPerUsd;
  };

  // Статистика
  const totalMonthlyCosts = billingData.reduce((sum, item) => {
    return sum + convertToRUB(item.monthlyCost || 0, item.monthlyCostCurrency || 'USD');
  }, 0);

  const totalPaymentsCount = billingData.reduce((sum, item) => {
    return sum + ((item.payments && Array.isArray(item.payments) ? item.payments.length : 0));
  }, 0);

  const urgentPayments = billingData.filter(item => {
    const nextPayment = new Date(item.nextPaymentDate);
    const now = new Date();
    const diffDays = Math.ceil((nextPayment - now) / (1000 * 60 * 60 * 24));
    return diffDays <= 7 && diffDays >= 0;
  });

  const overduePayments = billingData.filter(item => {
    const nextPayment = new Date(item.nextPaymentDate);
    const now = new Date();
    return nextPayment < now;
  });

  // Расчет дней до платежа
  const getDaysUntilPayment = (dateString) => {
    if (!dateString) return null;
    const nextPayment = new Date(dateString);
    const now = new Date();
    return Math.ceil((nextPayment - now) / (1000 * 60 * 60 * 24));
  };

  // Вычислить nextPaymentDate по платежу: сумма / месячная стоимость = кол-во месяцев
  const computeNextPaymentDate = (payment, server) => {
    if (!payment?.date) return '';
    const amountRUB = convertToRUB(payment.amount, payment.currency || 'USD');
    const costRUB = convertToRUB(server.monthlyCost || 0, server.monthlyCostCurrency || 'USD');
    const months = costRUB > 0 ? Math.max(1, Math.floor(amountRUB / costRUB)) : 1;
    const d = new Date(payment.date);
    d.setMonth(d.getMonth() + months);
    return d.toISOString().slice(0, 10);
  };

  // Форматирование
  function formatDate(dateString) {
    if (!dateString) return '—';
    try {
      return new Date(dateString).toLocaleDateString('ru-RU', { day: 'numeric', month: 'short' });
    } catch {
      return dateString;
    }
  }

  function formatCurrency(amount, currency = 'USD') {
    if (amount === undefined || amount === null || amount === '') return '—';
    return new Intl.NumberFormat('ru-RU', {
      style: 'currency',
      currency: currency,
      minimumFractionDigits: 2,
      maximumFractionDigits: 2
    }).format(amount);
  }

  function formatCurrencyInRUB(amount, currency) {
    const rubAmount = convertToRUB(amount, currency);
    return new Intl.NumberFormat('ru-RU', {
      style: 'currency',
      currency: 'RUB',
      minimumFractionDigits: 2,
      maximumFractionDigits: 2
    }).format(rubAmount);
  }

  // Фильтрация и сортировка
  const filteredData = billingData
    .filter(item => {
      const matchesSearch = 
        item.hostName?.toLowerCase().includes(searchTerm.toLowerCase()) ||
        item.provider?.toLowerCase().includes(searchTerm.toLowerCase());
      
      const matchesStatus = !filterStatus || item.status === filterStatus;
      
      let matchesUrgency = true;
      if (filterUrgency === 'overdue') {
        const days = getDaysUntilPayment(item.nextPaymentDate);
        matchesUrgency = days !== null && days < 0;
      } else if (filterUrgency === 'urgent') {
        const days = getDaysUntilPayment(item.nextPaymentDate);
        matchesUrgency = days !== null && days >= 0 && days <= 7;
      } else if (filterUrgency === 'soon') {
        const days = getDaysUntilPayment(item.nextPaymentDate);
        matchesUrgency = days !== null && days > 7 && days <= 30;
      }

      return matchesSearch && matchesStatus && matchesUrgency;
    })
    .sort((a, b) => {
      let aValue = a[sortField];
      let bValue = b[sortField];
      
      if (sortField === 'nextPaymentDate') {
        aValue = new Date(aValue || '9999-12-31');
        bValue = new Date(bValue || '9999-12-31');
      } else if (sortField === 'monthlyCost') {
        aValue = convertToRUB(a.monthlyCost, a.monthlyCostCurrency);
        bValue = convertToRUB(b.monthlyCost, b.monthlyCostCurrency);
      }
      
      if (sortOrder === 'asc') {
        return aValue > bValue ? 1 : -1;
      } else {
        return aValue < bValue ? 1 : -1;
      }
    });

  const paginatedData = filteredData.slice(
    (currentPage - 1) * pageSize,
    currentPage * pageSize
  );

  const totalPages = Math.ceil(filteredData.length / pageSize);

  const handleSort = (field) => {
    if (sortField === field) {
      setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc');
    } else {
      setSortField(field);
      setSortOrder('asc');
    }
  };

  // CRUD операции
  const handleAddItem = () => {
    setNewItem({
      hostName: '',
      purpose: '',
      country: '',
      provider: '',
      loginUrl: '',
      monthlyCost: 0,
      monthlyCostCurrency: 'USD',
      nextPaymentDate: '',
      lastPaymentDate: '',
      lastPaymentAmount: 0,
      lastPaymentCurrency: 'USD',
      status: 'active',
      notes: '',
      serverId: '',
    });
    setShowAddModal(true);
  };

  const handleEditItem = (item) => {
    setEditingItem({ ...item });
    setShowEditModal(true);
  };

  const handleDeleteItem = (item) => {
    setSelectedItem(item);
    setShowDeleteModal(true);
  };

  const confirmDelete = () => {
    if (selectedItem) {
      setBillingData(prev => prev.filter(item => item.id !== selectedItem.id));
      setShowDeleteModal(false);
      setSelectedItem(null);
    }
  };

  const handleAddSubmit = () => {
    if (!newItem.hostName || !newItem.provider) {
      setError('Заполните обязательные поля: Имя хоста, Провайдер');
      return;
    }
    
    const newId = Math.max(...billingData.map(item => parseInt(item.id) || 0), 0) + 1;
    setBillingData(prev => [...prev, { ...newItem, id: newId.toString() }]);
    setShowAddModal(false);
    setSuccess('Элемент добавлен');
    setTimeout(() => setSuccess(''), 3000);
  };

  const handleEditSubmit = () => {
    if (!editingItem.hostName || !editingItem.provider) {
      setError('Заполните обязательные поля');
      return;
    }
    
    // Снимаем флаг _external при редактировании (запись теперь заполнена)
    setBillingData(prev => prev.map(item => 
      item.id === editingItem.id ? { ...editingItem, _external: false } : item
    ));
    setShowEditModal(false);
    setSuccess('Элемент обновлен');
    setTimeout(() => setSuccess(''), 3000);
  };

  // Удаление платежа
  const handleDeletePayment = () => {
    if (!paymentToDelete) return;
    const { serverId, index } = paymentToDelete;
    setBillingData(prev => prev.map(s => {
      if (s.id !== serverId) return s;
      const payments = [...(s.payments || [])];
      payments.splice(index, 1);
      const last = payments.slice().sort((a,b) => new Date(b.date) - new Date(a.date))[0];
      const nextPaymentDate = last ? computeNextPaymentDate(last, s) : '';
      return {
        ...s,
        payments,
        lastPaymentDate: last?.date || '',
        lastPaymentAmount: last?.amount || 0,
        lastPaymentCurrency: last?.currency || 'USD',
        nextPaymentDate: nextPaymentDate || s.nextPaymentDate
      };
    }));
    setShowDeletePaymentModal(false);
    setPaymentToDelete(null);
    setSuccess('Платеж удалён');
    setTimeout(() => setSuccess(''), 3000);
  };

  // Экспорт данных
  const exportData = () => {
    const csvContent = [
      ['Host', 'Provider', 'Monthly Cost', 'Currency', 'Next Payment', 'Status'],
      ...filteredData.map(item => [
        item.hostName,
        item.provider,
        item.monthlyCost,
        item.monthlyCostCurrency,
        item.nextPaymentDate,
        item.status
      ])
    ].map(row => row.join(',')).join('\n');

    const blob = new Blob([csvContent], { type: 'text/csv' });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `billing-${new Date().toISOString().split('T')[0]}.csv`;
    a.click();
    window.URL.revokeObjectURL(url);
  };

  // Компонент бейджа срочности
  const UrgencyBadge = ({ days }) => {
    if (days === null) return <span className="text-muted">—</span>;
    
    if (days < 0) {
      return (
        <span className="badge bg-red-lt text-red">
          <IconAlertTriangle size={12} className="me-1" />
          {Math.abs(days)} дн. назад
        </span>
      );
    } else if (days === 0) {
      return (
        <span className="badge bg-red-lt text-red">
          Сегодня
        </span>
      );
    } else if (days <= 7) {
      return (
        <span className="badge bg-yellow-lt text-yellow">
          {days} дн.
        </span>
      );
    } else if (days <= 30) {
      return (
        <span className="badge bg-azure-lt text-azure">
          {days} дн.
        </span>
      );
    } else {
      return (
        <span className="text-muted">
          {days} дн.
        </span>
      );
    }
  };

  return (
    <div>
      {/* Заголовок */}
      <PageHeader
        title="Биллинг"
        icon={<IconCreditCard size={24} />}
        actions={
          <div className="d-flex flex-column flex-sm-row align-items-stretch align-items-sm-center gap-2">
            <div className="btn-group me-sm-2" role="group">
              <button
                className={`btn ${activeTab === 'subscriptions' ? 'btn-primary' : 'btn-outline-primary'}`}
                onClick={() => setActiveTab('subscriptions')}
              >
                <IconServer size={16} className="me-1 d-none d-sm-inline" />
                Подписки
                <span className={`badge ms-1 ${activeTab === 'subscriptions' ? 'bg-white text-primary' : 'bg-primary-lt text-primary'}`}>
                  {billingData.length}
                </span>
              </button>
              <button
                className={`btn ${activeTab === 'payments' ? 'btn-primary' : 'btn-outline-primary'}`}
                onClick={() => setActiveTab('payments')}
              >
                <IconHistory size={16} className="me-1 d-none d-sm-inline" />
                История платежей
                <span className={`badge ms-1 ${activeTab === 'payments' ? 'bg-white text-primary' : 'bg-primary-lt text-primary'}`}>
                  {totalPaymentsCount}
                </span>
              </button>
            </div>
            <PageHeaderActions
              loading={loading}
              onRefresh={() => { fetchBillingData(); fetchServers(); }}
              disableRefresh={loading}
              onExport={exportData}
              disableExport={loading}
              onSave={handleSaveChanges}
              disableSave={loading}
            />
          </div>
        }
      />

      {/* Уведомления */}
      {error && (
        <ErrorAlert
          message={error}
          onClose={() => setError('')}
          onRetry={fetchBillingData}
          className="mb-4"
        />
      )}
      {success && (
        <div className="alert alert-success alert-dismissible mb-4" role="alert">
          <IconCheck className="me-2" size={18} />
          {success}
          <button type="button" className="btn-close" onClick={() => setSuccess('')}></button>
        </div>
      )}

      {/* Статистика */}
      <div className="row g-3 mb-4">
        <div className="col-md-4">
          <div className="card h-100">
            <div className="card-body d-flex align-items-center">
              <span className="avatar avatar-lg me-3 bg-blue-lt text-blue border-0">
                <IconCurrencyDollar size={32} />
              </span>
              <div>
                <div className="h3 mb-0 fw-bold">
                  {formatCurrencyInRUB(totalMonthlyCosts, 'RUB')}
                </div>
                <div className="text-muted small">Месячные затраты</div>
              </div>
            </div>
          </div>
        </div>
        <div className="col-md-4">
          <div className="card h-100">
            <div className="card-body d-flex align-items-center">
              <span className={`avatar avatar-lg me-3 ${overduePayments.length > 0 ? 'bg-red-lt text-red' : 'bg-green-lt text-green'} border-0`}>
                <IconAlertTriangle size={32} />
              </span>
              <div>
                <div className="h3 mb-0 fw-bold">
                  {overduePayments.length}
                </div>
                <div className="text-muted small">Просрочено платежей</div>
              </div>
            </div>
          </div>
        </div>
        <div className="col-md-4">
          <div className="card h-100">
            <div className="card-body d-flex align-items-center">
              <span className={`avatar avatar-lg me-3 ${urgentPayments.length > 0 ? 'bg-yellow-lt text-yellow' : 'bg-azure-lt text-azure'} border-0`}>
                <IconClock size={32} />
              </span>
              <div>
                <div className="h3 mb-0 fw-bold">
                  {urgentPayments.length}
                </div>
                <div className="text-muted small">Оплата на этой неделе</div>
              </div>
            </div>
          </div>
        </div>
      </div>

      {/* Основная секция: Подписки */}
      {activeTab === 'subscriptions' && (
        <div className="card">
          <div className="card-header d-flex flex-wrap align-items-center justify-content-between gap-2">
            <h3 className="card-title mb-0">
              Подписки
              <span className="badge bg-blue-lt text-blue ms-2">{filteredData.length}</span>
            </h3>

            <div className="d-flex flex-wrap align-items-center gap-2 flex-grow-1 justify-content-end">
              {/* Поиск */}
              <div className="input-icon" style={{ minWidth: '220px', maxWidth: '280px' }}>
                <span className="input-icon-addon">
                  <IconSearch size={16} />
                </span>
                <input
                  type="text"
                  className="form-control form-control-sm"
                  placeholder="Поиск..."
                  value={searchTerm}
                  onChange={(e) => { setSearchTerm(e.target.value); setCurrentPage(1); }}
                />
              </div>

              {/* Быстрые фильтры */}
              <div className="btn-group" role="group">
                <button 
                  className={`btn ${filterUrgency === '' ? 'btn-outline-primary active' : 'btn-outline-secondary'}`}
                  onClick={() => { setFilterUrgency(''); setCurrentPage(1); }}
                >
                  Все
                </button>
                <button 
                  className={`btn ${filterUrgency === 'overdue' ? 'btn-outline-danger active' : 'btn-outline-secondary'}`}
                  onClick={() => { setFilterUrgency('overdue'); setCurrentPage(1); }}
                >
                  Просрочено
                </button>
                <button 
                  className={`btn ${filterUrgency === 'urgent' ? 'btn-outline-warning active' : 'btn-outline-secondary'}`}
                  onClick={() => { setFilterUrgency('urgent'); setCurrentPage(1); }}
                >
                  Срочно
                </button>
              </div>

              {/* Переключатель вида */}
              <div className="btn-group" role="group">
                <button
                  className={`btn ${viewMode === 'cards' ? 'btn-outline-primary active' : 'btn-outline-secondary'}`}
                  onClick={() => setViewMode('cards')}
                  title="Карточки"
                >
                  <IconLayoutGrid size={16} />
                </button>
                <button
                  className={`btn ${viewMode === 'table' ? 'btn-outline-primary active' : 'btn-outline-secondary'}`}
                  onClick={() => setViewMode('table')}
                  title="Таблица"
                >
                  <IconList size={16} />
                </button>
              </div>

              <div className="card-actions">
                <button className="btn btn-primary" onClick={handleAddItem}>
                  <IconPlus size={18} className="me-1" />
                  Добавить
                </button>
              </div>
            </div>
          </div>

          {/* Контент: карточки или таблица */}
          {paginatedData.length === 0 ? (
            <div className="card-body text-center text-muted py-5">
              <IconCreditCard size={48} className="mb-3 text-muted" />
              <h3>{searchTerm || filterUrgency ? 'Ничего не найдено' : 'Нет подписок'}</h3>
              <p className="text-muted">Добавьте первую подписку для отслеживания платежей</p>
              <button className="btn btn-primary" onClick={handleAddItem}>
                <IconPlus size={18} className="me-1" />
                Добавить подписку
              </button>
            </div>
          ) : viewMode === 'cards' ? (
            /* Карточный вид */
            <div className="card-body">
              {paginatedData.map(item => {
                const days = getDaysUntilPayment(item.nextPaymentDate);
                const linkedServer = item.serverId ? serversById.get(item.serverId) : null;
                
                return (
                  <BillingCard
                    key={item.id}
                    item={item}
                    linkedServer={linkedServer}
                    daysUntilPayment={days}
                    onEdit={handleEditItem}
                    onDelete={handleDeleteItem}
                    onAddPayment={(item) => {
                      setPaymentDraft({
                        serverId: item.id,
                        date: new Date().toISOString().slice(0,10),
                        amount: item.monthlyCost || 0,
                        currency: item.monthlyCostCurrency || 'USD',
                        note: ''
                      });
                      setShowPaymentModal(true);
                    }}
                    formatCurrencyInRUB={formatCurrencyInRUB}
                  />
                );
              })}
            </div>
          ) : (
            /* Табличный вид */
            <div className="table-responsive">
              <table className="table card-table table-vcenter mb-0">
                <thead>
                  <tr>
                    <th 
                      className="cursor-pointer" 
                      onClick={() => handleSort('hostName')}
                      style={{ minWidth: '200px' }}
                    >
                      Сервис
                      {sortField === 'hostName' && (
                        <span className="ms-1">{sortOrder === 'asc' ? '↑' : '↓'}</span>
                      )}
                    </th>
                    <th 
                      className="cursor-pointer text-end" 
                      onClick={() => handleSort('monthlyCost')}
                      style={{ width: '140px' }}
                    >
                      Стоимость
                      {sortField === 'monthlyCost' && (
                        <span className="ms-1">{sortOrder === 'asc' ? '↑' : '↓'}</span>
                      )}
                    </th>
                    <th 
                      className="cursor-pointer text-center" 
                      onClick={() => handleSort('nextPaymentDate')}
                      style={{ width: '120px' }}
                    >
                      Платёж
                      {sortField === 'nextPaymentDate' && (
                        <span className="ms-1">{sortOrder === 'asc' ? '↑' : '↓'}</span>
                      )}
                    </th>
                    <th className="text-center" style={{ width: '100px' }}>Срок</th>
                    <th className="text-center" style={{ width: '80px' }}>Статус</th>
                    <th style={{ width: '140px' }}></th>
                  </tr>
                </thead>
                <tbody>
                  {paginatedData.map(item => {
                    const days = getDaysUntilPayment(item.nextPaymentDate);
                    const linkedServer = item.serverId ? serversById.get(item.serverId) : null;
                    
                    return (
                      <tr key={item.id}>
                        <td>
                          <div className="d-flex align-items-center">
                            <div>
                              <div className="fw-semibold">
                                {item.hostName}
                                {item._external && (
                                  <span className="badge bg-yellow-lt text-yellow ms-2" title="Импортирован из серверов, требует заполнения">
                                    не заполнен
                                  </span>
                                )}
                              </div>
                              <div className="text-muted small d-flex align-items-center gap-2">
                                <span>{item.provider}</span>
                                {linkedServer && (
                                  <>
                                    <span>•</span>
                                    <span className="text-blue">{linkedServer.ip}</span>
                                  </>
                                )}
                                {item.loginUrl && (
                                  <a 
                                    href={item.loginUrl.startsWith('http') ? item.loginUrl : `https://${item.loginUrl}`} 
                                    target="_blank" 
                                    rel="noopener noreferrer"
                                    className="text-muted"
                                    title="Открыть панель"
                                  >
                                    <IconExternalLink size={12} />
                                  </a>
                                )}
                              </div>
                            </div>
                          </div>
                        </td>
                        <td className="text-end">
                          <div className="fw-semibold">
                            {formatCurrency(item.monthlyCost, item.monthlyCostCurrency)}
                          </div>
                          {item.monthlyCostCurrency !== 'RUB' && (
                            <div className="text-muted small">
                              ≈ {formatCurrencyInRUB(item.monthlyCost, item.monthlyCostCurrency)}
                            </div>
                          )}
                        </td>
                        <td className="text-center">
                          {formatDate(item.nextPaymentDate)}
                        </td>
                        <td className="text-center">
                          <UrgencyBadge days={days} />
                        </td>
                        <td className="text-center">
                          {item.status === 'active' ? (
                            <span className="badge bg-green-lt text-green">Активен</span>
                          ) : (
                            <span className="badge bg-secondary-lt text-secondary">Неактивен</span>
                          )}
                        </td>
                        <td className="text-end">
                          <div className="btn-group" role="group">
                            <button
                              className="btn btn-outline-success"
                              onClick={() => {
                                setPaymentDraft({
                                  serverId: item.id,
                                  date: new Date().toISOString().slice(0,10),
                                  amount: item.monthlyCost || 0,
                                  currency: item.monthlyCostCurrency || 'USD',
                                  note: ''
                                });
                                setShowPaymentModal(true);
                              }}
                              title="Записать платёж"
                            >
                              <IconCreditCard size={14} className="me-1" />
                              Оплата
                            </button>
                            <button
                              className="btn btn-outline-secondary"
                              onClick={() => handleEditItem(item)}
                              title="Редактировать"
                            >
                              <IconEdit size={14} />
                            </button>
                            <button
                              className="btn btn-outline-danger"
                              onClick={() => handleDeleteItem(item)}
                              title="Удалить"
                            >
                              <IconTrash size={14} />
                            </button>
                          </div>
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>
          )}
          
          {totalPages > 1 && (
            <Pagination
              currentPage={currentPage}
              totalPages={totalPages}
              totalItems={filteredData.length}
              pageSize={pageSize}
              onPageChange={setCurrentPage}
            />
          )}
        </div>
      )}

      {/* История платежей — компактная версия */}
      {activeTab === 'payments' && (
      <div className="card mt-4">
        <div className="card-header">
          <h3 className="card-title d-flex align-items-center gap-2">
            <IconHistory size={18} />
            История платежей
          </h3>
          <div className="card-actions">
            <button 
              className="btn btn-primary"
              onClick={() => { 
                setPaymentDraft({ serverId: '', date: '', amount: 0, currency: 'USD', note: '' }); 
                setShowPaymentModal(true); 
              }}
            >
              <IconPlus size={18} className="me-1" />
              Добавить
            </button>
          </div>
        </div>
        <div className="card-body p-0">
          <div className="table-responsive">
            <table className="table card-table table-vcenter mb-0">
              <thead>
                <tr>
                  <th>Сервис</th>
                  <th>Дата</th>
                  <th className="text-end">Сумма</th>
                  <th>Комментарий</th>
                  <th style={{ width: '80px' }}></th>
                </tr>
              </thead>
              <tbody>
                {(() => {
                  let allRows = billingData.flatMap(server => 
                    (server.payments || []).map((p, idx) => ({ 
                      server, 
                      ...p, 
                      _key: `${server.id}-${idx}`, 
                      _index: idx 
                    }))
                  );

                  // Поиск
                  if (paymentSearchTerm) {
                    const term = paymentSearchTerm.toLowerCase();
                    allRows = allRows.filter(r => 
                      r.server.hostName?.toLowerCase().includes(term) ||
                      r.note?.toLowerCase().includes(term)
                    );
                  }

                  // Сортировка по дате (новые сверху)
                  allRows.sort((a, b) => new Date(b.date) - new Date(a.date));

                  // Пагинация
                  const paginatedRows = allRows.slice(0, paymentPageSize);

                  if (paginatedRows.length === 0) {
                    return (
                      <tr>
                        <td colSpan="5" className="text-center text-muted py-4">
                          Платежей пока нет
                        </td>
                      </tr>
                    );
                  }

                  return paginatedRows.map(r => (
                    <tr key={r._key}>
                      <td>
                        <span className="fw-medium">{r.server.hostName}</span>
                        <span className="text-muted ms-2 small">{r.server.provider}</span>
                      </td>
                      <td>{formatDate(r.date)}</td>
                      <td className="text-end">
                        <span className="fw-semibold">{formatCurrency(r.amount, r.currency)}</span>
                      </td>
                      <td className="text-muted small">{r.note || '—'}</td>
                      <td>
                        <div className="btn-list gap-1 justify-content-end flex-nowrap">
                          <button
                            className="btn btn-icon btn-sm btn-outline-secondary"
                            onClick={() => {
                              setPaymentDraft({
                                serverId: r.server.id,
                                date: r.date,
                                amount: r.amount,
                                currency: r.currency || 'USD',
                                note: r.note || ''
                              });
                              setEditingPayment({ serverId: r.server.id, index: r._index });
                              setShowPaymentModal(true);
                            }}
                            title="Редактировать"
                          >
                            <IconEdit size={14} />
                          </button>
                          <button
                            className="btn btn-icon btn-sm btn-outline-danger"
                            onClick={() => {
                              setPaymentToDelete({ serverId: r.server.id, index: r._index, data: r });
                              setShowDeletePaymentModal(true);
                            }}
                            title="Удалить"
                          >
                            <IconTrash size={14} />
                          </button>
                        </div>
                      </td>
                    </tr>
                  ));
                })()}
              </tbody>
            </table>
          </div>
        </div>
      </div>
      )}

      {/* Модальные окна */}
      <FormModal
        show={showAddModal}
        title="Добавить подписку"
        onSubmit={(e) => { e.preventDefault(); handleAddSubmit(); }}
        onClose={() => setShowAddModal(false)}
        submitLabel="Добавить"
        submitIcon={IconPlus}
        size="md"
      >
        <BillingForm
          item={newItem}
          onItemChange={setNewItem}
          servers={servers}
        />
      </FormModal>

      <FormModal
        show={showEditModal}
        title="Редактировать подписку"
        onSubmit={(e) => { e.preventDefault(); handleEditSubmit(); }}
        onClose={() => setShowEditModal(false)}
        submitLabel="Сохранить"
        submitIcon={IconCheck}
        size="md"
      >
        <BillingForm
          item={editingItem}
          onItemChange={setEditingItem}
          servers={servers}
        />
      </FormModal>

      <ConfirmModal
        show={showDeleteModal}
        title="Удалить подписку"
        message={
          <>
            Удалить <strong>{selectedItem?.hostName}</strong>?
            <div className="text-muted small mt-1">Это действие нельзя отменить</div>
          </>
        }
        onConfirm={confirmDelete}
        onClose={() => setShowDeleteModal(false)}
        confirmLabel="Удалить"
        variant="danger"
      />

      {/* Модалка платежа */}
      <FormModal
        show={showPaymentModal}
        title={editingPayment ? "Редактировать платеж" : "Записать платеж"}
        onSubmit={(e) => {
          e.preventDefault();
          if (!paymentDraft.serverId || !paymentDraft.date || !paymentDraft.amount) {
            setError('Заполните все поля');
            setTimeout(() => setError(''), 3000);
            return;
          }
          
          if (editingPayment) {
            setBillingData(prev => prev.map(s => {
              if (s.id !== editingPayment.serverId) return s;
              const payments = [...(s.payments || [])];
              payments[editingPayment.index] = {
                date: paymentDraft.date,
                amount: paymentDraft.amount,
                currency: paymentDraft.currency || 'USD',
                note: paymentDraft.note || ''
              };
              const last = payments.slice().sort((a,b) => new Date(b.date) - new Date(a.date))[0];
              const nextPaymentDate = computeNextPaymentDate(last, s);
              return { ...s, payments, lastPaymentDate: last?.date || '', lastPaymentAmount: last?.amount || 0, lastPaymentCurrency: last?.currency || 'USD', nextPaymentDate: nextPaymentDate || s.nextPaymentDate };
            }));
            setEditingPayment(null);
          } else {
            setBillingData(prev => prev.map(s => {
              if (s.id !== paymentDraft.serverId) return s;
              const payments = [...(s.payments || []), { 
                date: paymentDraft.date, 
                amount: paymentDraft.amount, 
                currency: paymentDraft.currency || 'USD', 
                note: paymentDraft.note || '' 
              }];
              const last = payments.slice().sort((a,b) => new Date(b.date) - new Date(a.date))[0];
              const nextPaymentDate = computeNextPaymentDate(last, s);
              return { ...s, payments, lastPaymentDate: last?.date || '', lastPaymentAmount: last?.amount || 0, lastPaymentCurrency: last?.currency || 'USD', nextPaymentDate: nextPaymentDate || s.nextPaymentDate };
            }));
          }
          setShowPaymentModal(false);
          setSuccess(editingPayment ? 'Платеж обновлен' : 'Платеж записан');
          setTimeout(() => setSuccess(''), 3000);
        }}
        onClose={() => { setShowPaymentModal(false); setEditingPayment(null); }}
        submitLabel={editingPayment ? "Сохранить" : "Записать"}
        submitIcon={editingPayment ? IconCheck : IconPlus}
      >
        <PaymentForm
          servers={billingData}
          payment={paymentDraft}
          onChange={setPaymentDraft}
        />
      </FormModal>

      <ConfirmModal
        show={showDeletePaymentModal}
        title="Удалить платеж"
        message={
          paymentToDelete && (
            <>
              Удалить платеж от <strong>{formatDate(paymentToDelete.data?.date)}</strong> на сумму{' '}
              <strong>{formatCurrency(paymentToDelete.data?.amount, paymentToDelete.data?.currency)}</strong>?
            </>
          )
        }
        onConfirm={handleDeletePayment}
        onClose={() => setShowDeletePaymentModal(false)}
        confirmLabel="Удалить"
        variant="danger"
      />
    </div>
  );
}

// Компактная форма для добавления/редактирования подписки
function BillingForm({ item, onItemChange, servers }) {
  const currencyOptions = [
    { value: 'USD', label: 'USD' },
    { value: 'EUR', label: 'EUR' },
    { value: 'RUB', label: 'RUB' }
  ];

  return (
    <div className="row g-3">
      <div className="col-12">
        <FormField
          label="Имя сервиса"
          name="hostName"
          value={item.hostName}
          onChange={(value) => onItemChange({ ...item, hostName: value })}
          placeholder="Например: Hetzner VPS #1"
          required
        />
      </div>
      
      <div className="col-md-6">
        <FormField
          label="Провайдер"
          name="provider"
          value={item.provider}
          onChange={(value) => onItemChange({ ...item, provider: value })}
          placeholder="Hetzner, AWS, etc."
          required
        />
      </div>
      
      <div className="col-md-6">
        <label className="form-label">Связанный сервер</label>
        <ServerAutocompleteInput
          value={item.serverId || ''}
          onChange={(value) => onItemChange({ ...item, serverId: value || '' })}
          servers={servers}
          placeholder="Опционально"
        />
      </div>

      <div className="col-md-6">
        <FormField
          label="Стоимость"
          name="monthlyCost"
          type="number"
          value={item.monthlyCost}
          onChange={(value) => onItemChange({ ...item, monthlyCost: parseFloat(value) || 0 })}
          step="0.01"
        />
      </div>
      
      <div className="col-md-6">
        <FormField
          label="Валюта"
          name="monthlyCostCurrency"
          type="select"
          value={item.monthlyCostCurrency}
          onChange={(value) => onItemChange({ ...item, monthlyCostCurrency: value })}
          options={currencyOptions}
        />
      </div>

      <div className="col-md-6">
        <FormField
          label="Следующий платеж"
          name="nextPaymentDate"
          type="date"
          value={item.nextPaymentDate}
          onChange={(value) => onItemChange({ ...item, nextPaymentDate: value })}
        />
      </div>
      
      <div className="col-md-6">
        <FormField
          label="Ссылка для входа"
          name="loginUrl"
          value={item.loginUrl}
          onChange={(value) => onItemChange({ ...item, loginUrl: value })}
          placeholder="panel.hetzner.com"
        />
      </div>

      <div className="col-12">
        <div className="form-label">Статус</div>
        <div className="d-flex gap-2">
          <label className="form-selectgroup-item flex-fill">
            <input 
              type="radio" 
              name="status" 
              value="active" 
              className="form-selectgroup-input"
              checked={item.status === 'active'}
              onChange={() => onItemChange({ ...item, status: 'active' })}
            />
            <span className="form-selectgroup-label">
              <IconCheck size={16} className="me-1" />
              Активен
            </span>
          </label>
          <label className="form-selectgroup-item flex-fill">
            <input 
              type="radio" 
              name="status" 
              value="inactive" 
              className="form-selectgroup-input"
              checked={item.status === 'inactive'}
              onChange={() => onItemChange({ ...item, status: 'inactive' })}
            />
            <span className="form-selectgroup-label">
              <IconX size={16} className="me-1" />
              Неактивен
            </span>
          </label>
        </div>
      </div>

      <div className="col-12">
        <FormField
          label="Заметки"
          name="notes"
          value={item.notes}
          onChange={(value) => onItemChange({ ...item, notes: value })}
          placeholder="Опционально"
        />
      </div>
    </div>
  );
}

// Форма добавления платежа
function PaymentForm({ servers, payment, onChange }) {
  const serverOptions = [
    { value: '', label: 'Выберите сервис' },
    ...servers.map(s => ({ value: s.id, label: `${s.hostName} (${s.provider})` }))
  ];

  const currencyOptions = [
    { value: 'USD', label: 'USD' },
    { value: 'EUR', label: 'EUR' },
    { value: 'RUB', label: 'RUB' }
  ];

  const handleServerChange = (serverId) => {
    const server = servers.find(s => s.id === serverId);
    if (server) {
      onChange({
        ...payment,
        serverId,
        amount: server.monthlyCost || 0,
        currency: server.monthlyCostCurrency || 'USD'
      });
    } else {
      onChange({ ...payment, serverId });
    }
  };

  return (
    <div className="row g-3">
      <div className="col-12">
        <FormField
          label="Сервис"
          name="serverId"
          type="select"
          value={payment.serverId}
          onChange={handleServerChange}
          options={serverOptions}
          required
        />
      </div>
      
      <div className="col-12">
        <FormField
          label="Дата платежа"
          name="date"
          type="date"
          value={payment.date}
          onChange={(value) => onChange({ ...payment, date: value })}
          required
        />
      </div>
      
      <div className="col-md-8">
        <FormField
          label="Сумма"
          name="amount"
          type="number"
          value={payment.amount}
          onChange={(value) => onChange({ ...payment, amount: parseFloat(value) || 0 })}
          step="0.01"
          required
        />
      </div>
      
      <div className="col-md-4">
        <FormField
          label="Валюта"
          name="currency"
          type="select"
          value={payment.currency}
          onChange={(value) => onChange({ ...payment, currency: value })}
          options={currencyOptions}
        />
      </div>
      
      <div className="col-12">
        <FormField
          label="Комментарий"
          name="note"
          value={payment.note}
          onChange={(value) => onChange({ ...payment, note: value })}
          placeholder="Опционально"
        />
      </div>
    </div>
  );
}

export default BillingManager;
