import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../../../core/providers/auth_provider.dart';
import '../../../core/providers/locale_provider.dart';
import '../../../core/theme/app_theme.dart';
import '../../../core/utils/currency_formatter.dart';
import '../../../core/widgets/gradient_app_bar.dart';
import '../../../core/widgets/pill_tabs.dart';
import '../../../models/finance_entry.dart';
import 'lab_finance_repository.dart';

enum _FinanceSort { newestFirst, byAmountDesc, byAmountAsc }

class LabFinanceScreen extends ConsumerStatefulWidget {
  const LabFinanceScreen({super.key});

  @override
  ConsumerState<LabFinanceScreen> createState() => _LabFinanceScreenState();
}

class _LabFinanceScreenState extends ConsumerState<LabFinanceScreen>
    with SingleTickerProviderStateMixin {
  late TabController _tabController;
  late Future<_FinanceData> _future;
  _FinanceSort _sort = _FinanceSort.newestFirst;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 2, vsync: this);
    _tabController.addListener(() {
      if (mounted) setState(() {});
    });
    _load();
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  void _load() {
    final tenantId = ref.read(authProvider).activeTenant!.tenant.id;
    setState(() {
      _future = Future.wait([
        LabFinanceRepository.instance.listEntries(tenantId, status: 'pending'),
        LabFinanceRepository.instance.listEntries(tenantId, status: 'paid'),
        LabFinanceRepository.instance.summary(tenantId),
        LabFinanceRepository.instance.byCounterparty(tenantId),
      ]).then((results) => _FinanceData(
            pending: results[0] as List<FinanceEntry>,
            paid: results[1] as List<FinanceEntry>,
            summary: results[2] as Map<String, double>,
            counterparties: results[3] as List<CounterpartyFinanceSummary>,
          ));
    });
  }

  Future<void> _showSortOptions() async {
    final s = ref.read(stringsProvider);
    final result = await showSortSheet(
      context,
      title: s.sort,
      options: [s.sortNewest, s.sortAmountDesc, s.sortAmountAsc],
      current: _sort.index,
    );
    if (result != null) {
      setState(() => _sort = _FinanceSort.values[result]);
    }
  }

  List<FinanceEntry> _sorted(List<FinanceEntry> entries) {
    final list = List<FinanceEntry>.from(entries);
    switch (_sort) {
      case _FinanceSort.newestFirst:
        list.sort((a, b) {
          final da =
              a.dateCreated != null ? DateTime.tryParse(a.dateCreated!) : null;
          final db =
              b.dateCreated != null ? DateTime.tryParse(b.dateCreated!) : null;
          if (da == null && db == null) return 0;
          if (da == null) return 1;
          if (db == null) return -1;
          return db.compareTo(da);
        });
      case _FinanceSort.byAmountDesc:
        list.sort((a, b) => b.amount.compareTo(a.amount));
      case _FinanceSort.byAmountAsc:
        list.sort((a, b) => a.amount.compareTo(b.amount));
    }
    return list;
  }

  String _formatDate(String? raw) {
    if (raw == null) return '';
    try {
      final dt = DateTime.parse(raw);
      return '${dt.day.toString().padLeft(2, '0')}.${dt.month.toString().padLeft(2, '0')}.${dt.year}';
    } catch (_) {
      return '';
    }
  }

  Future<void> _confirmPayment(
    FinanceEntry entry,
    String Function(double) formatAmount,
  ) async {
    final confirmed = await showDialog<bool>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: const Text('Ödeme Onayla'),
        content: Text(
          '${entry.counterpartyName ?? "Bu kayıt"} için '
          '${formatAmount(entry.amount)} tutarındaki ödemenin '
          'hesabınıza ulaştığını onaylıyor musunuz?',
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(ctx, false),
            child: const Text('İptal'),
          ),
          FilledButton(
            onPressed: () => Navigator.pop(ctx, true),
            child: const Text('Onayla'),
          ),
        ],
      ),
    );
    if (confirmed != true || !mounted) return;
    try {
      await LabFinanceRepository.instance.confirmPayment(entry.id);
      _load();
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Ödeme onaylandı.')),
        );
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Hata: $e')),
        );
      }
    }
  }

  Future<void> _confirmCounterpartyPayments(
    CounterpartyFinanceSummary item,
    List<FinanceEntry> pending,
    String Function(double) formatAmount,
  ) async {
    final entries = pending
        .where((entry) =>
            entry.status.isOpen &&
            (entry.counterpartyTenantId == item.counterpartyTenantId ||
                entry.counterpartyName == item.counterpartyName))
        .toList();
    if (entries.isEmpty) return;

    final confirmed = await showDialog<bool>(
      context: context,
      builder: (ctx) => AlertDialog(
        title: const Text('Toplu Ödeme Onayla'),
        content: Text(
          '${item.counterpartyName} için ${entries.length} açık kayıt '
          '${formatAmount(item.pendingAmount)} toplam tutarla onaylansın mı?',
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(ctx, false),
            child: const Text('İptal'),
          ),
          FilledButton(
            onPressed: () => Navigator.pop(ctx, true),
            child: const Text('Toplu Onayla'),
          ),
        ],
      ),
    );
    if (confirmed != true || !mounted) return;

    try {
      await LabFinanceRepository.instance.confirmPayments(entries);
      _load();
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Toplu ödeme onaylandı.')),
        );
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Hata: $e')),
        );
      }
    }
  }

  Future<void> _sendPaymentReminder(CounterpartyFinanceSummary item) async {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(
          '${item.counterpartyName} için ödeme hatırlatması hazırlandı.',
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    final isSortActive = _sort != _FinanceSort.newestFirst;
    final s = ref.watch(stringsProvider);
    final currencyCode =
        ref.watch(authProvider).activeTenant?.tenant.defaultCurrency ?? 'TRY';
    String formatAmount(double amount) =>
        CurrencyFormatter.format(amount, currencyCode);

    return Scaffold(
      backgroundColor: AppColors.background,
      appBar: GradientAppBar(
        title: s.finance,
        category: s.laboratoryCategory,
        actions: [
          IconButton(
            onPressed: _showSortOptions,
            tooltip: 'Sırala',
            icon: Badge(
              isLabelVisible: isSortActive,
              smallSize: 8,
              backgroundColor: AppColors.accent,
              child: const Icon(Icons.sort_rounded),
            ),
          ),
        ],
      ),
      body: RefreshIndicator(
        color: AppColors.accent,
        onRefresh: () async => _load(),
        child: FutureBuilder<_FinanceData>(
          future: _future,
          builder: (ctx, snap) {
            if (snap.connectionState == ConnectionState.waiting) {
              return const Center(
                  child: CircularProgressIndicator(color: AppColors.accent));
            }
            if (snap.hasError) {
              return Center(
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Container(
                      width: 64,
                      height: 64,
                      decoration: BoxDecoration(
                          color: AppColors.cancelledBg,
                          borderRadius: BorderRadius.circular(16)),
                      child: const Icon(Icons.wifi_off_rounded,
                          color: AppColors.cancelled, size: 30),
                    ),
                    const SizedBox(height: 16),
                    Text('Hata: ${snap.error}',
                        style: const TextStyle(color: AppColors.textSecondary)),
                    const SizedBox(height: 12),
                    FilledButton.icon(
                      onPressed: _load,
                      icon: const Icon(Icons.refresh_rounded, size: 18),
                      label: const Text('Tekrar Dene'),
                    ),
                  ],
                ),
              );
            }

            final data = snap.data!;
            final pendingTotal = data.summary['pending'] ?? 0.0;
            final paidTotal = data.summary['paid'] ?? 0.0;
            final pending = _sorted(data.pending);
            final paid = _sorted(data.paid);

            return Column(
              children: [
                Padding(
                  padding: const EdgeInsets.all(16),
                  child: Row(
                    children: [
                      Expanded(
                        child: _SummaryCard(
                          label: 'Açık Alacak',
                          amount: formatAmount(pendingTotal),
                          color: AppColors.pending,
                          bgColor: AppColors.pendingBg,
                          icon: Icons.hourglass_empty_rounded,
                        ),
                      ),
                      const SizedBox(width: 12),
                      Expanded(
                        child: _SummaryCard(
                          label: 'Onaylanan Tahsilat',
                          amount: formatAmount(paidTotal),
                          color: AppColors.success,
                          bgColor: AppColors.successBg,
                          icon: Icons.check_circle_outline,
                        ),
                      ),
                    ],
                  ),
                ),
                if (data.counterparties.isNotEmpty)
                  Padding(
                    padding: const EdgeInsets.fromLTRB(16, 0, 16, 12),
                    child: _CounterpartySummaryList(
                      title: 'Klinik Bazlı Alacak',
                      items: data.counterparties,
                      formatAmount: formatAmount,
                      onConfirmAll: (item) => _confirmCounterpartyPayments(
                          item, pending, formatAmount),
                      onSendReminder: _sendPaymentReminder,
                    ),
                  ),
                PillTabs(
                  tabs: [s.pending, s.collected],
                  selected: _tabController.index,
                  onSelect: (i) => _tabController.animateTo(i),
                  counts: [pending.length, paid.length],
                ),
                Expanded(
                  child: TabBarView(
                    controller: _tabController,
                    children: [
                      _EntriesList(
                        entries: pending,
                        emptyMessage: s.noPendingEntries,
                        emptyIcon: Icons.hourglass_empty_rounded,
                        formatDate: _formatDate,
                        formatAmount: formatAmount,
                        onConfirmPayment: (entry) =>
                            _confirmPayment(entry, formatAmount),
                      ),
                      _EntriesList(
                        entries: paid,
                        emptyMessage: s.noPaidEntries,
                        emptyIcon: Icons.check_circle_outline,
                        formatDate: _formatDate,
                        formatAmount: formatAmount,
                      ),
                    ],
                  ),
                ),
              ],
            );
          },
        ),
      ),
    );
  }
}

