import 'dart:typed_data';

import 'package:flutter/material.dart';

import '../../../../api/marianumconnect/queries/submit_feedback/submit_feedback.dart';
import '../../../../widget/async_action_button.dart';
import '../../../../widget/demo_restricted.dart';
import '../../../../widget/file_pick.dart';
import '../../../../widget/focus_behaviour.dart';
import '../../../../widget/info_dialog.dart';

class FeedbackDialog extends StatefulWidget {
  const FeedbackDialog({super.key});

  @override
  State<FeedbackDialog> createState() => _FeedbackDialogState();
}

class _FeedbackDialogState extends State<FeedbackDialog> {
  final TextEditingController _feedbackInput = TextEditingController();
  final AsyncActionController _sendController = AsyncActionController();
  final AsyncActionController _pickController = AsyncActionController();

  Uint8List? _image;
  bool _textFieldEmpty = false;

  @override
  void initState() {
    super.initState();
    _feedbackInput.addListener(() {
      if (_textFieldEmpty && _feedbackInput.text.isNotEmpty) {
        setState(() => _textFieldEmpty = false);
      }
    });
  }

  @override
  void dispose() {
    _feedbackInput.dispose();
    _sendController.dispose();
    _pickController.dispose();
    super.dispose();
  }

  Future<void> _pickImage() async {
    final picked = await FilePick.singleGalleryPick();
    if (picked == null) return;
    final data = await picked.readAsBytes();
    if (!mounted) return;
    setState(() => _image = data);
  }

  Future<void> _submit() async {
    if (guardDemoAction(context)) return;
    if (_feedbackInput.text.trim().isEmpty) {
      setState(() => _textFieldEmpty = true);
      return;
    }
    await SubmitFeedback().run(
      message: _feedbackInput.text,
      screenshot: _image,
    );
    if (!mounted) return;
    Navigator.of(context).pop();
    InfoDialog.show(context, 'Danke für dein Feedback!');
  }

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    return Scaffold(
      appBar: AppBar(title: const Text('Feedback')),
      body: SingleChildScrollView(
        padding: const EdgeInsets.fromLTRB(16, 16, 16, 24),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Text(
              'Feedback, Anregungen, Ideen, Fehler und Verbesserungen',
              textAlign: TextAlign.center,
              style: theme.textTheme.titleMedium,
            ),
            const SizedBox(height: 6),
            Text(
              'Bitte gib keine geheimen Daten wie z.B. Passwörter weiter.',
              textAlign: TextAlign.center,
              style: theme.textTheme.bodySmall?.copyWith(
                color: theme.colorScheme.onSurfaceVariant,
              ),
            ),
            const SizedBox(height: 20),
            TextField(
              controller: _feedbackInput,
              autofocus: true,
              minLines: 5,
              maxLines: 8,
              textCapitalization: TextCapitalization.sentences,
              onChanged: (value) {
                if (value.trim().toLowerCase() == 'ranzig') {
                  _feedbackInput.text = 'selber';
                }
              },
              decoration: InputDecoration(
                border: const OutlineInputBorder(),
                label: const Text('Deine Nachricht'),
                hintText: 'Was möchtest du uns mitteilen?',
                errorText: _textFieldEmpty
                    ? 'Bitte gib eine Beschreibung an!'
                    : null,
              ),
              onTapOutside: (_) =>
                  FocusBehaviour.textFieldTapOutside(context),
            ),
            const SizedBox(height: 16),
            if (_image != null)
              Center(
                child: _ImagePreview(
                  bytes: _image!,
                  onRemove: () => setState(() => _image = null),
                ),
              )
            else
              Align(
                alignment: Alignment.centerLeft,
                child: AsyncTextButton(
                  controller: _pickController,
                  onPressed: _pickImage,
                  child: const Row(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Icon(Icons.attach_file_outlined, size: 18),
                      SizedBox(width: 6),
                      Text('Screenshot anhängen'),
                    ],
                  ),
                ),
              ),
            const SizedBox(height: 8),
            Align(
              alignment: Alignment.centerRight,
              child: AsyncTextButton(
                controller: _sendController,
                onPressed: _submit,
                child: const Text('Senden'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class _ImagePreview extends StatelessWidget {
  final Uint8List bytes;
  final VoidCallback onRemove;

  const _ImagePreview({required this.bytes, required this.onRemove});

  @override
  Widget build(BuildContext context) => Stack(
    children: [
      Padding(
        // Reserve space inside the Stack bounds for the close button.
        // Without it the button would sit on a negative Positioned and
        // Flutter wouldn't hit-test taps outside the Stack rect.
        padding: const EdgeInsets.only(top: 10, right: 10),
        child: ClipRRect(
          borderRadius: BorderRadius.circular(8),
          child: Container(
            decoration: BoxDecoration(
              border: Border.all(
                color: Theme.of(context).colorScheme.outlineVariant,
              ),
              borderRadius: BorderRadius.circular(8),
            ),
            constraints: const BoxConstraints(maxHeight: 200),
            child: Image.memory(bytes, fit: BoxFit.contain),
          ),
        ),
      ),
      Positioned(
        top: 0,
        right: 0,
        child: Material(
          color: Theme.of(context).colorScheme.surface,
          shape: const CircleBorder(),
          elevation: 2,
          child: InkWell(
            customBorder: const CircleBorder(),
            onTap: onRemove,
            child: const Padding(
              padding: EdgeInsets.all(4),
              child: Icon(Icons.close, size: 18),
            ),
          ),
        ),
      ),
    ],
  );
}
