import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:jihu_gitlab_app/core/load_state.dart';
import 'package:jihu_gitlab_app/core/widgets/avatar/avatar.dart';
import 'package:jihu_gitlab_app/core/widgets/avatar_and_name.dart';
import 'package:jihu_gitlab_app/core/widgets/common_app_bar.dart';
import 'package:jihu_gitlab_app/core/widgets/loading_button.dart';
import 'package:jihu_gitlab_app/core/widgets/selector/selector.dart';
import 'package:jihu_gitlab_app/core/widgets/toast.dart';
import 'package:jihu_gitlab_app/domain/discussions.dart';
import 'package:jihu_gitlab_app/domain/note.dart';
import 'package:jihu_gitlab_app/modules/todo_list/todo_param.dart';
import 'package:jihu_gitlab_app/modules/todo_list/widgets/member.dart';
import 'package:jihu_gitlab_app/modules/todo_list/widgets/member_provider.dart';

import '../../../core/widgets/changeable_time.dart';
import 'discussions_model.dart';

class DiscussionsPage extends StatefulWidget {
  final TodoParam param;

  const DiscussionsPage({super.key, required this.param});

  @override
  State<StatefulWidget> createState() => _DiscussionsPageState();
}

class _DiscussionsPageState extends State<DiscussionsPage> {
  final TextEditingController _commentController = TextEditingController();
  FocusNode commentFocusNode = FocusNode();
  final DiscussionsModel _model = DiscussionsModel();
  String placeholder = "Write a comment ...";
  int inputTextLength = 0;

