import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../shared/theme/theme_extensions.dart';
import '../../../core/providers/app_providers.dart';
import '../../../core/services/api_service.dart';
import 'enhanced_image_attachment.dart';
import 'package:share_plus/share_plus.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';
import 'dart:convert';

class EnhancedAttachment extends ConsumerStatefulWidget {
  final String attachmentId;
  final bool isMarkdownFormat;
  final BoxConstraints? constraints;
  final bool isUserMessage;
  final bool disableAnimation;

  const EnhancedAttachment({
    super.key,
    required this.attachmentId,
    this.isMarkdownFormat = false,
    this.constraints,
    this.isUserMessage = false,
    this.disableAnimation = false,
  });

  @override
  ConsumerState<EnhancedAttachment> createState() => _EnhancedAttachmentState();
}

class _EnhancedAttachmentState extends ConsumerState<EnhancedAttachment> {
  Map<String, dynamic>? _fileInfo;
  bool _isLoading = true;
  String? _error;
  String? _localFilePath;

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

  Future<void> _resolveType() async {
    try {
      // Data URL for images – short-circuit to image widget
      if (widget.attachmentId.startsWith('data:image/')) {
        setState(() {
          _isLoading = false;
          _fileInfo = {'mime': 'image/inline'};
        });
        return;
      }

      final api = ref.read(apiServiceProvider);
      if (api is! ApiService) {
        setState(() {
          _isLoading = false;
          _error = 'Service unavailable';
        });
        return;
      }

      final info = await api.getFileInfo(widget.attachmentId);
      setState(() {
        _fileInfo = info;
        _isLoading = false;
      });
    } catch (e) {
      setState(() {
        _error = 'Failed to load attachment';
        _isLoading = false;
      });
    }
  }

  bool _isImageFile(Map<String, dynamic>? info) {
    if (info == null) return false;
    final mime = (info['content_type'] ?? info['mime'] ?? '')
        .toString()
        .toLowerCase();
    if (mime.startsWith('image/')) return true;
    final name = (info['filename'] ?? info['name'] ?? '')
        .toString()
        .toLowerCase();
    final ext = name.split('.').length > 1 ? name.split('.').last : '';
    return ['jpg', 'jpeg', 'png', 'gif', 'webp'].contains(ext);
  }

  Future<String?> _ensureLocalFile() async {
    if (_localFilePath != null && await File(_localFilePath!).exists()) {
      return _localFilePath;
    }
    try {
      final api = ref.read(apiServiceProvider);
      if (api is! ApiService) return null;

      final content = await api.getFileContent(widget.attachmentId);
      final filename = (_fileInfo?['filename'] ?? _fileInfo?['name'] ?? 'file')
          .toString();
      final dir = await getTemporaryDirectory();
      final filePath = '${dir.path}/$filename';

      try {
        if (content.length > 128 &&
            RegExp(
              r'^[A-Za-z0-9+/=\r\n]+$',
            ).hasMatch(content.replaceAll('\n', ''))) {
          final bytes = base64Decode(content.replaceAll('\n', ''));
          await File(filePath).writeAsBytes(bytes, flush: true);
        } else {
          await File(filePath).writeAsString(content, flush: true);
        }
      } catch (_) {
        await File(filePath).writeAsString(content, flush: true);
      }

      _localFilePath = filePath;
      return _localFilePath;
    } catch (e) {
      setState(() {
        _error = 'Failed to prepare file';
      });
      return null;
    }
  }

  Future<void> _shareFile() async {
    final path = await _ensureLocalFile();
    if (path == null) return;
    final filename = (_fileInfo?['filename'] ?? _fileInfo?['name'] ?? 'file')
        .toString();
    await SharePlus.instance.share(
      ShareParams(files: [XFile(path, name: filename)]),
    );
  }

  String _fileIconFor(String filename) {
    final lower = filename.toLowerCase();
    String ext = '';
    final parts = lower.split('.');
    if (parts.length > 1) ext = parts.last;
    if (['pdf', 'doc', 'docx'].contains(ext)) return '📄';
    if (['xls', 'xlsx'].contains(ext)) return '📊';
    if (['ppt', 'pptx'].contains(ext)) return '📊';
    if (['jpg', 'jpeg', 'png', 'gif', 'webp'].contains(ext)) return '🖼️';
    if (['js', 'ts', 'py', 'dart', 'java', 'cpp'].contains(ext)) return '💻';
    if (['html', 'css', 'json', 'xml'].contains(ext)) return '🌐';
    if (['zip', 'rar', '7z', 'tar', 'gz'].contains(ext)) return '📦';
    if (['mp3', 'wav', 'flac', 'm4a'].contains(ext)) return '🎵';
    if (['mp4', 'avi', 'mov', 'mkv'].contains(ext)) return '🎬';
    return '📎';
  }