class _FinanceData {
  const _FinanceData({
    required this.pending,
    required this.paid,
    required this.summary,
    required this.counterparties,
  });

  final List<FinanceEntry> pending;
  final List<FinanceEntry> paid;
  final Map<String, double> summary;
  final List<CounterpartyFinanceSummary> counterparties;
}

class _SummaryCard extends StatelessWidget {
  const _SummaryCard({
    required this.label,
    required this.amount,
    required this.color,
    required this.bgColor,
    required this.icon,
  });

  final String label;
  final String amount;
  final Color color;
  final Color bgColor;
  final IconData icon;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(16),
      decoration: BoxDecoration(
        color: AppColors.surface,
        borderRadius: BorderRadius.circular(16),
        border: Border.all(color: AppColors.border),
        boxShadow: [
          BoxShadow(
              color: Colors.black.withValues(alpha: 0.06),
              blurRadius: 12,
              offset: const Offset(0, 4))
        ],
      ),
      child: Row(
        children: [
          Container(
            width: 44,
            height: 44,
            decoration: BoxDecoration(
                color: bgColor, borderRadius: BorderRadius.circular(12)),
            child: Icon(icon, color: color, size: 22),
          ),
          const SizedBox(width: 12),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  amount,
                  style: TextStyle(
                      fontSize: 18,
                      fontWeight: FontWeight.w800,
                      color: color,
                      height: 1),
                ),
                const SizedBox(height: 3),
                Text(label,
                    style: const TextStyle(
                        fontSize: 12,
                        color: AppColors.textSecondary,
                        fontWeight: FontWeight.w500)),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

class _EntriesList extends StatelessWidget {
  const _EntriesList({
    required this.entries,
    required this.emptyMessage,
    required this.emptyIcon,
    required this.formatDate,
    required this.formatAmount,
    this.onConfirmPayment,
  });

  final List<FinanceEntry> entries;
  final String emptyMessage;
  final IconData emptyIcon;
  final String Function(String?) formatDate;
  final String Function(double) formatAmount;
  final Future<void> Function(FinanceEntry entry)? onConfirmPayment;

  @override
  Widget build(BuildContext context) {
    if (entries.isEmpty) {
      return Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Container(
              width: 72,
              height: 72,
              decoration: BoxDecoration(
                  color: AppColors.inProgressBg,
                  borderRadius: BorderRadius.circular(20)),
              child: Icon(emptyIcon, size: 32, color: AppColors.inProgress),
            ),
            const SizedBox(height: 16),
            Text(emptyMessage,
                style: const TextStyle(
                    fontSize: 16,
                    fontWeight: FontWeight.w600,
                    color: AppColors.textPrimary)),
          ],
        ),
      );
    }

