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

import '../theme/theme_extension.dart';
import 'client_update_provider.dart';
import 'update_info.dart';

/// Soft banner mounted at the top of the shell. Renders nothing when
/// no update is available or the user has dismissed this version's
/// banner. Tapping Install downloads the APK and fires the system
/// install intent (Android only).
class UpdateBanner extends ConsumerStatefulWidget {
  const UpdateBanner({super.key});

  @override
  ConsumerState<UpdateBanner> createState() => _UpdateBannerState();
}

enum _Stage { idle, downloading, error }

class _UpdateBannerState extends ConsumerState<UpdateBanner> {
  _Stage _stage = _Stage.idle;
  double _progress = 0;
  String? _error;

  Future<void> _onInstall(UpdateInfo info) async {
    setState(() {
      _stage = _Stage.downloading;
      _progress = 0;
      _error = null;
    });
    try {
      final installer = await ref.read(updateInstallerProvider.future);
      final path = await installer.download(
        info.apkUrl,
        onProgress: (p) => setState(() => _progress = p),
      );
      await installer.install(path);
      // Stage stays 'downloading' — Android system install dialog has
      // taken over. If user cancels, the banner is still here.
    } catch (e) {
      if (!mounted) return;
      setState(() {
        _stage = _Stage.error;
        _error = '$e';
      });
    }
  }

  void _onDismiss(UpdateInfo info) {
    ref.read(dismissUpdateProvider)(info.version);
  }

  @override
  Widget build(BuildContext context) {
    final info = ref.watch(shouldShowUpdateBannerProvider);
    if (info == null) return const SizedBox.shrink();
    final fs = Theme.of(context).extension<FabledSwordTheme>()!;

    return Material(
      color: fs.iron,
      child: SafeArea(
        bottom: false,
        child: Padding(
          padding: const EdgeInsets.fromLTRB(12, 4, 4, 4),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Icon(LucideIcons.download, color: fs.parchment, size: 16),
              const SizedBox(width: 8),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Text(
                      _stage == _Stage.error
                          ? 'Update failed'
                          : 'Update Minstrel · ${info.version} available',
                      style: TextStyle(color: fs.parchment, fontSize: 12),
                      overflow: TextOverflow.ellipsis,
                    ),
                    if (_stage == _Stage.downloading) ...[
                      const SizedBox(height: 2),
                      LinearProgressIndicator(
                        value: _progress > 0 ? _progress : null,
                        minHeight: 2,
                        backgroundColor: fs.obsidian,
                        valueColor: AlwaysStoppedAnimation(fs.accent),
                      ),
                    ],
                    if (_stage == _Stage.error && _error != null) ...[
                      const SizedBox(height: 1),
                      Text(
                        _error!,
                        style: TextStyle(color: fs.ash, fontSize: 11),
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ],
                  ],
                ),
              ),
              if (_stage == _Stage.idle)
                TextButton(
                  onPressed: () => _onInstall(info),
                  style: TextButton.styleFrom(
                    foregroundColor: fs.accent,
                    minimumSize: const Size(56, 28),
                    padding: const EdgeInsets.symmetric(horizontal: 8),
                    tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                    visualDensity: VisualDensity.compact,
                  ),
                  child: const Text('Install', style: TextStyle(fontSize: 13)),
                ),
              if (_stage == _Stage.error)
                TextButton(
                  onPressed: () => _onInstall(info),
                  style: TextButton.styleFrom(
                    foregroundColor: fs.accent,
                    minimumSize: const Size(56, 28),
                    padding: const EdgeInsets.symmetric(horizontal: 8),
                    tapTargetSize: MaterialTapTargetSize.shrinkWrap,
                    visualDensity: VisualDensity.compact,
                  ),
                  child: const Text('Retry', style: TextStyle(fontSize: 13)),
                ),
              SizedBox(
                width: 32,
                height: 32,
                child: IconButton(
                  tooltip: 'Dismiss',
                  padding: EdgeInsets.zero,
                  iconSize: 16,
                  icon: Icon(LucideIcons.x, color: fs.ash),
                  onPressed: () => _onDismiss(info),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
