import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:selectable_autolink_text/selectable_autolink_text.dart';
import 'package:telnow_mobile_new/src/api/api_auth_provider.dart';
import 'package:telnow_mobile_new/src/layouts/functions/message.dart';
import 'package:telnow_mobile_new/src/layouts/components/template.dart';
import 'package:telnow_mobile_new/src/utils/U.dart';
import 'package:telnow_mobile_new/src/utils/provider.dart';
import 'package:translator/translator.dart';
import 'package:url_launcher/url_launcher.dart';

class WebMessageListPage extends StatefulWidget {
  Map<String, dynamic>? user;
  WebMessageListPage(this.user, {super.key});

  @override
  State<WebMessageListPage> createState() => _WebMessageListPageState();
}

class _WebMessageListPageState extends State<WebMessageListPage> {
  final MessageFunction messageFunc = MessageFunction();
  final ApiAuthProvider apiAuthProvider = ApiAuthProvider();
  final translator = GoogleTranslator();

  String? idChat;
  String tenant = '';
  String opponent = '';
  ScrollController scrollController = ScrollController();
  List messageData = [];

  int page = 0;
  bool isAfterLoad = false;
  String username = '';
  bool isLoad = false;
  bool stopLoad = false;
  bool scrollBottom = false;
  bool isReverse = false;
  bool askBroadcast = false;

  @override
  void initState() {
    Provider.of<MessageModule>(context, listen: false).reset();
    if(widget.user == null){
      messageFunc.getUser(context);
    }
    else{
      Provider.of<MessageModule>(context, listen: false).setUser(widget.user!);
      messageFunc.getDataMessages(context);
    }
    // TODO: implement initState
    super.initState();
  }

  selectMessage(data, isMe) async{
    if(idChat != data['chatId']){
      setState(() {
        idChat = data['chatId'];
        username = Provider.of<MessageModule>(context, listen: false).user()['userId'];
        askBroadcast = isMe;
        opponent = isMe ? data['recipientName'] : data['senderName'];
        tenant = data['recipient'];

        messageData = [];
        page = 0;
        isAfterLoad = false;
        isLoad = false;
        stopLoad = false;
        scrollBottom = false;
        isReverse = false;
      });

      scrollController.addListener(() => scrollListener());
      if (!isMe) {
        await apiAuthProvider.patchData('/api/messages/' + data['id'].toString(), {'readStatus': 'READ'}, context);
      }

      getMessage();
      getCollectionData();
    }
  }

  getMessage() async {
    String url = 'myMessages/$idChat';
    String filter = '{"f":["uniqueId","LIKE","%-%"]}';
    if (askBroadcast) {
      url = 'myBroadcast';
      filter = '{"f":["1","EQ","1"]}';
    }
    if (!isLoad && !stopLoad) {
      setState(() => isLoad = true);
      var mymess = await apiAuthProvider.getData('/api/messages/search/$url', {'isPaged': 'true', 'page': page.toString(), 'size': '20', 'filter': filter, 'tenant': tenant}, context);
      if (mymess.containsKey('_embedded') && mounted) {
        List data = mymess['_embedded']['myMessages'];
        for (int i = 0; i < data.length; i++) {
          if (username == data[i]['from']['user']) {
            data[i]['selected'] = false;
          }
          else{
            if(U.autoTranslate()){
              data[i]['translate'] = '';
            }
          }

          setState(() => messageData.insert(0, data[i]));
        }
        setState(() {
          if (page == 0) {
            scrollBottom = true;
          }
          isLoad = false;
          page++;

          if (messageData.length >= mymess['page']['totalElements']) {
            stopLoad = true;
          }
        });

        if(U.autoTranslate()){
          translateMessage();
        }
      } else {
        setState(() {
          isLoad = false;
          stopLoad = true;
        });
      }
    }
  }

