import 'dart:async';

import 'package:commons_core/commons_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';

import '../i18n/strings.g.dart';
import '../services/profile_cache.dart';
import '../services/social_connection.dart';
import 'market_widgets.dart';
import 'theme.dart';

/// Read-only "product page" for one discovered [Offer] (the Wallapop-style
/// detail behind a market card). Shows only what the author elected to publish —
/// summary, reciprocity mode, category, coarse area, price, and the eco flag —
/// plus who's sharing it and a way to message them. It never fetches inventory
/// or an exact address: the privacy seam means the network simply has no more.
class MarketOfferDetailScreen extends StatefulWidget {
  const MarketOfferDetailScreen({
    required this.offer,
    required this.connection,
    this.mine = false,
    this.profileCache,
    super.key,
  });

  final Offer offer;

  /// The shared relay connection, for fetching the author's published profile.
  final SocialConnection connection;

  /// Whether this is the current user's own listing (hide the message button).
  final bool mine;

  /// Optional cache of peers' published display names; null in tests.
  final ProfileCache? profileCache;

  @override
  State<MarketOfferDetailScreen> createState() =>
      _MarketOfferDetailScreenState();
}

class _MarketOfferDetailScreenState extends State<MarketOfferDetailScreen> {
  String? _sellerName;
  String? _sellerAbout;
  String? _sellerG1;
  bool _profileLoading = true;

  @override
  void initState() {
    super.initState();
    _loadSeller();
  }

  /// Best-effort fetch of the author's published profile (name/about/Ğ1), the
  /// same path the chat header uses. Degrades silently when offline.
  Future<void> _loadSeller() async {
    final cachedName = await widget.profileCache?.name(widget.offer.authorPubkeyHex);
    if (mounted && cachedName != null) setState(() => _sellerName = cachedName);

    final session = await widget.connection.session();
    if (!mounted) return;
    if (session == null) {
      setState(() => _profileLoading = false);
      return;
    }
    try {
      final profile = await session.profile.fetch(widget.offer.authorPubkeyHex);
      if (profile != null && profile.name.isNotEmpty) {
        unawaited(widget.profileCache
            ?.setName(widget.offer.authorPubkeyHex, profile.name));
      }
      if (mounted) {
        setState(() {
          if (profile != null && profile.name.isNotEmpty) {
            _sellerName = profile.name;
          }
          _sellerAbout = profile?.about.isNotEmpty == true ? profile!.about : null;
          _sellerG1 = profile?.g1.isNotEmpty == true ? profile!.g1 : null;
          _profileLoading = false;
        });
      }
    } catch (_) {
      if (mounted) setState(() => _profileLoading = false);
    }
  }

  // No dispose of the session — it belongs to the shared connection.

  Future<void> _copyId() async {
    final t = context.t;
    final messenger = ScaffoldMessenger.of(context);
    await Clipboard.setData(
        ClipboardData(text: widget.offer.authorPubkeyHex));
    messenger.showSnackBar(SnackBar(content: Text(t.market.idCopied)));
  }

