import 'package:bubble/bubble.dart';
import 'package:flutter/material.dart';
import 'package:jiffy/jiffy.dart';
import 'package:marianum_mobile/api/marianumcloud/talk/chat/richObjectStringProcessor.dart';
import 'package:marianum_mobile/api/marianumcloud/talk/room/getRoomResponse.dart';
import 'package:marianum_mobile/api/marianumcloud/talk/sendMessage/sendMessage.dart';
import 'package:marianum_mobile/api/marianumcloud/talk/sendMessage/sendMessageParams.dart';
import 'package:marianum_mobile/data/chatList/chatProps.dart';
import 'package:provider/provider.dart';

class ChatView extends StatefulWidget {
  final GetRoomResponseObject room;
  final String selfId;
  final CircleAvatar avatar;

  const ChatView({Key? key, required this.room, required this.selfId, required this.avatar}) : super(key: key);

  @override
  State<ChatView> createState() => _ChatViewState();
}

class _ChatViewState extends State<ChatView> {
  static const styleSystem = BubbleStyle(
    color: Color(0xffd4eaf4),
    borderWidth: 1,
    elevation: 2,
    margin: BubbleEdges.only(top: 15),
    alignment: Alignment.center,
  );

  static BubbleStyle getStyleOther(bool seamless) {
    return BubbleStyle(
      nip: BubbleNip.leftTop,
      color: seamless ? Colors.transparent : Colors.white,
      borderWidth: seamless ? 0 : 1,
      elevation: seamless ? 0 : 1,
      margin: const BubbleEdges.only(top: 15, left: 10, right: 50),
      alignment: Alignment.topLeft,
    );
  }

  static BubbleStyle getStyleSelf(bool seamless) {
    return BubbleStyle(
      nip: BubbleNip.rightBottom,
      color: seamless ? Colors.transparent : const Color(0xffd9fdd3),
      borderWidth: seamless ? 0 : 1,
      elevation: seamless ? 0 : 1,
      margin: const BubbleEdges.only(top: 15, right: 10, left: 50),
      alignment: Alignment.topRight,
    );
  }