  @override
  Widget build(BuildContext context) {
    if (_isLoading) {
      return Container(
        width: widget.constraints?.maxWidth ?? 160,
        height: 84,
        decoration: BoxDecoration(
          color: context.conduitTheme.cardBackground,
          borderRadius: BorderRadius.circular(AppBorderRadius.md),
          border: Border.all(
            color: context.conduitTheme.textPrimary.withValues(alpha: 0.1),
            width: BorderWidth.regular,
          ),
        ),
      );
    }

    if (_error != null) {
      return Container(
        padding: const EdgeInsets.all(Spacing.sm),
        decoration: BoxDecoration(
          color: context.conduitTheme.surfaceContainer,
          borderRadius: BorderRadius.circular(AppBorderRadius.md),
          border: Border.all(
            color: context.conduitTheme.error.withValues(alpha: 0.3),
            width: BorderWidth.regular,
          ),
        ),
        child: Text(
          _error!,
          style: TextStyle(
            color: context.conduitTheme.error,
            fontSize: AppTypography.labelMedium,
          ),
        ),
      );
    }

    // Image: delegate to existing image widget for consistency
    if (_isImageFile(_fileInfo)) {
      return EnhancedImageAttachment(
        attachmentId: widget.attachmentId,
        isMarkdownFormat: widget.isMarkdownFormat,
        constraints: widget.constraints,
        isUserMessage: widget.isUserMessage,
        disableAnimation: widget.disableAnimation,
      );
    }

    final filename = (_fileInfo?['filename'] ?? _fileInfo?['name'] ?? 'File')
        .toString();
    final size = _fileInfo?['size'];
    final sizeLabel = size is num ? _formatSize(size.toInt()) : null;
    final lowerName = filename.toLowerCase();
    final fileExtension = lowerName.contains('.')
        ? lowerName.split('.').last
        : '';
    final List<String> metaParts = [];
    if (fileExtension.isNotEmpty) {
      metaParts.add('.${fileExtension.toUpperCase()}');
    }
    if (sizeLabel != null) {
      metaParts.add(sizeLabel);
    }
    final metaLabel = metaParts.join(' • ');

    final card = Container(
      constraints: widget.constraints,
      padding: const EdgeInsets.all(Spacing.md),
      decoration: BoxDecoration(
        color: context.conduitTheme.cardBackground,
        borderRadius: BorderRadius.circular(AppBorderRadius.md),
        border: Border.all(
          color: context.conduitTheme.textPrimary.withValues(alpha: 0.12),
          width: BorderWidth.regular,
        ),
      ),
      child: Row(
        mainAxisSize: MainAxisSize.max,
        children: [
          Text(
            _fileIconFor(filename),
            style: const TextStyle(fontSize: AppTypography.headlineLarge),
          ),
          const SizedBox(width: Spacing.sm),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisSize: MainAxisSize.min,
              children: [
                Text(
                  filename,
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                  style: TextStyle(
                    color: context.conduitTheme.textPrimary,
                    fontSize: AppTypography.labelLarge,
                    fontWeight: FontWeight.w600,
                  ),
                ),
                if (metaLabel.isNotEmpty)
                  Text(
                    metaLabel,
                    style: TextStyle(
                      color: context.conduitTheme.textSecondary.withValues(
                        alpha: 0.7,
                      ),
                      fontSize: AppTypography.labelMedium,
                    ),
                  ),
              ],
            ),
          ),
        ],
      ),
    );

    return InkWell(
      borderRadius: BorderRadius.circular(AppBorderRadius.md),
      onTap: () async {
        await HapticFeedback.mediumImpact();
        await _shareFile();
      },
      child: card,
    );
  }

  String _formatSize(int bytes) {
    if (bytes < 1024) return '$bytes B';
    if (bytes < 1024 * 1024) {
      return '${(bytes / 1024).toStringAsFixed(1)} KB';
    }
    if (bytes < 1024 * 1024 * 1024) {
      return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB';
    }
    return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB';
  }
}
