import 'dart:io';

import 'package:flutter/material.dart';
import 'package:matrix/matrix.dart';
import 'package:mime/mime.dart';
import 'package:pyramid/core/theme.dart';

class AttachmentDialog extends StatefulWidget {
  final List<File> files;
  final Room room;
  final Event? replyTo;

  const AttachmentDialog({
    super.key,
    required this.files,
    required this.room,
    this.replyTo,
  });

  static Future<bool> show(
    BuildContext context,
    List<File> files,
    Room room, {
    Event? replyTo,
  }) async {
    // Snappy Scale+Fade-Eingangsanimation statt Standard-Einblendung.
    return await showGeneralDialog<bool>(
          context: context,
          barrierDismissible: true,
          barrierLabel: 'Anhang',
          barrierColor: Colors.black54,
          transitionDuration: const Duration(milliseconds: 180),
          pageBuilder: (_, _, _) =>
              AttachmentDialog(files: files, room: room, replyTo: replyTo),
          transitionBuilder: (_, anim, _, child) {
            final curved =
                CurvedAnimation(parent: anim, curve: Curves.easeOutBack);
            return FadeTransition(
              opacity: anim,
              child: ScaleTransition(scale: Tween(begin: 0.92, end: 1.0).animate(curved), child: child),
            );
          },
        ) ??
        false;
  }

  @override
  State<AttachmentDialog> createState() => _AttachmentDialogState();
}

class _AttachmentDialogState extends State<AttachmentDialog> {
  final _msgCtrl = TextEditingController();
  bool _sending = false;
  String? _error;
  bool _compress = false;

  bool get _hasImages => widget.files.any((f) {
    final mime = lookupMimeType(f.path.split(Platform.pathSeparator).last) ?? '';
    return mime.startsWith('image/');
  });

  @override
  void dispose() {
    _msgCtrl.dispose();
    super.dispose();
  }

  Future<void> _send() async {
    setState(() { _sending = true; _error = null; });
    try {
      for (final file in widget.files) {
        final bytes = await file.readAsBytes();
        final filename = file.path.split(Platform.pathSeparator).last;
        final mimeType = lookupMimeType(filename) ?? 'application/octet-stream';
        final matrixFile = MatrixFile(bytes: bytes, name: filename, mimeType: mimeType);
        final isImage = mimeType.startsWith('image/');
        await widget.room.sendFileEvent(
          matrixFile,
          inReplyTo: widget.replyTo,
          shrinkImageMaxDimension: (_compress && isImage) ? 1600 : null,
        );
      }
      if (_msgCtrl.text.trim().isNotEmpty) {
        await widget.room.sendTextEvent(
          _msgCtrl.text.trim(),
          inReplyTo: widget.replyTo,
        );
      }
      if (mounted) Navigator.of(context).pop(true);
    } catch (e) {
      setState(() { _sending = false; _error = e.toString().split('\n').first; });
    }
  }