  @override
  Widget build(BuildContext context) {
    final t = context.t;
    final o = widget.offer;
    return Scaffold(
      appBar: AppBar(title: Text(o.summary)),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          if (o.imageUrl != null) ...[
            OfferHeroImage(url: o.imageUrl!, semanticLabel: t.market.photo),
            const SizedBox(height: 16),
          ],
          Row(
            children: [
              Expanded(
                child: Text(
                  o.summary,
                  style: const TextStyle(
                    fontSize: 22,
                    fontWeight: FontWeight.w600,
                    color: seedTitle,
                  ),
                ),
              ),
              const SizedBox(width: 8),
              OfferTypeChip(label: offerTypeLabel(t, o.type)),
            ],
          ),
          const SizedBox(height: 12),
          Wrap(
            spacing: 8,
            runSpacing: 8,
            children: [
              if (o.isOrganic)
                _Badge(
                  icon: Icons.eco,
                  label: t.editVariety.organic,
                ),
              if (o.category != null && o.category!.isNotEmpty)
                _Badge(icon: Icons.folder_outlined, label: o.category!),
              _Badge(icon: Icons.place_outlined, label: t.market.near),
            ],
          ),
          if (o.type == OfferType.sale && o.priceAmount != null) ...[
            const SizedBox(height: 16),
            Text(
              '${o.priceAmount} ${o.priceCurrency ?? ''}'.trim(),
              style: const TextStyle(
                fontSize: 20,
                fontWeight: FontWeight.w700,
                color: seedOnSurface,
              ),
            ),
          ],
          if (o.type == OfferType.exchange &&
              o.exchangeTerms != null &&
              o.exchangeTerms!.isNotEmpty) ...[
            const SizedBox(height: 16),
            Text(
              o.exchangeTerms!,
              style: const TextStyle(color: seedOnSurface, fontSize: 15),
            ),
          ],
          const SizedBox(height: 24),
          const Divider(),
          const SizedBox(height: 12),
          _SellerSection(
            title: t.market.sharedBy,
            name: _sellerName ?? shortPubkey(o.authorPubkeyHex),
            about: _sellerAbout,
            loading: _profileLoading,
            hasProfile:
                _sellerName != null || _sellerAbout != null || _sellerG1 != null,
            noProfileLabel: t.market.noProfile,
            onCopyId: _copyId,
            copyIdTooltip: t.market.copyId,
          ),
          const SizedBox(height: 24),
          if (!widget.mine)
            FilledButton.icon(
              key: const Key('offerDetail.contact'),
              onPressed: () => context.push('/chat/${o.authorPubkeyHex}'),
              icon: const Icon(Icons.chat_bubble_outline),
              label: Text(t.market.contact),
            ),
        ],
      ),
    );
  }
}

/// A small pill with an icon + label (eco, category, "near you").
class _Badge extends StatelessWidget {
  const _Badge({required this.icon, required this.label});

  final IconData icon;
  final String label;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
      decoration: BoxDecoration(
        color: seedPrimaryContainer.withValues(alpha: 0.5),
        borderRadius: BorderRadius.circular(20),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: [
          Icon(icon, size: 15, color: seedGreen),
          const SizedBox(width: 5),
          Text(label,
              style: const TextStyle(color: seedOnSurface, fontSize: 13)),
        ],
      ),
    );
  }
}

/// "Shared by" card: who's offering this, their bio, and a copy-code affordance.
class _SellerSection extends StatelessWidget {
  const _SellerSection({
    required this.title,
    required this.name,
    required this.about,
    required this.loading,
    required this.hasProfile,
    required this.noProfileLabel,
    required this.onCopyId,
    required this.copyIdTooltip,
  });

  final String title;
  final String name;
  final String? about;
  final bool loading;
  final bool hasProfile;
  final String noProfileLabel;
  final VoidCallback onCopyId;
  final String copyIdTooltip;

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          title,
          style: const TextStyle(
            fontSize: 13,
            color: seedMuted,
            fontWeight: FontWeight.w600,
          ),
        ),
        const SizedBox(height: 8),
        Row(
          children: [
            const CircleAvatar(
              radius: 20,
              backgroundColor: seedPrimaryContainer,
              child: Icon(Icons.person_outline, color: seedGreen),
            ),
            const SizedBox(width: 12),
            Expanded(
              child: Text(
                name,
                style: const TextStyle(
                  fontSize: 16,
                  fontWeight: FontWeight.w500,
                  color: seedOnSurface,
                ),
              ),
            ),
            IconButton(
              key: const Key('offerDetail.copyId'),
              icon: const Icon(Icons.copy, size: 18, color: seedMuted),
              tooltip: copyIdTooltip,
              onPressed: onCopyId,
            ),
          ],
        ),
        if (about != null) ...[
          const SizedBox(height: 8),
          Text(about!,
              style: const TextStyle(color: seedOnSurface, fontSize: 14)),
        ] else if (!loading && !hasProfile) ...[
          const SizedBox(height: 8),
          Text(noProfileLabel,
              style: const TextStyle(color: seedMuted, fontSize: 13)),
        ],
      ],
    );
  }
}
