import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../../../core/api/api_client_provider.dart';
import '../../../core/constants.dart';
import '../../../core/theme/halo_tokens.dart';
import '../../../core/theme/widgets/widgets.dart';
import '../../chat/widgets/bestie_unavailable_dialog.dart';
import '../../payment/state/payment_draft_provider.dart';
import '../providers/bestie_history_provider.dart';

/// `BestieHistoryList` — the picker for the returning-user "curhat lagi"
/// flow (mermaid §4). Visual reference: `screens/v4.jsx::BestieHistoryList`.
///
/// Reached from `BestieChoiceSheet` → "bestie yang udah kenal". Row tap =
/// pick a past bestie → targeted-pair payment flow. Transcript browsing
/// lives in the Chat-tab Selesai sub-tab, not here.
///
/// Row interaction rules:
///   - mitra_is_online + status != closing → tap stamps the picked mitra
///     onto `paymentDraftNotifierProvider` (via `setTargetedMitra`) and
///     pushes `/payment/entry`. The Phase-4 multi-screen payment flow
///     (entry → method-pick → duration-pick → method → waiting → notif-gate
///     → searching) reads the targeting back off the draft to fire the
///     returning-chat request after the customer pays.
///   - status == closing → tap drops into the chat session screen so the
///     user can finish the goodbye composer (one-time grace path).
///   - mitra_is_online == false → row stays dimmed for the visual cue, but
///     tap is enabled and opens [BestieOfflinePopup] with the
///     [BestieOfflineVariant.prePayReturning] variant (Stage 5.3). The popup
///     offers "cari bestie lain" (resets the draft + pushes `/payment/entry`
///     for a fresh blast-payment flow) and `tanya admin`.
class BestieHistoryListScreen extends ConsumerWidget {
  const BestieHistoryListScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final historyAsync = ref.watch(bestieHistoryProvider);
    final rawAsync = ref.watch(_rawHistoryProvider);

    return Scaffold(
      backgroundColor: HaloTokens.bg,
      appBar: AppBar(
        backgroundColor: HaloTokens.bg,
        foregroundColor: HaloTokens.brandDark,
        elevation: 0,
        title: const Text(
          'bestie kamu sebelumnya',
          style: TextStyle(
            fontFamily: HaloTokens.fontDisplay,
            fontSize: 20,
            fontWeight: FontWeight.w700,
            color: HaloTokens.brandDark,
          ),
        ),
      ),
      body: historyAsync.when(
        loading: () => const Center(child: CircularProgressIndicator()),
        error: (_, __) => const Center(
          child: Text(
            'gagal memuat riwayat. tarik untuk muat ulang.',
            style: TextStyle(fontFamily: HaloTokens.fontBody),
          ),
        ),
        data: (items) {
          if (items.isEmpty) {
            return const Center(
              child: Padding(
                padding: EdgeInsets.symmetric(horizontal: HaloSpacing.s24),
                child: Text(
                  'belum ada bestie sebelumnya. coba bestie baru dulu ya.',
                  textAlign: TextAlign.center,
                  style: TextStyle(
                    fontFamily: HaloTokens.fontBody,
                    color: HaloTokens.inkSoft,
                  ),
                ),
              ),
            );
          }
          return RefreshIndicator(
            onRefresh: () async {
              ref.invalidate(bestieHistoryProvider);
              ref.invalidate(_rawHistoryProvider);
              await ref.read(bestieHistoryProvider.future);
            },
            child: ListView.separated(
              padding: const EdgeInsets.symmetric(
                horizontal: HaloSpacing.s20,
                vertical: HaloSpacing.s12,
              ),
              itemCount: items.length + 1,
              separatorBuilder: (_, __) =>
                  const SizedBox(height: HaloSpacing.s12),
              itemBuilder: (context, index) {
                if (index == 0) {
                  return Padding(
                    padding: const EdgeInsets.only(
                      bottom: HaloSpacing.s8,
                      left: 2,
                    ),
                    child: Text(
                      '${items.length} bestie yang pernah nemenin kamu',
                      style: const TextStyle(
                        fontFamily: HaloTokens.fontBody,
                        fontSize: 13,
                        color: HaloTokens.inkSoft,
                      ),
                    ),
                  );
                }
                final item = items[index - 1];
                final raw = rawAsync.valueOrNull?[index - 1];
                final isClosing = raw?['status'] == SessionStatus.closing;
                return _BestieRow(
                  item: item,
                  isClosing: isClosing,
                  onPick: () {
                    if (isClosing) {
                      context.push(
                        '/chat/session/${item.sessionId}',
                        extra: item.mitraName,
                      );
                      return;
                    }
                    // Offline mitra — surface the Stage 5.3 pre-payment
                    // popup. The popup's "cari bestie lain" CTA resets the
                    // draft and pushes `/payment/entry` for a blast flow.
                    if (!item.mitraIsOnline) {
                      // ignore: discarded_futures
                      BestieOfflinePopup.show(
                        context,
                        variant: BestieOfflineVariant.prePayReturning,
                        mitraName: item.mitraName,
                      );
                      return;
                    }
                    if (item.mitraId == null) return;
                    // Stamp the targeted mitra onto the payment draft; the
                    // multi-screen payment flow (entry → method → waiting →
                    // notif-gate → searching) reads it back to fire the
                    // returning-chat request after payment confirms.
                    ref.read(paymentDraftNotifierProvider.notifier)
                        .setTargetedMitra(
                          mitraId: item.mitraId!,
                          mitraName: item.mitraName,
                        );
                    context.push('/payment/entry');
                  },
                );
              },
            ),
          );
        },
      ),
    );
  }
}