  final ScrollController _listController = ScrollController();
  final TextEditingController _textBoxController = TextEditingController();
  bool sending = false;

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

    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      Provider.of<ChatProps>(context, listen: false).setQueryToken(widget.room.token);
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return Consumer<ChatProps>(
      builder: (context, data, child) {
        List<Bubble> messages = List<Bubble>.empty(growable: true);

        if(!data.primaryLoading()) {
          bool showActorDisplayName = true;
          bool showBubbleTime = true;

          data.getChatResponse.sortByTimestamp().forEach((element) {

            showActorDisplayName = element.messageType == GetRoomResponseObjectMessageType.comment && widget.room.type != GetRoomResponseObjectConversationType.oneToOne;
            showBubbleTime = element.messageType != GetRoomResponseObjectMessageType.system;

            BubbleStyle currentStyle;
            if(element.messageType == GetRoomResponseObjectMessageType.comment) {
              if(element.actorId == widget.selfId) {
                currentStyle = getStyleSelf(element.messageParameters?.containsKey("file") ?? false);
              } else {
                currentStyle = getStyleOther(element.messageParameters?.containsKey("file") ?? false);
              }
            } else {
              currentStyle = styleSystem;
            }

            var _actorTextStyle = TextStyle(color: Theme.of(context).primaryColor, fontWeight: FontWeight.bold);

            messages.add(Bubble(
              margin: BubbleEdges.only(bottom: element == data.getChatResponse.sortByTimestamp().last ? 20 : 0),

              style: currentStyle,
              child: Container(
                constraints: BoxConstraints(
                  maxWidth: MediaQuery.of(context).size.width * 0.9,
                  minWidth: showActorDisplayName ? _textSize(element.actorDisplayName, _actorTextStyle).width : 30,
                ),
                child: Stack(
                  children: [
                    Padding(
                      padding: EdgeInsets.only(bottom: showBubbleTime ? 18 : 0, top: showActorDisplayName ? 18 : 0),
                      child: FutureBuilder(
                        future: RichObjectStringProcessor.parseAnyToWidget(element.message, element.messageParameters),
                        builder: (context, snapshot) {
                          if(!snapshot.hasData) return const CircularProgressIndicator();
                          return snapshot.data ?? const Icon(Icons.error);
                        },
                      )
                    ),
                    Visibility(
                      visible: showActorDisplayName,
                      child: Positioned(
                        top: 0,
                        left: 0,
                        child: Text(
                          element.actorDisplayName,
                          textAlign: TextAlign.start,
                          style: _actorTextStyle,
                        ),
                      ),
                    ),
                    Visibility(
                      visible: showBubbleTime,
                      child: Positioned(
                        bottom: 0,
                        right: 0,
                        child: Text(
                          Jiffy.unixFromSecondsSinceEpoch(element.timestamp).format("HH:mm"),
                          textAlign: TextAlign.end,
                          style: const TextStyle(color: Colors.grey, fontSize: 12),
                        ),
                      ),
                    ),
                  ],
                ),
              ),


                // Stack(
              //   children: [
              //     Visibility(
              //       visible: showMetadata,
              //       child: Positioned(
              //         top: 0,
              //         left: 0,
              //         child: Expanded(child: Text(element.actorDisplayName, style: TextStyle(fontWeight: FontWeight.bold, color: Theme.of(context).primaryColor))),
              //       ),
              //     ),
              //     Padding(
              //       padding: EdgeInsets.symmetric(vertical: showMetadata ? 18 : 0),
              //       child: Text(RichObjectStringProcessor.parse(element.message, element.messageParameters)),
              //     ),
              //     Visibility(
              //       visible: showMetadata,
              //       child: Positioned(
              //         bottom: 0,
              //         right: 0,
              //         child: Text(
              //           "${Jiffy.unixFromSecondsSinceEpoch(element.timestamp).yMMMMd} - ${Jiffy.unixFromSecondsSinceEpoch(element.timestamp).format("HH:mm")}",
              //           style: TextStyle(color: Theme.of(context).disabledColor),
              //         ),
              //       ),
              //     ),
              //   ],
              // ),
            ));
          });
        }

        return Scaffold(
          backgroundColor: const Color(0xffefeae2),
          appBar: AppBar(
            title: Row(
              children: [
                widget.avatar,
                const SizedBox(width: 10),
                Expanded(
                  child: Text(widget.room.displayName, overflow: TextOverflow.ellipsis, maxLines: 1),
                )
              ],
            ),
          ),
          body: Container(
            decoration: const BoxDecoration(
              image: DecorationImage(
                image: AssetImage("assets/background/chat.png"),
                scale: 1.5,
                opacity: 0.5,
                repeat: ImageRepeat.repeat,
                colorFilter: ColorFilter.linearToSrgbGamma()
              )
            ),
            child: data.primaryLoading() ? const Center(child: CircularProgressIndicator()) : Column(
              children: [
                Expanded(
                  child: ListView(
                    reverse: true,
                    controller: _listController,
                    children: messages.reversed.toList(),
                  ),
                ),
                Container(
                  color: Theme.of(context).dividerColor,
                  padding: const EdgeInsets.all(10),
                  child: Row(
                    children: [
                      Expanded(
                        child: TextField(
                          controller: _textBoxController,
                          readOnly: sending,
                          maxLines: null,
                          decoration: const InputDecoration(
                            hintText: "Nachricht",
                            border: OutlineInputBorder(),
                            labelText: "",
                          ),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.symmetric(horizontal: 15),
                        child: sending ? const Center(child: CircularProgressIndicator()) : IconButton(
                            onPressed: () {
                              if(_textBoxController.text.isEmpty) return;
                              setState(() {
                                sending = true;
                              });
                              SendMessage(widget.room.token, SendMessageParams(_textBoxController.text)).run().then((value) => {
                                Provider.of<ChatProps>(context, listen: false).run(),
                                _textBoxController.text = "",
                                setState(() {
                                  sending = false;
                                }),
                              });
                            },
                            icon: const Icon(Icons.send)
                        ),
                      )
                    ],
                  ),
                )
              ],
            )
          ),
        );
      },
    );
  }

  Size _textSize(String text, TextStyle style) {
    final TextPainter textPainter = TextPainter(
        text: TextSpan(text: text, style: style),
        maxLines: 1,
        textDirection: TextDirection.ltr)
      ..layout(minWidth: 0, maxWidth: double.infinity);
    return textPainter.size;
  }
}