  getCollectionData() {
    FirebaseFirestore.instance.collection("tmMessages").doc('messages').collection(idChat!).snapshots().listen((querySnapshot) {
      setState(() {
        querySnapshot.docChanges.forEach((result) async {
          var data = result.doc.data();
          if (result.type == DocumentChangeType.added && isAfterLoad) {
            if ((username == data!['from']['user'] && messageData.where((element) => element['uniqueId'] == data['uniqueId']).length > 0) || (username != data['from']['user'] && data['readStatus'] == 'DELETED')) {
              int index = messageData.indexWhere((element) => element['uniqueId'] == data['uniqueId']);
              messageData[index]['read'] = data['read'];
              messageData[index]['readStatus'] = data['readStatus'];
              messageData[index]['imageUrl'] = data['imageUrl'];
            } else {
              if(U.autoTranslate()){
                var locale = context.locale.toString() == 'zh' ? 'zh-cn' : context.locale.toString();
                var translate = await translator.translate(data['msg']??'', to: locale);
                data['translate'] = translate.text;
              }
              messageData.add(data);
            }
          } else if (result.type == DocumentChangeType.modified && isAfterLoad) {
            // print("modified");
            if (messageData.where((element) => element['uniqueId'] == data!['uniqueId']).length > 0) {
              int index = messageData.indexWhere((element) => element['uniqueId'] == data!['uniqueId']);
              messageData[index]['read'] = data!['read'];
              messageData[index]['readStatus'] = data['readStatus'];
            }
          } else if (result.type == DocumentChangeType.removed && isAfterLoad) {
            // print("removed");
          }
        });
        isAfterLoad = true;
      });
    });
  }

  translateMessage(){
    var locale = context.locale.toString() == 'zh' ? 'zh-cn' : context.locale.toString();
    messageData.forEach((element) async{
      if (username != element['from']['user'] && element['translate'] == '') {
        var translate = await translator.translate(element['msg']??'', to: locale);
        setState(() {
          element['translate'] = translate.text;
        });
      }
    });
  }

  deleteCollection() {
    try{
      FirebaseFirestore.instance.collection("tmMessages").doc('messages').collection(idChat!).get().then((value) {
        for (DocumentSnapshot ds in value.docs) {
          ds.reference.delete();
        }
      });
    } catch(e){}
  }

  scrollToBottom() {
    scrollController.animateTo(scrollController.position.minScrollExtent, duration: Duration(milliseconds: 1), curve: Curves.decelerate);
    scrollBottom = false;
  }

  scrollListener() {
    if (scrollController.offset >= scrollController.position.maxScrollExtent) {
      // print('loadMessage');
      getMessage();
    }
  }