  @override
  void initState() {
    super.initState();
    _toggleLoading(true);
    _model.getDiscussions(widget.param).then((value) => _toggleLoading(false)).catchError((e) => _toggleLoading(false));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: true,
      appBar: _buildAppBar(context),
      backgroundColor: const Color(0xF8F8FAFF),
      body: SafeArea(
        child: Stack(
          children: <Widget>[
            Offstage(
                offstage: !(_model.loadState == LoadState.successState),
                child: GestureDetector(
                  onTap: () {
                    setState(() {
                      placeholder = "Write a comment ...";
                      _model.selectedNoteId = null;
                      commentFocusNode.unfocus();
                    });
                  },
                  child: Column(children: [Expanded(child: SingleChildScrollView(child: _buildIssueDetailPageView())), _buildIssueReplyView()]),
                )),
            Offstage(offstage: !(_model.loadState == LoadState.loadingState), child: _buildLoadingView()),
          ],
        ),
      ),
    );
  }

  CommonAppBar _buildAppBar(BuildContext context) {
    return CommonAppBar(title: Text(_model.issueDetail.iid == 0 ? "" : '${_model.issueDetail.projectName}  #${_model.issueDetail.iid}'), showLeading: true);
  }

  // TODO Extract to Loading widget
  Widget _buildLoadingView() {
    return Center(
      heightFactor: 100,
      child: Column(
        children: [
          Container(height: 100),
          Image.asset("assets/images/loading.png", height: 40, width: 40),
          Container(height: 5),
          const Text("Loading", style: TextStyle(fontSize: 14, color: Color.fromRGBO(23, 19, 33, 1)))
        ],
      ),
    );
  }

  Widget _buildIssueDetailPageView() {
    return Column(
      children: [
        _buildIssueDetailView(),
        Container(
          margin: _model.comments.isEmpty ? const EdgeInsets.all(0) : const EdgeInsets.fromLTRB(12, 12, 12, 0),
          padding: _model.comments.isEmpty ? const EdgeInsets.all(0) : const EdgeInsets.only(left: 12),
          width: MediaQuery.of(context).size.width,
          height: _model.comments.isEmpty ? 0 : 40,
          alignment: Alignment.centerLeft,
          decoration: const BoxDecoration(color: Colors.white),
          child: Column(mainAxisSize: MainAxisSize.min, children: const [Text("Comments", style: TextStyle(color: Color(0xFF1A1B36), fontSize: 16, fontWeight: FontWeight.w600))]),
        ),
        Container(
          padding: _model.comments.isEmpty ? const EdgeInsets.all(0) : const EdgeInsets.fromLTRB(12, 12, 12, 0),
          margin: _model.comments.isEmpty ? const EdgeInsets.all(0) : const EdgeInsets.fromLTRB(12, 0, 12, 0),
          constraints: _model.comments.isEmpty ? const BoxConstraints(minHeight: 0) : const BoxConstraints(minHeight: 50),
          decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(4))),
          child: _buildDiscussionList(),
        ),
      ],
    );
  }

  void _saveCommentAndRefresh() async {
    var commentContent = _commentController.text;
    if (commentContent.isEmpty) {
      Toast.show('Please write a comment ');
      return;
    }
    _toggleLoading(true);
    try {
      await _model.saveComment(commentContent).then((value) => Toast.success(context, 'Successful')).catchError((e) => Toast.error(context, 'Failed'));
      await _model.getDiscussions(widget.param);
    } finally {
      _toggleLoading(false);
    }
    _commentController.clear();
    commentFocusNode.unfocus();
  }

  Widget _buildIssueReplyView() {
    return Align(
      alignment: Alignment.bottomCenter,
      child: Container(
        width: double.infinity,
        padding: const EdgeInsets.symmetric(horizontal: 12),
        decoration: const BoxDecoration(color: Color(0xF8F8FAFF), border: Border(top: BorderSide(width: 0.2, color: Color(0xFFCECECE)))),
        child: Row(children: [
          Flexible(child: _buildInputView()),
          IconButton(
            icon: const Icon(Icons.alternate_email),
            onPressed: () async {
              List<Member> result = await _openMemberSelector();
              if (result.isNotEmpty) {
                var selectedUsername = result[0].username;
                _commentController.text = "${_commentController.text}@$selectedUsername ";
              }
            },
          ),
          _buildAddCommentButton()
        ]),
      ),
    );
  }

  Widget _buildInputView() {
    return Container(
        constraints: const BoxConstraints(minHeight: 32),
        margin: const EdgeInsets.fromLTRB(0, 12, 8, 8),
        padding: const EdgeInsets.only(left: 8),
        decoration: const BoxDecoration(color: Colors.white),
        child: TextField(
          maxLines: null,
          controller: _commentController,
          focusNode: commentFocusNode,
          onChanged: (text) async {
            if (text.endsWith("@") && text.length > inputTextLength) {
              List<Member> result = await _openMemberSelector();
              if (result.isNotEmpty) {
                var selectedUsername = result[0].username;
                _commentController.text = "${_commentController.text}$selectedUsername ";
              }
            }
            setState(() {
              _model.submittable = text.isNotEmpty;
            });
            inputTextLength = text.length;
          },
          cursorColor: const Color(0xFFFC6D26),
          decoration: InputDecoration(hintText: placeholder, border: InputBorder.none, hintStyle: const TextStyle(fontSize: 12, fontWeight: FontWeight.w400)),
        ));
  }

  Widget _buildAddCommentButton() {
    return LoadingButton(
        isLoading: _model.isLoading,
        disabled: !_model.submittable,
        text: const Text("Comment", style: TextStyle(color: Colors.white, fontSize: 12)),
        onPressed: () {
          _saveCommentAndRefresh();
        });
  }

  Widget _buildIssueDetailView() {
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        Container(
          padding: const EdgeInsets.all(12),
          margin: const EdgeInsets.fromLTRB(12, 12, 12, 0),
          constraints: const BoxConstraints(minHeight: 50),
          decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(4))),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Row(children: [
                Expanded(child: Text.rich(TextSpan(text: _model.issueDetail.title, style: const TextStyle(fontSize: 18, color: Color(0xFF1A1B36), fontWeight: FontWeight.w600)))),
              ]),
              Markdown(
                padding: const EdgeInsets.only(left: 0, top: 12, right: 16, bottom: 16),
                shrinkWrap: true,
                data: _model.issueDetail.description,
                selectable: true,
                physics: const NeverScrollableScrollPhysics(),
              ),
              Row(
                children: [
                  Text(_model.issueDetail.recentActivities(), style: const TextStyle(color: Color(0xFF87878C), fontWeight: FontWeight.w400, fontSize: 12)),
                  ChangeableTime.show(() => setState(() {}), true, _model.issueDetail.recentActivityTimes(), const Color(0xFF87878C), FontWeight.w400, 12)
                ],
              ),
            ],
          ),
        )
      ],
    );
  }

  Widget _buildDiscussionList() {
    return ListView.separated(
      physics: const NeverScrollableScrollPhysics(),
      itemBuilder: (context, index) {
        Discussion comment = _model.comments[index];
        return Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                Row(
                  children: [
                    Avatar(avatarUrl: comment.notes[0].author.avatarUrl, size: 24),
                    Text(" ${comment.notes[0].author.name}", style: const TextStyle(color: Color(0xFF1A1B36), fontWeight: FontWeight.w400, fontSize: 13)),
                    ChangeableTime.show(() => setState(() {}), true, comment.notes[0].createdAt, const Color(0xFF95979A), FontWeight.w400, 12),
                  ],
                ),
                InkWell(
                    onTap: () {
                      setState(() {
                        placeholder = "Reply ${comment.notes[0].author.name}:";
                        _model.selectedNoteId = _model.comments[index].notes[0].id;
                        _model.selectedDiscussionId = _model.comments[index].id;
                        FocusScope.of(context).requestFocus(commentFocusNode);
                      });
                    },
                    child: Image.asset("assets/images/replay.png", height: 16, width: 16)),
              ],
            ),
            Column(
              children: [
                Markdown(padding: const EdgeInsets.fromLTRB(0, 12, 0, 12), shrinkWrap: true, data: comment.notes[0].body, selectable: true, physics: const NeverScrollableScrollPhysics()),
              ],
            ),
            _model.comments[index].individualNote == false && _model.comments[index].notes.length > 1
                ? Container(
                    padding: const EdgeInsets.fromLTRB(12, 12, 12, 0),
                    decoration: BoxDecoration(border: Border.all(color: const Color(0xFFF3F3F3)), color: Colors.white, borderRadius: const BorderRadius.all(Radius.circular(4))),
                    child: _buildDiscussionNotesView(_model.comments[index].notes))
                : Container(height: 0),
          ],
        );
      },
      itemCount: _model.comments.length,
      shrinkWrap: true,
      separatorBuilder: (BuildContext context, int index) {
        return const Divider(height: 30, color: Colors.white);
      },
    );
  }

  Widget _buildDiscussionNotesView(List<Note> notes) {
    List<Widget> widgets = [];
    Widget content = Column();
    for (int i = 0; i < notes.length; i++) {
      if (i == 0) {
        continue;
      }
      widgets.add(Row(
        children: [
          Avatar(avatarUrl: notes[i].author.avatarUrl, size: 24),
          Text(" ${notes[i].author.name}", style: const TextStyle(color: Color(0xFF1A1B36), fontWeight: FontWeight.w400, fontSize: 13)),
          ChangeableTime.show(() => setState(() {}), true, notes[i].createdAt, const Color(0xFF95979A)),
        ],
      ));
      widgets.add(Column(
        children: [Markdown(padding: const EdgeInsets.fromLTRB(0, 12, 0, 12), shrinkWrap: true, data: notes[i].body, selectable: true, physics: const NeverScrollableScrollPhysics())],
      ));
    }
    content = Column(children: widgets);
    return content;
  }

  void _toggleLoading(bool on) {
    setState(() {
      _model.isLoading = on;
    });
  }

  Future<List<Member>> _openMemberSelector() async {
    return (await Navigator.of(context).push(MaterialPageRoute(builder: (context) {
          return Selector<int, Member>(
            itemBuilder: (BuildContext context, int index, dynamic member) => AvatarAndName(username: member.username, avatarUrl: member.avatarUrl),
            filter: (keyword, member) => member.username.toLowerCase().contains(keyword.toLowerCase()),
            dataProvider: MemberProvider(projectId: widget.param.projectId),
            keyMapper: (member) => member.id,
            title: 'Select contact',
            key: const Key('member-selector'),
          );
        })) ??
        <Member>[]) as List<Member>;
  }
}