  @override
  Widget build(BuildContext context) {
    final pt = PyramidTheme.of(context);

    return Dialog(
      backgroundColor: pt.bg1,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(pt.rLg),
        side: BorderSide(color: pt.border),
      ),
      child: ConstrainedBox(
        constraints: const BoxConstraints(maxWidth: 480, minWidth: 320),
        child: Padding(
          padding: const EdgeInsets.all(24),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // Title
              Row(
                children: [
                  Icon(Icons.attach_file_rounded, size: 18, color: pt.accent),
                  const SizedBox(width: 8),
                  Text(
                    '${widget.files.length} Datei${widget.files.length == 1 ? '' : 'en'} senden',
                    style: TextStyle(color: pt.fg, fontSize: 16, fontWeight: FontWeight.w600),
                  ),
                  const Spacer(),
                  GestureDetector(
                    onTap: () => Navigator.of(context).pop(false),
                    child: Icon(Icons.close_rounded, size: 18, color: pt.fgDim),
                  ),
                ],
              ),
              const SizedBox(height: 16),
              // File list
              ConstrainedBox(
                constraints: const BoxConstraints(maxHeight: 160),
                child: ListView.builder(
                  shrinkWrap: true,
                  itemCount: widget.files.length,
                  itemBuilder: (ctx, i) => _FilePreview(file: widget.files[i], pt: pt),
                ),
              ),
              const SizedBox(height: 16),
              // Caption field
              TextField(
                controller: _msgCtrl,
                style: TextStyle(color: pt.fg, fontSize: 14),
                cursorColor: pt.accent,
                maxLines: 3,
                minLines: 1,
                decoration: InputDecoration(
                  hintText: 'Nachricht hinzufügen (optional)',
                  hintStyle: TextStyle(color: pt.fgDim, fontSize: 14),
                  filled: true,
                  fillColor: pt.bg2,
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(pt.rBase),
                    borderSide: BorderSide(color: pt.border),
                  ),
                  enabledBorder: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(pt.rBase),
                    borderSide: BorderSide(color: pt.border),
                  ),
                  focusedBorder: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(pt.rBase),
                    borderSide: BorderSide(color: pt.accent),
                  ),
                  contentPadding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
                  isDense: true,
                ),
              ),
              // Image quality toggle
              if (_hasImages) ...[
                const SizedBox(height: 12),
                Container(
                  padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                  decoration: BoxDecoration(
                    color: pt.bg2,
                    borderRadius: BorderRadius.circular(pt.rBase),
                    border: Border.all(color: pt.border),
                  ),
                  child: Row(
                    children: [
                      Icon(Icons.high_quality_outlined, size: 16, color: pt.fgMuted),
                      const SizedBox(width: 8),
                      Text('Hohe Qualität', style: TextStyle(color: pt.fg, fontSize: 13)),
                      const Spacer(),
                      Switch.adaptive(
                        value: !_compress,
                        onChanged: (v) => setState(() => _compress = !v),
                        activeThumbColor: pt.accent,
                      ),
                    ],
                  ),
                ),
              ],
              if (_error != null) ...[
                const SizedBox(height: 8),
                Text(_error!, style: TextStyle(color: pt.danger, fontSize: 12)),
              ],
              const SizedBox(height: 16),
              // Actions
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  TextButton(
                    onPressed: _sending ? null : () => Navigator.of(context).pop(false),
                    child: Text('Abbrechen', style: TextStyle(color: pt.fgMuted)),
                  ),
                  const SizedBox(width: 8),
                  FilledButton.icon(
                    onPressed: _sending ? null : _send,
                    style: FilledButton.styleFrom(
                      backgroundColor: pt.accent,
                      foregroundColor: pt.accentFg,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(pt.rBase),
                      ),
                    ),
                    icon: _sending
                        ? SizedBox(
                            width: 14,
                            height: 14,
                            child: CircularProgressIndicator(
                              strokeWidth: 2,
                              color: pt.accentFg,
                            ),
                          )
                        : const Icon(Icons.send_rounded, size: 14),
                    label: const Text('Senden'),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _FilePreview extends StatefulWidget {
  final File file;
  final PyramidTheme pt;

  const _FilePreview({required this.file, required this.pt});

  @override
  State<_FilePreview> createState() => _FilePreviewState();
}

class _FilePreviewState extends State<_FilePreview> {
  int? _bytes;

  @override
  void initState() {
    super.initState();
    widget.file.length().then((b) { if (mounted) setState(() => _bytes = b); });
  }

  @override
  Widget build(BuildContext context) {
    final filename = widget.file.path.split(Platform.pathSeparator).last;
    final mime = lookupMimeType(filename) ?? 'application/octet-stream';
    final isImage = mime.startsWith('image/');

    return Container(
      margin: const EdgeInsets.only(bottom: 8),
      padding: const EdgeInsets.all(10),
      decoration: BoxDecoration(
        color: widget.pt.bg2,
        borderRadius: BorderRadius.circular(widget.pt.rBase),
        border: Border.all(color: widget.pt.border),
      ),
      child: Row(
        children: [
          if (isImage)
            ClipRRect(
              borderRadius: BorderRadius.circular(6),
              child: Image.file(widget.file, width: 40, height: 40, fit: BoxFit.cover),
            )
          else
            Container(
              width: 40,
              height: 40,
              decoration: BoxDecoration(
                color: widget.pt.bg3,
                borderRadius: BorderRadius.circular(6),
              ),
              child: Center(
                child: Icon(_mimeIcon(mime), size: 20, color: widget.pt.fgDim),
              ),
            ),
          const SizedBox(width: 10),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(
                  filename,
                  style: TextStyle(color: widget.pt.fg, fontSize: 13),
                  overflow: TextOverflow.ellipsis,
                ),
                if (_bytes != null)
                  Text(
                    _formatSize(_bytes!),
                    style: TextStyle(color: widget.pt.fgDim, fontSize: 11),
                  ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  IconData _mimeIcon(String mime) {
    if (mime.startsWith('video/')) return Icons.videocam_outlined;
    if (mime.startsWith('audio/')) return Icons.audio_file_outlined;
    if (mime.contains('pdf')) return Icons.picture_as_pdf_outlined;
    if (mime.contains('zip') || mime.contains('tar') || mime.contains('gz')) {
      return Icons.folder_zip_outlined;
    }
    return Icons.insert_drive_file_outlined;
  }

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