  @override
  Widget build(BuildContext context) {
    if (messageData.length > 0) {
      if (scrollController.position.maxScrollExtent > 0 && !isReverse) {
        setState(() => isReverse = true);
      }

      if (isAfterLoad && scrollBottom && isReverse) {
        scrollToBottom();
      }
    }

    return Scaffold(
      backgroundColor: backgroundColor,
      appBar: PreferredSize(preferredSize: Size.fromHeight(0), child: AppBar(elevation: 0, backgroundColor: primaryColor)),
      body: Column(
        children: [
          Container(
            padding: EdgeInsets.symmetric(vertical: 25, horizontal: 100),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Text('message'.tr(), style: TextStyle(color: textColor, fontSize: 17, fontWeight: FontWeight.w500), overflow: TextOverflow.ellipsis),
                GestureDetector(
                  child: Text('buttonBack'.tr(), style: TextStyle(color: primaryColor, fontSize: 14)),
                  onTap: (){
                    deleteCollection();
                    navigateBack(context);
                  },
                )
              ],
            ),
          ),
          divider(),
          Expanded(
            child: Container(
              width: double.infinity, height: double.infinity,
              padding: EdgeInsets.symmetric(vertical: 25, horizontal: 100),
              child: Row(
                children: [
                  Expanded(
                    child: Stack(
                      children: [
                        Container(
                          width: double.infinity, height: double.infinity,
                          child: EasyRefresh(
                            header: MaterialHeader(clamping: true, color: primaryColor),
                            onRefresh: () => messageFunc.onRefresh(context),
                            child: Provider.of<MessageModule>(context).data().isEmpty && !Provider.of<MessageModule>(context).firstLoad()? loadingTemplate(() {},) : Provider.of<MessageModule>(context).data().isEmpty ? Center(
                              child: Text('noMessageText').tr(),
                            ) : SingleChildScrollView(
                              padding: EdgeInsets.symmetric(vertical: 20, horizontal: 10),
                              child: Column(
                                mainAxisSize: MainAxisSize.max,
                                children: List.generate(Provider.of<MessageModule>(context).data().length, (i) {
                                  bool _isMe = Provider.of<MessageModule>(context, listen: false).data()[i]['userId'] == Provider.of<MessageModule>(context, listen: false).user()['userId'] ? true : false;
                                  return GestureDetector(
                                    child: Container(
                                      padding: EdgeInsets.all(10),
                                      child: Row(
                                        children: [
                                          Provider.of<MessageModule>(context).data()[i]['senderAvatar'] != null && Provider.of<MessageModule>(context).data()[i]['senderAvatar'] != '' ? CircleAvatar(
                                            backgroundImage: NetworkImage(Provider.of<MessageModule>(context).data()[i]['senderAvatar']), radius: 24,
                                          ) : Container(
                                            height: 48, width: 48,
                                            child: Center(child: Text(_isMe ? Provider.of<MessageModule>(context).data()[i]['recipientName'] == "all_informants" ? "allInformants".tr()[0] : Provider.of<MessageModule>(context).data()[i]['recipientName'][0] : Provider.of<MessageModule>(context).data()[i]['senderName'][0], style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 18))),
                                            decoration: BoxDecoration(shape: BoxShape.circle, color: Color(U.getColor(_isMe ? Provider.of<MessageModule>(context).data()[i]['recipient'] : Provider.of<MessageModule>(context).data()[i]['recipientId']))),
                                          ),
                                          SizedBox(width: 20),
                                          Expanded(
                                            child: Column(
                                              crossAxisAlignment: CrossAxisAlignment.start,
                                              children: [
                                                Text(_isMe ? Provider.of<MessageModule>(context).data()[i]['recipientName'] == "all_informants" ? "allInformants".tr() : Provider.of<MessageModule>(context).data()[i]['recipientName'] : Provider.of<MessageModule>(context).data()[i]['senderName']),
                                                SizedBox(height: 5),
                                                Row(
                                                  children: [
                                                    _isMe ? Padding(
                                                      padding: EdgeInsets.only(right: 5),
                                                      child: Icon(Icons.done_all, size: 18, color: Colors.blueGrey),
                                                    ) : Container(),
                                                    Provider.of<MessageModule>(context).data()[i]['isImage'] ? Align(
                                                      alignment: Alignment.centerLeft,
                                                      child: Row(
                                                        children: [
                                                          Icon(Provider.of<MessageModule>(context).data()[i]['fileType'] == 'pdf' ? Icons.picture_as_pdf : Icons.image, color: Colors.black45, size: 16),
                                                          SizedBox(width: 6),
                                                          Provider.of<MessageModule>(context).data()[i]['lastText'] == '' ? Provider.of<MessageModule>(context).data()[i]['fileType'] == 'pdf' ? Text('pdfFile'.tr()) : Text('photo'.tr()) : Container()
                                                        ],
                                                      ),
                                                    ) : Container(),
                                                    Expanded(
                                                      child: Text(Provider.of<MessageModule>(context).data()[i]['lastText'], style: TextStyle(fontSize: 13), maxLines: 1, overflow: TextOverflow.ellipsis),
                                                    )
                                                  ],
                                                )
                                              ],
                                            ),
                                          ),
                                          SizedBox(width: 20),
                                          Column(
                                            mainAxisAlignment: MainAxisAlignment.center,
                                            crossAxisAlignment: CrossAxisAlignment.end,
                                            children: [
                                              Text(messageFunc.timeSet(Provider.of<MessageModule>(context).data()[i]['lastDateTimeSend']), style: TextStyle(fontSize: 11, color: Provider.of<MessageModule>(context).data()[i]['lastReadStatus'] == 'UNREAD' && !_isMe ? Colors.green : Colors.black45)),
                                              SizedBox(height: 4),
                                              Icon(Icons.circle, color: Colors.green.withValues(alpha: Provider.of<MessageModule>(context).data()[i]['lastReadStatus'] == 'UNREAD' && !_isMe ? 1 : 0))
                                            ],
                                          )
                                        ],
                                      ),
                                      decoration: BoxDecoration(color: idChat != null && idChat == Provider.of<MessageModule>(context, listen: false).data()[i]['chatId'] ? Color(0xff26DA17).withValues(alpha: 0.2) : Colors.white, borderRadius: BorderRadius.all(Radius.circular(12))),
                                    ),
                                    onTap: ()=>selectMessage(Provider.of<MessageModule>(context, listen: false).data()[i], _isMe),
                                  );
                                }),
                              ),
                            ),
                          ),
                          decoration: BoxDecoration(color: Colors.white, border: Border.all(color: textColor.withValues(alpha: 0.15)), borderRadius: BorderRadius.all(Radius.circular(12))),
                        ),
                        Provider.of<MessageModule>(context).user().isNotEmpty && Provider.of<MessageModule>(context).user()['canSendMessage'] ? Align(
                          alignment: Alignment.bottomRight,
                          child: GestureDetector(
                            child: Container(
                              margin: EdgeInsets.only(right: 20, bottom: 20),
                              width: 50, height: 50, alignment: Alignment.center,
                              child: U.iconsax('message', color: Colors.white),
                              decoration: BoxDecoration(
                                color: primaryColor,
                                borderRadius: BorderRadius.all(Radius.circular(50))
                              ),
                            ),
                            onTap: ()=>messageFunc.createMessage(context),
                          ),
                        ) : Container()
                      ],
                    ),
                  ),
                  SizedBox(width: 30),
                  Expanded(
                    child: Container(
                      child: idChat != null ? Column(
                        children: [
                          Container(
                            width: double.infinity, padding: EdgeInsets.all(20),
                            child: Text(opponent != 'all_informants' ? opponent : "allInformants".tr(), style: TextStyle(color: textColor, fontSize: 16)),
                          ),
                          divider(),
                          Expanded(
                            child: messageData.isEmpty && !isAfterLoad ? loadingTemplate(() {},) : SingleChildScrollView(
                              padding: const EdgeInsets.fromLTRB(10, 10, 10, 7),
                              controller: scrollController,
                              reverse: isReverse,
                              child: Column(
                                children: List.generate(messageData.length, (i) {
                                  bool hideDate = i == 0 ? false : checkDate(messageData[i]['datetime'], messageData[i - 1]['datetime']);
                                  bool isNip = i == 0 ? true : !hideDate ? true : messageData[i]['from']['user'] == messageData[i - 1]['from']['user'] ? false : true;
                                  return Column(
                                    children: [
                                      !hideDate ? Center(
                                        child: Padding(
                                          padding: const EdgeInsets.all(10),
                                          child: bubble_chat(Text(convertDate(messageData[i]['datetime'], context.locale.toString()), textAlign: TextAlign.center, style: TextStyle(fontSize: 12)), null, false, false),
                                        ),
                                      ) : Container(),
                                      Builder(builder: (context) {
                                        var isMe = messageData[i]['from']['user'] == Provider.of<MessageModule>(context, listen: false).user()['userId'];
                                        var isFile = messageData[i]['imageUrl'] != null && messageData[i]['imageUrl'] != '' && messageData[i]['readStatus'] != 'DELETED';
                                        var isPdf = isFile && messageData[i]['imageUrl'].split('.').last == 'pdf';
                                        var isImg = isFile && !isPdf;
                                        var isTranslate = U.autoTranslate() && !isMe && messageData[i]['msg'] != messageData[i]['translate'];

                                        var wdg = messageData[i]['readStatus'] == 'DELETED' ? Text('deletedMessage'.tr(), style: TextStyle(fontSize: 14, color: Colors.black54, fontStyle: FontStyle.italic)) : Column(
                                          crossAxisAlignment: CrossAxisAlignment.start,
                                          children: [
                                            isPdf ? GestureDetector(
                                              child: Container(
                                                child: Builder(builder: (context) {
                                                  var pdfContainer = Container(
                                                    padding: EdgeInsets.all(6),
                                                    child: Row(
                                                      mainAxisSize: MainAxisSize.min,
                                                      children: [
                                                        Icon(Icons.picture_as_pdf),
                                                        SizedBox(width: 6),
                                                        Flexible(child: Text(getImageName(messageData[i]['imageUrl'])))
                                                      ],
                                                    ),
                                                    decoration: BoxDecoration(color: Colors.black12.withValues(alpha: 0.1), borderRadius: BorderRadius.all(Radius.circular(4))),
                                                  );

                                                  return pdfContainer;
                                                }),
                                              ),
                                              onTap: () async {
                                                await launchUrl( messageData[i]['imageUrl']);
                                              },
                                            ) : isImg ? GestureDetector(
                                              child: Container(
                                                margin: const EdgeInsets.only(bottom: 5),
                                                child: Builder(builder: (context) {
                                                  return Image.network(messageData[i]['imageUrl'], fit: BoxFit.cover, width: 200, height: 200);
                                                })
                                              ),
                                              onTap: () => navigateTo(context, PhotoPreview(opponent, messageData[i]['imageUrl'], true)),
                                            ) : SizedBox(height: 1),
                                            messageData[i]['msg'] != null && messageData[i]['msg'] != '' ? Column(
                                              crossAxisAlignment: !isMe?CrossAxisAlignment.start:CrossAxisAlignment.end,
                                              children: [
                                                SizedBox(height: 4),
                                                SelectableAutoLinkText(
                                                  messageData[i]['msg'],
                                                  style: TextStyle(fontSize: 14, color: Colors.black),
                                                  linkStyle: TextStyle(color: Colors.blueAccent),
                                                  highlightedLinkStyle: TextStyle(color: Colors.blueAccent, backgroundColor: Colors.blueAccent.withAlpha(0x33)),
                                                  onTap: (link) async{
                                                    if (await canLaunchUrl(Uri.parse(link))) {
                                                      await launchUrl(Uri.parse(link));
                                                    }
                                                  },
                                                  onLongPress: (link) {
                                                    Clipboard.setData(new ClipboardData(text: link)).then((value){
                                                      showSuccess('link_copied'.tr(), context);
                                                    });
                                                  },
                                                  enableInteractiveSelection: false,
                                                ),
                                                isTranslate ? Container(
                                                  margin: EdgeInsets.only(top: 2), decoration: BoxDecoration(border: Border(top: BorderSide(color: Colors.black.withValues(alpha: 0.2)))),
                                                  child: Text(messageData[i]['translate']!=''?'(${messageData[i]['translate']})':'...', style: TextStyle(fontSize: 14, color: Colors.black.withValues(alpha: 0.65), fontStyle: FontStyle.italic)),
                                                ) : Container(),
                                              ],
                                            ) : Container()
                                          ],
                                        );

                                        var timeBubble = Positioned(
                                          bottom: 0, right: isNip ? 6 : 0,
                                          child: Text(DateFormat('HH:mm').format(DateTime.parse(messageData[i]['datetime'])), style: TextStyle(fontSize: 10, color: Colors.black45)),
                                        );

                                        var expander = Expanded(
                                          flex: 8,
                                          child: Column(
                                            children: [
                                              bubble_chat(wdg, timeBubble, isNip, isMe),
                                              SizedBox(height: 5),
                                            ],
                                            crossAxisAlignment: isMe ? CrossAxisAlignment.end : CrossAxisAlignment.start,
                                          )
                                        );

                                        return isMe ? Row(
                                          children: [
                                            Expanded(flex: 2, child: Container()),
                                            expander,
                                          ],
                                        ) : Row(
                                          children: [
                                            expander,
                                            Expanded(flex: 2, child: Container()),
                                          ],
                                        );
                                      }),
                                    ],
                                  );
                                }),
                              ),
                            ),
                          )
                        ],
                      ) : Container(),
                      decoration: BoxDecoration(color: Colors.white, border: Border.all(color: textColor.withValues(alpha: 0.15)), borderRadius: BorderRadius.all(Radius.circular(12))),
                    ),
                  )
                ],
              ),
            ),
          )
        ],
      ),
    );
  }

  getImageName(imageUrl) {
    var imgSplit = imageUrl.toString().split('/');
    return imgSplit[imgSplit.length - 1];
  }

  Widget bubble_chat(Widget child, Widget? time, bool isNip, bool isMe) {
    bool isDate = false;
    if (time == null) {
      isDate = true;
      time = Container();
    }
    Color color = isMe ? primaryColor.withValues(alpha: 0.3) : isDate ? Color(0xffD5F5FF) : Color(0xffECECEC);
    var clipPath = ClipPath(
      child: ConstrainedBox(
        constraints: BoxConstraints(minWidth: 50),
        child: Container(
          decoration: BoxDecoration(
            color: color,
          ),
          child: Padding(padding: EdgeInsets.all(8),
            child: isDate ? child : Stack(
              children: [
                Padding(
                  padding: EdgeInsets.only(
                    bottom: 15,
                    right: isNip && isMe ? 6 : 0,
                    left: isNip && !isMe ? 6 : 0,
                  ),
                  child: child,
                ),
                time
              ],
            ),
          ),
        ),
      ),
      clipper: isMe ? MyClipper(isNip) : YourClipper(isNip),
    );

    return Padding(
        padding: EdgeInsets.only(
            right: isNip && isMe ? 0 : 6,
            left: isNip && !isMe ? 0 : 6
        ),
        child: clipPath
    );
  }

  bool checkDate(date1, date2) {
    final dateToCheck1 = DateTime(DateTime.parse(date1).year, DateTime.parse(date1).month, DateTime.parse(date1).day);
    final dateToCheck2 = DateTime(DateTime.parse(date2).year, DateTime.parse(date2).month, DateTime.parse(date2).day);

    return dateToCheck1 == dateToCheck2 ? true : false;
  }

  String convertDate(date, locale) {
    final dateToCheck = DateTime.parse(date);

    final now = DateTime.now();
    final today = DateTime(now.year, now.month, now.day);
    final yesterday = DateTime(now.year, now.month, now.day - 1);

    final aDate = DateTime(dateToCheck.year, dateToCheck.month, dateToCheck.day);
    if (aDate == today) {
      return 'today'.tr();
    } else if (aDate == yesterday) {
      return 'yesterday'.tr();
    } else {
      return DateFormat('dd MMMM yyyy', locale).format(DateTime.parse(date));
    }
  }
}