    return ListView.builder(
      padding: const EdgeInsets.fromLTRB(16, 8, 16, 24),
      itemCount: entries.length,
      itemBuilder: (ctx, i) {
        final entry = entries[i];
        final isPending = entry.status == FinanceStatus.pending;
        final isReported = entry.status == FinanceStatus.reported;
        final statusColor = isPending
            ? AppColors.pending
            : isReported
                ? AppColors.accent
                : AppColors.success;
        final statusBg = isPending
            ? AppColors.pendingBg
            : isReported
                ? AppColors.inProgressBg
                : AppColors.successBg;

        return Padding(
          padding: const EdgeInsets.only(bottom: 10),
          child: Material(
            color: AppColors.surface,
            borderRadius: BorderRadius.circular(14),
            child: InkWell(
              onTap: isReported && onConfirmPayment != null
                  ? () => onConfirmPayment!(entry)
                  : null,
              borderRadius: BorderRadius.circular(14),
              child: Container(
                padding: const EdgeInsets.all(14),
                decoration: BoxDecoration(
                  color: AppColors.surface,
                  borderRadius: BorderRadius.circular(14),
                  border: Border.all(color: AppColors.border),
                  boxShadow: [
                    BoxShadow(
                        color: Colors.black.withValues(alpha: 0.04),
                        blurRadius: 8,
                        offset: const Offset(0, 2))
                  ],
                ),
                child: Row(
                  children: [
                    Container(
                      width: 44,
                      height: 44,
                      decoration: BoxDecoration(
                          color: statusBg,
                          borderRadius: BorderRadius.circular(12)),
                      child: Icon(
                        isPending
                            ? Icons.hourglass_empty_rounded
                            : isReported
                                ? Icons.verified_outlined
                                : Icons.check_circle_outline,
                        color: statusColor,
                        size: 22,
                      ),
                    ),
                    const SizedBox(width: 12),
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            entry.counterpartyName ?? 'Klinik',
                            style: const TextStyle(
                                fontSize: 15,
                                fontWeight: FontWeight.w600,
                                color: AppColors.textPrimary),
                          ),
                          if (entry.patientCode != null) ...[
                            const SizedBox(height: 2),
                            Text(
                              'Protokol: ${entry.patientCode}',
                              style: const TextStyle(
                                  fontSize: 12, color: AppColors.textSecondary),
                            ),
                          ],
                          if (entry.dateCreated != null) ...[
                            const SizedBox(height: 2),
                            Text(
                              formatDate(entry.dateCreated),
                              style: const TextStyle(
                                  fontSize: 12, color: AppColors.textMuted),
                            ),
                          ],
                          if (isReported) ...[
                            const SizedBox(height: 4),
                            const Text(
                              'Dokunarak ödeme onayı verebilirsiniz.',
                              style: TextStyle(
                                  fontSize: 12, color: AppColors.textSecondary),
                            ),
                          ] else if (isPending) ...[
                            const SizedBox(height: 4),
                            const Text(
                              'Klinikten ödeme bildirimi bekleniyor.',
                              style: TextStyle(
                                  fontSize: 12, color: AppColors.textSecondary),
                            ),
                          ],
                        ],
                      ),
                    ),
                    const SizedBox(width: 8),
                    Column(
                      crossAxisAlignment: CrossAxisAlignment.end,
                      children: [
                        Text(
                          formatAmount(entry.amount),
                          style: TextStyle(
                            fontWeight: FontWeight.w700,
                            color: statusColor,
                            fontSize: 15,
                          ),
                        ),
                        const SizedBox(height: 4),
                        Container(
                          padding: const EdgeInsets.symmetric(
                              horizontal: 8, vertical: 2),
                          decoration: BoxDecoration(
                            color: statusBg,
                            borderRadius: BorderRadius.circular(8),
                          ),
                          child: Text(
                            entry.status.label,
                            style: TextStyle(
                              color: statusColor,
                              fontSize: 11,
                              fontWeight: FontWeight.w600,
                            ),
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
      },
    );
  }
}

class _CounterpartySummaryList extends StatelessWidget {
  const _CounterpartySummaryList({
    required this.title,
    required this.items,
    required this.formatAmount,
    required this.onConfirmAll,
    required this.onSendReminder,
  });

  final String title;
  final List<CounterpartyFinanceSummary> items;
  final String Function(double) formatAmount;
  final Future<void> Function(CounterpartyFinanceSummary item) onConfirmAll;
  final Future<void> Function(CounterpartyFinanceSummary item) onSendReminder;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.all(14),
      decoration: BoxDecoration(
        color: AppColors.surface,
        borderRadius: BorderRadius.circular(16),
        border: Border.all(color: AppColors.border),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            title,
            style: const TextStyle(
              fontSize: 14,
              fontWeight: FontWeight.w700,
              color: AppColors.textPrimary,
            ),
          ),
          const SizedBox(height: 10),
          for (final item in items.take(5)) ...[
            Row(
              children: [
                Expanded(
                  child: Text(
                    item.counterpartyName,
                    style: const TextStyle(
                      fontSize: 13,
                      color: AppColors.textPrimary,
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                ),
                Text(
                  formatAmount(item.pendingAmount),
                  style: const TextStyle(
                    fontSize: 13,
                    color: AppColors.pending,
                    fontWeight: FontWeight.w700,
                  ),
                ),
                if (item.pendingAmount > 0) ...[
                  const SizedBox(width: 8),
                  IconButton(
                    onPressed: () => onSendReminder(item),
                    tooltip: 'Ödeme hatırlat',
                    icon: const Icon(Icons.notifications_active_outlined),
                    color: AppColors.pending,
                    visualDensity: VisualDensity.compact,
                  ),
                  TextButton.icon(
                    onPressed: () => onConfirmAll(item),
                    icon: const Icon(Icons.done_all_rounded, size: 16),
                    label: const Text('Toplu Onay'),
                    style: TextButton.styleFrom(
                      foregroundColor: AppColors.success,
                      padding: const EdgeInsets.symmetric(horizontal: 8),
                      visualDensity: VisualDensity.compact,
                    ),
                  ),
                ],
              ],
            ),
            const SizedBox(height: 8),
          ],
        ],
      ),
    );
  }
}
