import 'dart:convert';

import 'package:flutter/material.dart';

import '../application/application.dart';
import '../domain/domain.dart';
import 'theme.dart';

final class ShareInboxScreen extends StatefulWidget {
  const ShareInboxScreen({required this.shareUseCases, super.key});

  final ShareUseCases shareUseCases;

  @override
  State<ShareInboxScreen> createState() => _ShareInboxScreenState();
}

final class _ShareInboxScreenState extends State<ShareInboxScreen> {
  late Future<List<ShareInboxItem>> _items;

  @override
  void initState() {
    super.initState();
    _items = widget.shareUseCases.refreshInbox();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Partages reçus')),
      body: FutureBuilder<List<ShareInboxItem>>(
        future: _items,
        builder: (context, snapshot) {
          if (snapshot.connectionState != ConnectionState.done) {
            return const Center(child: CircularProgressIndicator());
          }
          final items = snapshot.data ?? const <ShareInboxItem>[];
          if (items.isEmpty) {
            return const _EmptyInbox();
          }
          return RefreshIndicator(
            onRefresh: _reload,
            child: ListView.separated(
              padding: const EdgeInsets.all(16),
              itemBuilder: (context, index) {
                final item = items[index];
                return _ShareInboxTile(
                  item: item,
                  onAccept: item.status == ShareInboxStatus.pending
                      ? () => _accept(item)
                      : null,
                  onDecline: item.status == ShareInboxStatus.pending
                      ? () => _decline(item)
                      : null,
                );
              },
              separatorBuilder: (context, index) => const SizedBox(height: 12),
              itemCount: items.length,
            ),
          );
        },
      ),
    );
  }

  Future<void> _reload() async {
    setState(() {
      _items = widget.shareUseCases.refreshInbox();
    });
    await _items;
  }

  Future<void> _accept(ShareInboxItem item) async {
    await widget.shareUseCases.acceptShare(item.shareId);
    if (!mounted) return;
    await _reload();
    if (!mounted) return;
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(_acceptedMessage(item.resourceType))),
    );
  }

  Future<void> _decline(ShareInboxItem item) async {
    await widget.shareUseCases.declineShare(item.shareId);
    if (!mounted) return;
    await _reload();
    if (!mounted) return;
    ScaffoldMessenger.of(
      context,
    ).showSnackBar(const SnackBar(content: Text('Partage refusé.')));
  }
}

final class _ShareInboxTile extends StatelessWidget {
  const _ShareInboxTile({
    required this.item,
    required this.onAccept,
    required this.onDecline,
  });

  final ShareInboxItem item;
  final VoidCallback? onAccept;
  final VoidCallback? onDecline;

  @override
  Widget build(BuildContext context) {
    final summary = _summaryFromPayload(item);
    return CourtBlazerAccentPanel(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Icon(
                item.resourceType == ShareResourceType.program
                    ? Icons.list_alt
                    : Icons.event_note,
              ),
              const SizedBox(width: 12),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      _resourceTitle(item.resourceType),
                      style: Theme.of(context).textTheme.labelLarge,
                    ),
                    const SizedBox(height: 4),
                    Text(
                      summary.name,
                      style: Theme.of(context).textTheme.titleMedium,
                    ),
                    const SizedBox(height: 4),
                    Text('Envoyé par ${item.senderUserId}'),
                    if (summary.detail.isNotEmpty) ...[
                      const SizedBox(height: 4),
                      Text(summary.detail),
                    ],
                  ],
                ),
              ),
              Chip(
                visualDensity: VisualDensity.compact,
                label: Text(_statusLabel(item.status)),
              ),
            ],
          ),
          if (item.status == ShareInboxStatus.pending) ...[
            const SizedBox(height: 16),
            Row(
              children: [
                Expanded(
                  child: OutlinedButton(
                    onPressed: onDecline,
                    child: const Text('Refuser'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: FilledButton(
                    onPressed: onAccept,
                    child: const Text('Accepter'),
                  ),
                ),
              ],
            ),
          ],
        ],
      ),
    );
  }
}

final class _EmptyInbox extends StatelessWidget {
  const _EmptyInbox();

  @override
  Widget build(BuildContext context) {
    return const Center(
      child: Padding(
        padding: EdgeInsets.all(24),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text('Aucun partage reçu', textAlign: TextAlign.center),
            SizedBox(height: 8),
            Text(
              "Les programmes et séances qu'on t'envoie apparaîtront ici.",
              textAlign: TextAlign.center,
            ),
          ],
        ),
      ),
    );
  }
}

final class _InboxSummary {
  const _InboxSummary({required this.name, required this.detail});

  final String name;
  final String detail;
}

_InboxSummary _summaryFromPayload(ShareInboxItem item) {
  try {
    final payload = jsonDecode(item.payloadJson) as Map<String, dynamic>;
    final name = payload['name'] as String? ?? 'Partage GameTime';
    return switch (item.resourceType) {
      ShareResourceType.program => _InboxSummary(
        name: name,
        detail: _programDetail(payload),
      ),
      ShareResourceType.workoutTemplate => _InboxSummary(
        name: name,
        detail: _templateDetail(payload),
      ),
    };
  } on Object {
    return const _InboxSummary(name: 'Partage GameTime', detail: '');
  }
}

String _programDetail(Map<String, dynamic> payload) {
  final exercises = payload['exercises'] as List<dynamic>? ?? const [];
  final sets = exercises.fold<int>(0, (total, raw) {
    final exercise = raw as Map<String, dynamic>;
    return total + (exercise['setsCount'] as int? ?? 0);
  });
  return '${exercises.length} exercice${exercises.length > 1 ? 's' : ''} · '
      '$sets série${sets > 1 ? 's' : ''}';
}

String _templateDetail(Map<String, dynamic> payload) {
  final programs = payload['programs'] as List<dynamic>? ?? const [];
  var exerciseCount = 0;
  for (final raw in programs) {
    final program = raw as Map<String, dynamic>;
    final snapshotJson = program['programSnapshotJson'] as String?;
    if (snapshotJson == null) continue;
    final snapshot = jsonDecode(snapshotJson) as Map<String, dynamic>;
    exerciseCount +=
        (snapshot['exercises'] as List<dynamic>? ?? const []).length;
  }
  return '${programs.length} programme${programs.length > 1 ? 's' : ''} · '
      '$exerciseCount exercice${exerciseCount > 1 ? 's' : ''}';
}

String _resourceTitle(ShareResourceType type) {
  return switch (type) {
    ShareResourceType.program => 'Programme',
    ShareResourceType.workoutTemplate => 'Séance',
  };
}

String _statusLabel(ShareInboxStatus status) {
  return switch (status) {
    ShareInboxStatus.pending => 'À traiter',
    ShareInboxStatus.accepted => 'Accepté',
    ShareInboxStatus.declined => 'Refusé',
    ShareInboxStatus.revoked => 'Retiré',
  };
}

String _acceptedMessage(ShareResourceType type) {
  return switch (type) {
    ShareResourceType.program => 'Programme ajouté.',
    ShareResourceType.workoutTemplate => 'Séance ajoutée.',
  };
}
