import 'package:electronic_assistant/base/base_page.dart';
import 'package:electronic_assistant/data/bean/agenda.dart';
import 'package:electronic_assistant/data/bean/chat_item.dart';
import 'package:electronic_assistant/data/bean/file_chat_item.dart';
import 'package:electronic_assistant/data/bean/reference_chat_item.dart';
import 'package:electronic_assistant/module/browser/view.dart';
import 'package:electronic_assistant/module/chat/controller.dart';
import 'package:electronic_assistant/resource/colors.gen.dart';
import 'package:electronic_assistant/utils/expand.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
import 'package:get/get.dart';
import 'package:lottie/lottie.dart';
import 'package:markdown/markdown.dart' as md;
import 'package:pull_to_refresh/pull_to_refresh.dart';

import '../../data/bean/progressing_chat_item.dart';
import '../../data/bean/talks.dart';
import '../../resource/assets.gen.dart';
import '../../router/app_pages.dart';

class ChatPage extends BasePage<ChatController> {
  const ChatPage({super.key});

  static start() {
    Get.toNamed(RoutePath.chat);
  }

  static startByTalk(TalkBean talkInfo, {Agenda? agenda}) {
    Get.toNamed(RoutePath.chat, arguments: [talkInfo, agenda]);
  }

  static startByTalkId(String talkId, {Agenda? agenda}) {
    Get.toNamed(RoutePath.chat, arguments: [talkId, agenda]);
  }

  @override
  bool immersive() {
    return true;
  }

  @override
  Color navigationBarColor() {
    return "#F6F6F6".color;
  }

