import 'package:flutter/material.dart';

import '/components/view_image.dart';
import '/database/models/image_message.dart';
import '/database/models/my_profile.dart';
import '/database/models/messages.dart';
import '/utils/time.dart';

@immutable
class ConversationMessage extends StatefulWidget {
  const ConversationMessage({
    Key? key,
    required this.message,
    required this.profile,
    required this.index,
  }) : super(key: key);

  final Message message;
  final MyProfile profile;
  final int index;

  @override
  _ConversationMessageState createState() => _ConversationMessageState();
}

class _ConversationMessageState extends State<ConversationMessage> {

  List<PopupMenuEntry<String>> menuItems = [];

  Offset? _tapPosition;

  bool showDownloadButton = false;
  bool showDeleteButton = false;

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

    showDownloadButton = widget.message.runtimeType == ImageMessage;
    showDeleteButton = widget.message.senderId == widget.profile.id;

    if (showDownloadButton) {
      menuItems.add(PopupMenuItem(
        value: 'download',
        child: Row(
          children: const [
            Icon(Icons.download),
            SizedBox(
              width: 10,
            ),
            Text('Download')
          ],
        ),
      ));
    }

    if (showDeleteButton) {
      menuItems.add(PopupMenuItem(
        value: 'delete',
        child: Row(
          children: const [
            Icon(Icons.delete),
            SizedBox(
              width: 10,
            ),
            Text('Delete')
          ],
        ),
      ));
    }

    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: const EdgeInsets.only(left: 14,right: 14,top: 0,bottom: 0),
      child: Align(
        alignment: (
          widget.message.senderId == widget.profile.id ?
            Alignment.topRight :
            Alignment.topLeft
        ),
        child: Column(
          crossAxisAlignment: widget.message.senderId == widget.profile.id ?
            CrossAxisAlignment.end :
            CrossAxisAlignment.start,
          children: <Widget>[

            messageContent(context),

            const SizedBox(height: 1.5),

            Row(
              mainAxisAlignment: widget.message.senderId == widget.profile.id ?
                MainAxisAlignment.end :
                MainAxisAlignment.start,
              children: <Widget>[
                const SizedBox(width: 10),
                usernameOrFailedToSend(),
              ],
            ),

            const SizedBox(height: 1.5),

            Row(
              mainAxisAlignment: widget.message.senderId == widget.profile.id ?
                MainAxisAlignment.end :
                MainAxisAlignment.start,
              children: <Widget>[
                const SizedBox(width: 10),
                Text(
                  convertToAgo(widget.message.createdAt),
                  textAlign: widget.message.senderId == widget.profile.id ?
                    TextAlign.left :
                    TextAlign.right,
                  style: TextStyle(
                    fontSize: 12,
                    color: Theme.of(context).hintColor,
                  ),
                ),
              ],
            ),

            widget.index != 0 ?
              const SizedBox(height: 20) :
              const SizedBox.shrink(),
          ],
        )
      ),
    );
  }

  void _showCustomMenu() {
    if (menuItems.isEmpty) {
      return;
    }

    final Size overlay = MediaQuery.of(context).size;

    int addVerticalOffset = 75 * menuItems.length;

    // TODO: Implement download & delete methods
    showMenu(
      context: context,
      items: menuItems,
      position: RelativeRect.fromRect(
        Offset(_tapPosition!.dx, (_tapPosition!.dy - addVerticalOffset)) & const Size(40, 40),
        Offset.zero & overlay
      )
    )
    .then<void>((String? delta) async {
      if (delta == null) {
        return;
      }
    });
  }

  void _storePosition(TapDownDetails details) {
    _tapPosition = details.globalPosition;
  }

  Widget messageContent(BuildContext context) {
    if (widget.message.runtimeType == ImageMessage) {
      return GestureDetector(
        onTap: () {
          Navigator.push(context, MaterialPageRoute(builder: (context) {
            return ViewImage(
              message: (widget.message as ImageMessage)
            );
          }));
        },
        onLongPress: _showCustomMenu,
        onTapDown: _storePosition,
        child: ConstrainedBox(
          constraints: const BoxConstraints(maxHeight: 350, maxWidth: 250),
          child: ClipRRect(
            borderRadius: BorderRadius.circular(20), child: Image.file(
              (widget.message as ImageMessage).file,
              fit: BoxFit.fill,
            ),
          ),
        ),
      );
    }

    return GestureDetector(
      onLongPress: _showCustomMenu,
      onTapDown: _storePosition,
      child: Container(
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(20),
          color: (
            widget.message.senderId == widget.profile.id ?
              Theme.of(context).colorScheme.primary :
              Theme.of(context).colorScheme.tertiary
          ),
        ),
        padding: const EdgeInsets.all(12),
        child: Text(
          widget.message.getContent(),
          style: TextStyle(
            fontSize: 15,
            color: widget.message.senderId == widget.profile.id ?
              Theme.of(context).colorScheme.onPrimary :
              Theme.of(context).colorScheme.onTertiary,
          ),
        ),
      ),
    );
  }

  Widget usernameOrFailedToSend() {
    if (widget.message.senderId != widget.profile.id) {
      return Text(
        widget.message.senderUsername,
        style: TextStyle(
          fontSize: 12,
          color: Theme.of(context).hintColor,
        ),
      );
    }

    if (widget.message.failedToSend) {
      return Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: const <Widget>[
          Icon(
            Icons.warning_rounded,
            color: Colors.red,
            size: 20,
          ),
          Text(
            'Failed to send',
            style: TextStyle(color: Colors.red, fontSize: 12),
            textAlign: TextAlign.right,
          ),
        ],
      );
    }

    return const SizedBox.shrink();
  }
}