/**
 * Author: Damodar Lohani
 * profile: https://github.com/lohanidamodar
  */
import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:naim/classes/appdata.dart';
import 'dart:math';

import 'package:naim/classes/assets.dart';
import 'package:naim/classes/cipher.dart';
import 'package:naim/widgets/chatbubble.dart';

import '../classes/Auth.dart';
import '../classes/message.dart';
import '../main.dart';

class ChatPage extends StatefulWidget {
  static final String path = "lib/src/pages/misc/chat2.dart";
  @override
  _ChatPageState createState() => _ChatPageState();
  ChatPage(this.isGroup, {this.grp, this.user});
  final bool isGroup;
  late NAUsers? user;
  late NAGroups? grp;
}

class _ChatPageState extends State<ChatPage> with RouteAware {
  String? text;
  TextEditingController? _controller;
  StreamSubscription? loginSubscription;
  List<String> avatarsx = [];
  List<Message> messages = [];
  final rand = Random();

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

    _controller = TextEditingController();
    appData.currentchat = {
      'user': widget.user,
      "is_group": widget.isGroup ? 1 : 0,
      "grp": widget.grp
    };
    loadMessages();
    main();
  }

  @override
  void didPopNext() {
    appData.currentchat = {};
  }

  @override
  void didPush() {}

  @override
  void dispose() {
    if (loginSubscription != null) {
      loginSubscription!.cancel();
    }
    routeObserver.unsubscribe(this);
    appData.currentchat = {};

    super.dispose();
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    routeObserver.subscribe(this, ModalRoute.of(context) as PageRoute);
  }

  main() {
    loginSubscription = appData.eventBus!.on().listen((event) {
      if (event.data["type"] == "new_message") {
        processNewMessage(event.data);
      } else if (event.data["type"] == "is_typing") {}
    }, onError: (e) {
      print(e.toString());
    }, onDone: () => print("doe with bus"));
  }

  processNewMessage(dynamic datax) {
    bool bfound = false;
    var is_group = widget.isGroup ? 1 : 0;

    if (is_group == int.parse(datax["is_group"].toString())) {
      if (int.parse(appData.currentchat["is_group"].toString()) == 1) {
        if (widget.grp!.id == int.parse(datax["to"].toString())) {
          bfound = true;
        }
      } else {
        if (widget.user!.id == int.parse(datax["data"]["userid"].toString())) {
          bfound = true;
        }
      }
    }

    print("bfound === $bfound");

    if (bfound) {
      loadMessages();
      /* var data = datax["data"];
      var msg = Message.fromJson(data);
      setState(() {
        messages.insert(0, msg);
      }); */
    }
  }

  @override
  Widget build(BuildContext context) {
    appData.context = context;
    return Scaffold(
      appBar: AppBar(
        foregroundColor: appColors.armyColor(context),
        leading: IconButton(
          onPressed: () {
            Navigator.of(context).pop();
          },
          icon: Icon(
            Icons.arrow_back,
            color: appColors.armyColor(context),
          ),
        ),
        backgroundColor: appColors.backgroundColor(context),
        title: Row(
          children: [
            CircleAvatar(
              backgroundImage: NetworkImage(
                widget.isGroup
                    ? dataUrl + widget.grp!.photo
                    : dataUrl + widget.user!.photo,
              ),
              radius: 20.0,
            ),
            const SizedBox(width: 4),
            Column(
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                Text(
                  widget.isGroup
                      ? widget.grp!.groupName
                      : widget.user!.username == ""
                          ? widget.user!.phone
                          : "${widget.user!.lastname}, ${widget.user!.firstname}",
                  style: TextStyle(
                      color: appColors.textColor(context),
                      fontSize: 13,
                      fontWeight: FontWeight.bold),
                ),
              ],
            ),
          ],
        ),
      ),
      body: SafeArea(
        child: Column(
          children: <Widget>[
            Expanded(
              child: Container(
                decoration: BoxDecoration(
                  image: DecorationImage(
                    fit: BoxFit.cover,
                    colorFilter: ColorFilter.mode(
                        appColors.backgroundColor(context), BlendMode.multiply),
                    image: const AssetImage(camobkimg),
                  ),
                ),
                child: ListView.separated(
                  physics: BouncingScrollPhysics(),
                  separatorBuilder: (context, index) {
                    return const SizedBox(height: 10.0);
                  },
                  reverse: true,
                  itemCount: messages.length,
                  itemBuilder: (BuildContext context, int index) {
                    Message m = messages[index];

                    return ChatBubble(m);
                  },
                ),
              ),
            ),
            _buildBottomBar(context),
          ],
        ),
      ),
    );
  }

  Container _buildBottomBar(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: appColors.backgroundColor(context),
      ),
      padding: const EdgeInsets.symmetric(
        vertical: 8.0,
        horizontal: 20.0,
      ),
      child: Row(
        children: <Widget>[
          Expanded(
            child: TextField(
              textInputAction: TextInputAction.send,
              controller: _controller,
              style: TextStyle(color: appColors.textColor(context)),
              decoration: InputDecoration(
                  contentPadding: const EdgeInsets.symmetric(
                    vertical: 10.0,
                    horizontal: 20.0,
                  ),
                  border: OutlineInputBorder(
                      borderSide: BorderSide(
                          color: appColors.textColor(context), width: 1.0),
                      borderRadius: BorderRadius.circular(20.0)),
                  enabledBorder: OutlineInputBorder(
                      borderSide: BorderSide(
                          color: appColors.textColor(context), width: 1.0),
                      borderRadius: BorderRadius.circular(20.0)),
                  focusedBorder: OutlineInputBorder(
                      borderSide: BorderSide(
                          color: appColors.armyColor(context), width: 2.0),
                      borderRadius: BorderRadius.circular(20.0)),
                  hintText: "Aa",
                  hintStyle:
                      TextStyle(color: appColors.textColorSecondary(context))),
              onEditingComplete: _save,
            ),
          ),
          IconButton(
            icon: const Icon(Icons.send),
            color: appColors.armyColor(context),
            onPressed: _save,
          )
        ],
      ),
    );
  }

  _save() async {
    if (_controller!.text.isEmpty) return;
    FocusScope.of(context).requestFocus(FocusNode());
    var msg = Message(
        print: true,
        rnd: randomString(9),
        userid: appData.dbUser['id'],
        description: encryptIt(_controller!.text, appData.strPwd).base64,
        type: "text",
        user: NAUsers.fromJson(appData.dbUser),
        timestamp: DateTime.now());
    setState(() {
      messages.insert(0, msg);
      msg.sendMessage(
          widget.isGroup, widget.isGroup ? widget.grp!.id : widget.user!.id);
      _controller!.clear();
    });
  }

  loadMessages() async {
    try {
      var dio = Dio();
      dio.options.baseUrl = appApi;
      var formData = {
        "token": appData.dbUser['token'],
        "is_group": widget.isGroup ? 1 : 0,
        "other_id": widget.isGroup ? widget.grp!.id : widget.user!.id
      };

      print(formData);

      var response = await dio.post(
        "getmessagethread",
        data: formData,
        options: Options(
          method: 'POST',
          responseType: ResponseType.plain,
          headers: {
            HttpHeaders.contentLengthHeader:
                formData.length, // set content-length
          },
        ),
      );
      //print(response.data);
      //print("respnse data ======= ==");
      var data = json.decode(response.data);
      if (data["result"] != null) {
        if (data["result"] == "success") {
          var msgs = json.decode(data["data"]["messages"]);
          var x = List<Message>.from(msgs.map((dat) {
            return Message.fromJson(dat);
          }).toList());
          x.sort((a, b) => b.timestamp.compareTo(a.timestamp));
          setState(() {
            messages = x;
          });
        } else {
          return {"result": false, "msg": data["data"]["message"]};
        }
      }
    } catch (e) {
      print("Error: " + e.toString());
      return {"result": false, "msg": e.toString()};
    }
    return {"result": false, "msg": "Something went wrong"};
  }
}