  @override
  Widget buildBody(BuildContext context) {
    // 第一次启动时弹出定制窗口

    return Stack(
      children: [
        _buildBackgroundGradient(),
        _buildTopGradient(),
        Scaffold(
          backgroundColor: Colors.transparent,
          appBar: AppBar(
            leading: IconButton(
              icon: SizedBox(
                  width: 24.w,
                  height: 24.w,
                  child: Assets.images.iconBack.image()),
              onPressed: () {
                Get.back();
              },
            ),
            scrolledUnderElevation: 0,
            backgroundColor: Colors.transparent,
            systemOverlayStyle: SystemUiOverlayStyle.dark,
            centerTitle: true,
            title: IntrinsicWidth(
              child: Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Image(
                      image: Assets.images.iconChatXiaoTin.provider(),
                      width: 28.w,
                      height: 28.w),
                  Container(
                      margin: EdgeInsets.only(left: 6.w),
                      child: Text('聊天',
                          style: TextStyle(
                              fontSize: 16.w,
                              fontWeight: FontWeight.bold,
                              color: ColorName.primaryTextColor))),
                ],
              ),
            ),
          ),
          body: buildBodyContent(context),
        )
      ],
    );
  }

  Widget buildBodyContent(BuildContext context) {
    return Column(
      children: [
        Expanded(
            child: Container(
          padding: EdgeInsets.symmetric(horizontal: 12.w),
          child: Obx(() {
            return NotificationListener<ScrollNotification>(
              onNotification: (scrollNotification) {
                if (scrollNotification is ScrollStartNotification) {
                  FocusScope.of(context).unfocus();
                }
                return false;
              },
              child: SmartRefresher(
                controller: controller.refreshController,
                footer: CustomFooter(
                  loadStyle: LoadStyle.ShowWhenLoading,
                  builder: (context, mode) {
                    if (mode == LoadStatus.loading ||
                        mode == LoadStatus.canLoading) {
                      return const SizedBox(
                        height: 60.0,
                        child: SizedBox(
                          height: 20.0,
                          width: 20.0,
                          child: CupertinoActivityIndicator(),
                        ),
                      );
                    } else {
                      return Container();
                    }
                  },
                ),
                enablePullDown: false,
                enablePullUp: true,
                onLoading: controller.loadMoreHistory,
                onRefresh: controller.loadMoreHistory,
                child: ListView.builder(
                    reverse: true,
                    controller: controller.listScrollController,
                    itemBuilder: _chatItemBuilder,
                    itemCount: controller.chatItems.length),
              ),
            );
          }),
        )),
        Container(
          margin: EdgeInsets.symmetric(horizontal: 12.w, vertical: 12.h),
          width: 1.sw,
          decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.circular(24.w),
              boxShadow: const [
                BoxShadow(
                  color: Color(0x4CDDDEE8),
                  blurRadius: 10,
                  offset: Offset(0, 4),
                  spreadRadius: 0,
                )
              ]),
          child: Padding(
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
            child: Column(
              children: [
                Obx(() {
                  TalkBean? talkInfo = controller.talkInfo.value;
                  if (talkInfo == null) {
                    return Container();
                  } else {
                    return _buildReferenceFile(talkInfo);
                  }
                }),
                Row(
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: [
                    Expanded(
                        child: Container(
                      margin: EdgeInsets.only(right: 6.w),
                      child: CupertinoTextField(
                        controller: controller.inputController,
                        padding: EdgeInsets.symmetric(vertical: 3.w),
                        style: TextStyle(
                            fontSize: 14.w, color: ColorName.primaryTextColor),
                        placeholder: '有问题尽管问我~',
                        placeholderStyle: TextStyle(
                            fontSize: 14.w, color: const Color(0xFFAFAFAF)),
                        textCapitalization: TextCapitalization.sentences,
                        textInputAction: TextInputAction.newline,
                        cursorColor: ColorName.colorPrimary,
                        decoration: const BoxDecoration(),
                        expands: true,
                        maxLines: null,
                        minLines: null,
                      ),
                    )),
                    GestureDetector(
                      onTap: () {
                        controller.onAddFileClick();
                      },
                      child: Image(
                          image: Assets.images.iconChatAddFile.provider(),
                          width: 26.w,
                          height: 26.w),
                    ),
                    Container(
                      margin: EdgeInsets.only(left: 16.w),
                      child: GestureDetector(
                        onTap: () {
                          controller.onSendClick();
                        },
                        child: Image(
                            image: Assets.images.iconChatSend.provider(),
                            width: 26.w,
                            height: 26.w),
                      ),
                    )
                  ],
                )
              ],
            ),
          ),
        ),
      ],
    );
  }

  Widget _chatItemBuilder(BuildContext context, int index) {
    ChatItem chatItem = controller.chatItems[index];
    if (chatItem.role == 'user') {
      return _buildUserChatItem(context, chatItem);
    } else if (chatItem.role == 'assistant') {
      return _buildAssistantChatItem(context, chatItem);
    } else {
      return Container();
    }
  }

  Widget _buildAssistantChatItem(BuildContext context, ChatItem chatItem) {
    ProgressingChatItem? progressingChatItem;
    if (chatItem is ProgressingChatItem) {
      progressingChatItem = chatItem;
    }
    return Align(
      alignment: Alignment.centerLeft,
      child: IntrinsicWidth(
        child: progressingChatItem == null
            ? _buildAssistantChatItemContent(null, chatItem.content)
            : Obx(() {
                bool? isStreamStarted = progressingChatItem == null
                    ? null
                    : progressingChatItem.streamContent.isNotEmpty ||
                        progressingChatItem.isFinished.value ||
                        progressingChatItem.isFailed.value;
                return _buildAssistantChatItemContent(
                    isStreamStarted,
                    progressingChatItem!.isFailed.value
                        ? progressingChatItem.error.value
                        : progressingChatItem.streamContent.value);
              }),
      ),
    );
  }

  Container _buildAssistantChatItemContent(
      bool? isStreamStarted, String content) {
    return Container(
        padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
        margin: EdgeInsets.symmetric(vertical: 10.h),
        alignment: Alignment.centerLeft,
        constraints: BoxConstraints(
          maxWidth: 0.78.sw,
        ),
        decoration: BoxDecoration(
            border: isStreamStarted == null || isStreamStarted == true
                ? null
                : Border.all(color: ColorName.colorPrimary, width: 1.w),
            color: ColorName.white,
            borderRadius: BorderRadius.only(
                topRight: Radius.circular(20.w),
                bottomRight: Radius.circular(20.w),
                bottomLeft: Radius.circular(20.w))),
        child: isStreamStarted != null && isStreamStarted == false
            ? Lottie.asset("assets/anim/anim_chat_response_loading.zip",
                width: 46.w, height: 20.w)
            : SelectionArea(
                child: HtmlWidget(
                  onTapUrl: (url) {
                    BrowserPage.start(url);
                    return true;
                  },
                  md.markdownToHtml(content,
                      inlineSyntaxes: [
                        md.InlineHtmlSyntax(),
                        md.StrikethroughSyntax(),
                        md.EmojiSyntax(),
                        md.ColorSwatchSyntax(),
                        md.AutolinkExtensionSyntax(),
                        md.ImageSyntax()
                      ],
                      blockSyntaxes: [
                        const md.FencedCodeBlockSyntax(),
                        const md.HeaderWithIdSyntax(),
                        const md.SetextHeaderWithIdSyntax(),
                        const md.UnorderedListWithCheckboxSyntax(),
                        const md.OrderedListWithCheckboxSyntax(),
                        const md.FootnoteDefSyntax(),
                        const md.AlertBlockSyntax(),
                      ]),
                  textStyle: TextStyle(
                      fontSize: 14.w, color: ColorName.primaryTextColor),
                ),
              ));
  }

  Widget _buildUserChatItem(BuildContext context, ChatItem chatItem) {
    if (chatItem is FileChatItem) {
      return _buildUserFileChatItem(context, chatItem);
    } else if (chatItem is ReferenceChatItem) {
      return _buildUserNormalChatItem(context, chatItem,
          referenceTalkTitle: chatItem.talkInfo.title.value);
    }
    return _buildUserNormalChatItem(context, chatItem,
        referenceTalkTitle: chatItem.talkTitle);
  }

  Widget _buildUserNormalChatItem(BuildContext context, ChatItem chatItem,
      {String? referenceTalkTitle}) {
    return Align(
      alignment: Alignment.centerRight,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.end,
        children: [
          IntrinsicWidth(
            child: Container(
              padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
              margin: referenceTalkTitle == null
                  ? EdgeInsets.symmetric(vertical: 10.h)
                  : EdgeInsets.only(top: 10.h),
              alignment: Alignment.centerRight,
              constraints: BoxConstraints(
                maxWidth: 0.78.sw,
              ),
              decoration: BoxDecoration(
                  color: ColorName.colorPrimary,
                  borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(16.w),
                      bottomRight: Radius.circular(16.w),
                      bottomLeft: Radius.circular(16.w))),
              child: SelectableText(chatItem.content,
                  style: TextStyle(fontSize: 14.w, color: ColorName.white)),
            ),
          ),
          if (referenceTalkTitle != null)
            Container(
              padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
              margin: EdgeInsets.only(top: 8.h, bottom: 10.h),
              constraints: BoxConstraints(
                maxWidth: 0.78.sw,
              ),
              decoration: BoxDecoration(
                  color: "#EFEFEF".color,
                  borderRadius: BorderRadius.all(Radius.circular(10.w))),
              child: Row(
                children: [
                  Image(
                      image: Assets.images.iconReferenceChatArrow.provider(),
                      width: 16.w,
                      height: 16.w),
                  Container(
                    margin: EdgeInsets.only(right: 2.w, left: 4.w),
                    child: Image(
                        image: Assets.images.iconReferenceChatFile.provider(),
                        width: 16.w,
                        height: 16.w),
                  ),
                  Text(referenceTalkTitle,
                      style: TextStyle(
                          fontSize: 12.w,
                          color: ColorName.secondaryTextColor,
                          overflow: TextOverflow.ellipsis)),
                ],
              ),
            ),
        ],
      ),
    );
  }

  Widget _buildUserFileChatItem(BuildContext context, FileChatItem chatItem) {
    return Align(
      alignment: Alignment.centerRight,
      child: Container(
        padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 16.h),
        margin: EdgeInsets.symmetric(vertical: 10.h),
        constraints: BoxConstraints(
          maxWidth: 0.56.sw,
        ),
        decoration: BoxDecoration(
          color: ColorName.white,
          borderRadius: BorderRadius.only(
              topLeft: Radius.circular(16.w),
              bottomRight: Radius.circular(16.w),
              bottomLeft: Radius.circular(16.w)),
          border: Border.all(color: "#ECECEC".color, width: 1.w),
        ),
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Container(
              margin: EdgeInsets.only(right: 6.w),
              child: Image(
                  image: Assets.images.iconFilesFile.provider(),
                  width: 30.w,
                  height: 32.w),
            ),
            Flexible(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(chatItem.talkInfo.title.value.orEmpty,
                      maxLines: 1,
                      style: TextStyle(
                          fontSize: 14.w,
                          color: ColorName.primaryTextColor,
                          fontWeight: FontWeight.bold,
                          overflow: TextOverflow.ellipsis)),
                  Text(chatItem.talkInfo.summary.value.orEmpty,
                      maxLines: 1,
                      style: TextStyle(
                          fontSize: 12.w,
                          color: ColorName.secondaryTextColor,
                          overflow: TextOverflow.ellipsis)),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  _buildReferenceFile(TalkBean talkInfo) {
    if (talkInfo.oversizeFile == true) {
      return _buildOverSizeReference(talkInfo);
    } else {
      return _buildNormalReference(talkInfo);
    }
  }

  Container _buildOverSizeReference(TalkBean talkInfo) {
    return Container(
      margin: EdgeInsets.only(bottom: 14.h),
      padding: EdgeInsets.only(left: 8.w, top: 8.h, right: 10.w, bottom: 8.h),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.all(Radius.circular(8.w)),
        border: Border.all(color: "#F0F0F0".color, width: 1.w),
      ),
      child: Column(
        children: [
          Row(
            children: [
              Text(talkInfo.title.value.orEmpty,
                  style: TextStyle(
                      fontWeight: FontWeight.bold,
                      fontSize: 14.w,
                      color: ColorName.primaryTextColor)),
              const Spacer(),
              Container(
                margin: EdgeInsets.only(left: 8.w),
                child: Image(
                    image: Assets.images.iconReferenceChatDeleteFile.provider(),
                    width: 18.w,
                    height: 18.w),
              ),
            ],
          ),
          Container(
            margin: EdgeInsets.only(top: 11.h),
            child: Row(
              children: [
                Container(
                  margin: EdgeInsets.only(right: 2.w),
                  child: Image(
                      image: Assets.images.iconReferenceChatFile.provider(),
                      width: 16.w,
                      height: 16.w),
                ),
                Text("谈话·超长内容",
                    style: TextStyle(
                        fontSize: 12.w, color: ColorName.tertiaryTextColor)),
              ],
            ),
          )
        ],
      ),
    );
  }

  _buildNormalReference(TalkBean talkInfo) {
    return Container(
      margin: EdgeInsets.only(bottom: 14.h),
      child: Row(
        children: [
          Image(
              image: Assets.images.iconReferenceChatArrow.provider(),
              width: 16.w,
              height: 16.w),
          Container(
            margin: EdgeInsets.only(right: 2.w, left: 4.w),
            child: Image(
                image: Assets.images.iconReferenceChatFile.provider(),
                width: 16.w,
                height: 16.w),
          ),
          Text(talkInfo.title.value.orEmpty,
              overflow: TextOverflow.ellipsis,
              maxLines: 1,
              style: TextStyle(
                  fontSize: 12.w,
                  color: ColorName.primaryTextColor,
                  overflow: TextOverflow.ellipsis)),
          const Spacer(),
          Container(
            margin: EdgeInsets.only(left: 8.w),
            color: "#F6F6F6".color,
            child: GestureDetector(
              onTap: () => controller.onDeleteReference(),
              child: Image(
                  image: Assets.images.iconReferenceChatDeleteFile.provider(),
                  width: 18.w,
                  height: 18.w),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildTopGradient() {
    return Container(
        width: 1.sw,
        height: 128.h,
        decoration: BoxDecoration(
          gradient: LinearGradient(
            colors: ['#E8EBFF'.toColor(), '#00E8EBFF'.toColor()],
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
            stops: const [0.5, 1.0],
          ),
        ));
  }

  Widget _buildBackgroundGradient() {
    return Container(
      width: 1.sw,
      height: 1.sh,
      decoration: BoxDecoration(
        gradient: LinearGradient(
          colors: ['#F2F8F4'.toColor(), '#F6F6F6'.toColor()],
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          stops: const [0, 1.0],
        ),
      ),
    );
  }
}