/// Raw history payload — used to read fields the v4 `BestieHistoryItem`
/// model doesn't surface (currently `status`, for the closing-row branch).
final _rawHistoryProvider =
    FutureProvider<List<Map<String, dynamic>>>((ref) async {
  final api = ref.read(apiClientProvider);
  final response = await api.get('/api/client/chat/history');
  return ((response['data']['items'] as List?) ?? const [])
      .cast<Map<String, dynamic>>();
});

class _BestieRow extends StatelessWidget {
  final BestieHistoryItem item;
  final bool isClosing;
  final VoidCallback onPick;

  const _BestieRow({
    required this.item,
    required this.isClosing,
    required this.onPick,
  });

  @override
  Widget build(BuildContext context) {
    // Online + has mitraId → full-colour, taps into targeted-pair payment.
    // Closing → full-colour, taps into the goodbye composer (mitraId may be
    // absent but `sessionId` is what the chat route needs).
    // Offline → dim, but still tappable so [BestieOfflinePopup] can fire the
    // Stage 5.3 pre-payment branch.
    final isLive = item.mitraIsOnline && item.mitraId != null;
    final tappable = isLive || isClosing || !item.mitraIsOnline;
    final dim = !isLive && !isClosing;
    return Material(
      color: HaloTokens.surface,
      borderRadius: HaloRadius.lg,
      child: InkWell(
        onTap: tappable ? onPick : null,
        borderRadius: HaloRadius.lg,
        child: Opacity(
          opacity: dim ? 0.55 : 1.0,
          child: Padding(
            padding: const EdgeInsets.all(HaloSpacing.s16),
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                HaloOrb(
                  size: 56,
                  seed: (item.mitraId ?? item.mitraName).hashCode,
                  label: item.mitraName,
                ),
                const SizedBox(width: HaloSpacing.s12),
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Row(
                        children: [
                          Flexible(
                            child: Text(
                              'bestie ${item.mitraName}',
                              overflow: TextOverflow.ellipsis,
                              style: const TextStyle(
                                fontFamily: HaloTokens.fontBody,
                                fontSize: 15,
                                fontWeight: FontWeight.w700,
                                color: HaloTokens.ink,
                              ),
                            ),
                          ),
                          if (item.mitraIsOnline) ...[
                            const SizedBox(width: HaloSpacing.s8),
                            const _OnlinePill(),
                          ],
                          if (isClosing) ...[
                            const SizedBox(width: HaloSpacing.s8),
                            const _ClosingBadge(),
                          ],
                        ],
                      ),
                      const SizedBox(height: 2),
                      Text(
                        [
                          '${item.sessionsCount}× sesi',
                          if (item.endedAt != null)
                            'terakhir ${_formatDate(item.endedAt!)}',
                        ].join(' · '),
                        style: const TextStyle(
                          fontFamily: HaloTokens.fontBody,
                          fontSize: 12,
                          color: HaloTokens.inkSoft,
                        ),
                      ),
                      if (item.topics.isNotEmpty) ...[
                        const SizedBox(height: 2),
                        Text(
                          '"${item.topics.first}"',
                          overflow: TextOverflow.ellipsis,
                          style: const TextStyle(
                            fontFamily: HaloTokens.fontBody,
                            fontSize: 11.5,
                            fontStyle: FontStyle.italic,
                            color: HaloTokens.inkMuted,
                          ),
                        ),
                      ],
                    ],
                  ),
                ),
                const SizedBox(width: HaloSpacing.s8),
                Text(
                  '→',
                  style: TextStyle(
                    fontSize: 16,
                    color: dim ? HaloTokens.inkMuted : HaloTokens.brand,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  String _formatDate(DateTime d) =>
      '${d.day.toString().padLeft(2, '0')}/${d.month.toString().padLeft(2, '0')}/${d.year}';
}

class _OnlinePill extends StatelessWidget {
  const _OnlinePill();

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
      decoration: BoxDecoration(
        color: HaloTokens.success.withAlpha(36),
        borderRadius: BorderRadius.circular(999),
      ),
      child: const Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          _Dot(color: HaloTokens.success),
          SizedBox(width: 4),
          Text(
            'ONLINE',
            style: TextStyle(
              fontFamily: HaloTokens.fontBody,
              fontSize: 10,
              fontWeight: FontWeight.w700,
              letterSpacing: 0.6,
              color: HaloTokens.success,
            ),
          ),
        ],
      ),
    );
  }
}

class _Dot extends StatelessWidget {
  final Color color;
  const _Dot({required this.color});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 6,
      height: 6,
      decoration: BoxDecoration(color: color, shape: BoxShape.circle),
    );
  }
}

class _ClosingBadge extends StatelessWidget {
  const _ClosingBadge();

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
      decoration: BoxDecoration(
        color: HaloTokens.accentSoft,
        borderRadius: BorderRadius.circular(999),
      ),
      child: const Text(
        'Belum ditutup',
        style: TextStyle(
          fontFamily: HaloTokens.fontBody,
          fontSize: 10,
          fontWeight: FontWeight.w600,
          color: HaloTokens.brandDark,
        ),
      ),
    );
  }
}
