// ignore_for_file: library_private_types_in_public_api, deprecated_member_use, depend_on_referenced_packages, unnecessary_import

import 'package:didvan/views/widgets/state_handlers/state_handler.dart';
import 'package:flutter/foundation.dart' show kIsWeb;

import 'package:didvan/config/design_config.dart';
import 'package:didvan/config/theme_data.dart';
import 'package:didvan/constants/app_icons.dart';
import 'package:didvan/main.dart';
import 'package:didvan/models/ai/ai_chat_args.dart';
import 'package:didvan/models/ai/chats_model.dart';
import 'package:didvan/models/ai/files_model.dart';
import 'package:didvan/models/ai/messages_model.dart';
import 'package:didvan/models/enums.dart';
import 'package:didvan/models/view/alert_data.dart';
import 'package:didvan/routes/routes.dart';
import 'package:didvan/services/media/media.dart';
import 'package:didvan/services/network/request.dart';
import 'package:didvan/services/network/request_helper.dart';
import 'package:didvan/utils/action_sheet.dart';
import 'package:didvan/utils/date_time.dart';
import 'package:didvan/utils/extension.dart';
import 'package:didvan/views/ai/ai_chat_state.dart';
import 'package:didvan/views/ai/history_ai_chat_state.dart';
import 'package:didvan/views/ai/widgets/ai_message_bar.dart';
import 'package:didvan/views/ai/widgets/audio_wave.dart';
import 'package:didvan/views/ai/widgets/hoshan_drawer.dart';
import 'package:didvan/views/widgets/didvan/didvan_markdown.dart';
import 'package:didvan/views/widgets/didvan/text.dart';
import 'package:didvan/views/widgets/marquee_text.dart';
import 'package:didvan/views/widgets/skeleton_image.dart';
import 'package:didvan/views/widgets/video/chat_video_player.dart';
import 'package:didvan/views/widgets/video/custome_controls.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:persian_number_utility/persian_number_utility.dart';
import 'package:provider/provider.dart';

class AiChatPage extends StatefulWidget {
  final AiChatArgs args;
  const AiChatPage({Key? key, required this.args}) : super(key: key);

  @override
  _AiChatPageState createState() => _AiChatPageState();
}

class _AiChatPageState extends State<AiChatPage> {
  final GlobalKey<ScaffoldState> scaffKey = GlobalKey<ScaffoldState>();
  FocusNode focusNode = FocusNode();

  @override
  void didUpdateWidget(covariant AiChatPage oldWidget) {
  super.didUpdateWidget(oldWidget);
  if (widget.args.bot.id != oldWidget.args.bot.id) {
    final state = context.read<AiChatState>();
    state.clearChat(); 

    if (widget.args.chat != null) {
      state.chatId = widget.args.chat!.id!;
      state.chat = widget.args.chat;
      state.getAllMessages(state.chatId!);
    }
    

    if (widget.args.prompts != null) {
        state.messages.add(MessageModel(
            dateTime: DateTime.now()
                .subtract(const Duration(minutes: 210))
                .toIso8601String(),
            prompts: [widget.args.prompts!]));

        state.message.clear();
        state.update();
        state.postMessage(
            widget.args.bot, widget.args.assistantsName != null);
      }
  }
}
  @override
  void initState() {
    final state = context.read<AiChatState>();
    if (widget.args.chat != null) {
      state.chatId = widget.args.chat!.id!;
      state.chat = widget.args.chat;
    }
    
    
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      if (state.chatId != null) {
        state.getAllMessages(state.chatId!).then((value) => Future.delayed(
              const Duration(
                milliseconds: 100,
              ),
              () => focusNode.requestFocus(),
            ));
      } else {
        state.appState = AppState.idle; 
        Future.delayed(
          const Duration(
            milliseconds: 100,
          ),
          () => focusNode.requestFocus(),
        );
      }
      if (widget.args.prompts != null) {
        state.messages.add(MessageModel(
            dateTime: DateTime.now()
                .subtract(const Duration(minutes: 210))
                .toIso8601String(),
            prompts: [widget.args.prompts!]));

        state.message.clear();
        state.update();
        await state.postMessage(
            widget.args.bot, widget.args.assistantsName != null);
      }
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        if (context.read<HistoryAiChatState>().refresh) {
          context.read<HistoryAiChatState>().getChats();
          context.read<HistoryAiChatState>().refresh = false;
        }
        return true;
      },
      child: Consumer<AiChatState>(
        builder: (context, state, child) => Scaffold(
            // appBar: HoshanAppBar(
            //   onBack: () {
            //     Navigator.pop(context);
            //   },
            //   withActions: false,
            // ),
            key: scaffKey,
            resizeToAvoidBottomInset: true,
            drawer: HoshanDrawer(
              scaffKey: scaffKey,
            ),
            body: StateHandler<AiChatState>(
              state: state,
              onRetry: () {
                if (state.chatId != null) {
                  state.getAllMessages(state.chatId!);
                }
              },
              builder: (context, state) {
                return Stack(
                  children: [
                    SingleChildScrollView(
                      reverse: true,
                      controller: state.scrollController,
                      child: Column(
                        children: [
                          Column(
                            crossAxisAlignment: CrossAxisAlignment.center,
                            children: [
                              const SizedBox(
                                height: 24,
                              ),
                              // SkeletonImage(
                              //   width: 75,
                              //   height: 75,
                              //   imageUrl: widget.args.bot.image.toString(),
                              //   borderRadius: BorderRadius.circular(360),
                              // ),
                              // const SizedBox(
                              //   height: 12,
                              // ),
                              // DidvanText(
                              //   widget.args.assistantsName ??
                              //       widget.args.bot.name.toString(),
                              //   fontSize: 17,
                              //   fontWeight: FontWeight.bold,
                              // ),
                              if (state.messages.isEmpty)
                                Column(
                                  children: [
                                    const SizedBox(
                                      height: 16,
                                    ),
                                    Padding(
                                      padding: const EdgeInsets.only(left: 60,right: 60),
                                      child: Center(
                                          child: DidvanText(
                                        widget.args.bot.description ?? '',
                                        fontSize: 12,
                                        color: Theme.of(context)
                                            .colorScheme
                                            .caption,
                                        textAlign: TextAlign.justify,
                                      )),
                                    ),
                                    const SizedBox(
                                      height: 100,
                                    ),
                                  ],
                                )
                            ],
                          ),
                          if (state.messages.isNotEmpty)
                            ListView.builder(
                                itemCount: state.messages.length,
                                shrinkWrap: true,
                                physics: const NeverScrollableScrollPhysics(),
                                padding: EdgeInsets.only(
                                    bottom: state.file != null &&
                                            !(state.file!.isRecorded)
                                        ? 180
                                        : 100),
                                itemBuilder: (context, mIndex) {
                                  final prompts =
                                      state.messages[mIndex].prompts;
                                  final time =
                                      state.messages[mIndex].dateTime;
                                  return Column(
                                    children: [
                                      timeLabel(context, time),
                                      ListView.builder(
                                        itemCount: prompts.length,
                                        shrinkWrap: true,
                                        physics:
                                            const NeverScrollableScrollPhysics(),
                                        itemBuilder: (context, index) {
                                          final message = prompts[index];

                                          return messageBubble(message,
                                              context, state, index, mIndex);
                                        },
                                      ),
                                    ],
                                  );
                                }),
                        ],
                      ),
                    ),
                    Positioned(
                      top: 32,
                      right: 0,
                      child: InkWell(
                          onTap: () => scaffKey.currentState!.openDrawer(),
                          child: Container(
                            width: 46,
                            height: 46,
                            decoration: BoxDecoration(
                                color: Theme.of(context).colorScheme.surface,
                                borderRadius: const BorderRadius.only(
                                    topLeft: Radius.circular(12),
                                    bottomLeft: Radius.circular(12)),
                                boxShadow: DesignConfig.defaultShadow),
                            child: Icon(
                              DidvanIcons.angle_left_light,
                              color: Theme.of(context).colorScheme.title,
                            ),
                          )),
                    )
                  ],
                );
              },
            ),
            bottomSheet: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                AiMessageBar(
                  bot: widget.args.bot,
                  attch: widget.args.attach,
                  assistantsName: widget.args.assistantsName,
                ),
              ],
            )),
      ),
    );
  }

  Center timeLabel(BuildContext context, String time) {
    return Center(
      child: Container(
        margin: const EdgeInsets.symmetric(vertical: 12),
        padding: const EdgeInsets.all(4),
        decoration: BoxDecoration(
          color: Theme.of(context).colorScheme.splash,
          borderRadius: DesignConfig.lowBorderRadius,
        ),
        child: DidvanText(
          DateTime.parse(time).toPersianDateStr(),
          style: Theme.of(context).textTheme.labelSmall,
          color: DesignConfig.isDark
              ? Theme.of(context).colorScheme.white
              : Theme.of(context).colorScheme.black,
        ),
      ),
    );
  }

  Widget messageBubble(Prompts message, BuildContext context, AiChatState state,
      int index, int mIndex) {
    FilesModel? file = message.fileLocal ??
        (message.file == null
            ? null
            : FilesModel(message.file.toString().replaceAll(' ', ''),
                duration: message.duration != null
                    ? Duration(seconds: message.duration!)
                    : null));

    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 4),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: message.role.toString().contains('user')
            ? CrossAxisAlignment.start
            : CrossAxisAlignment.end,
        children: [
          Row(
            mainAxisAlignment: message.role.toString().contains('user')
                ? MainAxisAlignment.start
                : MainAxisAlignment.end,
            children: [
              Container(
                constraints: BoxConstraints(
                    maxWidth: MediaQuery.sizeOf(context).width / 1.3),
                decoration: BoxDecoration(
                  borderRadius: DesignConfig.mediumBorderRadius.copyWith(
                    bottomLeft: !message.role.toString().contains('user')
                        ? Radius.zero
                        : null,
                    bottomRight: message.role.toString().contains('user')
                        ? Radius.zero
                        : null,
                  ),
                  color: message.error != null && message.error!
                      ? Theme.of(context).colorScheme.error.withOpacity(0.4)
                      : (message.role.toString().contains('user')
                              ? Theme.of(context).colorScheme.surface
                              : Theme.of(context).colorScheme.focused)
                          .withOpacity(0.9),
                  border: Border.all(
                    color: Theme.of(context).colorScheme.border,
                    width: 0.5,
                  ),
                ),
                child: Container(
                  child: message.finished != null && !message.finished!
                      ? Column(
                          children: [
                            ValueListenableBuilder<Stream<String>>(
                                valueListenable: state.messageOnstream,
                                builder: (context, value, child) {
                                  return StreamBuilder<String>(
                                    stream: value,
                                    builder: (context, snapshot) {
                                      if (!snapshot.hasData) {
                                        return const SizedBox();
                                      }
                                      return Padding(
                                        padding: const EdgeInsets.symmetric(
                                            vertical: 8.0, horizontal: 16),
                                        child: Directionality(
                                          textDirection: snapshot.data
                                                  .toString()
                                                  .startsWithEnglish()
                                              ? TextDirection.ltr
                                              : TextDirection.rtl,
                                          child: DidvanMarkdownText(
                                            text: "${snapshot.data}...",
                                          ),
                                        ),
                                      );
                                    },
                                  );
                                }),
                            Padding(
                              padding:
                                  const EdgeInsets.symmetric(vertical: 8.0),
                              child: SpinKitThreeBounce(
                                color: Theme.of(context).colorScheme.primary,
                                size: 18,
                              ),
                            )
                          ],
                        )
                      : Column(
                          children: [
                            if (file != null)
                              (file.isAudio())
                                  ? Padding(
                                      padding: const EdgeInsets.symmetric(
                                          horizontal: 16, vertical: 8),
                                      child: AudioWave(
                                        file: file.path,
                                        totalDuration: file.duration,
                                      ),
                                    )
                                  : file.isVideo()
                                      ? Padding(
                                          padding: const EdgeInsets.fromLTRB(
                                              16, 16, 16, 0),
                                          child: ClipRRect(
                                              borderRadius:
                                                  DesignConfig.lowBorderRadius,
                                              child: ChatVideoPlayer(
                                                src: RequestHelper.baseUrl +
                                                    file.path,
                                                custome: const CustomControls(),
                                              )),
                                        )
                                      : file.isImage()
                                          ? Padding(
                                              padding:
                                                  const EdgeInsets.all(8.0),
                                              child: messageImage(file),
                                            )
                                          : Padding(
                                              padding: const EdgeInsets.all(
                                                8.0,
                                              ),
                                              child: messageFile(
                                                  context, message, state),
                                            ),
                            if (message.text != null &&
                                message.text!.isNotEmpty &&
                                ((message.audio == null ||
                                    (message.audio != null &&
                                        !message.audio!))))
                              Padding(
                                padding: const EdgeInsets.symmetric(
                                    vertical: 8.0, horizontal: 16),
                                child: Directionality(
                                  textDirection: message.text
                                          .toString()
                                          .startsWithEnglish()
                                      ? TextDirection.ltr
                                      : TextDirection.rtl,
                                  child: DidvanMarkdownText(
                                    text: message.text.toString(),
                                  ),
                                ),
                              ),
                            Padding(
                              padding:
                                  const EdgeInsets.symmetric(horizontal: 8.0),
                              child: Row(
                                mainAxisAlignment: MainAxisAlignment.end,
                                children: [
                                  if (message.role
                                          .toString()
                                          .contains('user') &&
                                      widget.args.assistantsName == null)
                                    PopupMenuButton(
                                        offset: const Offset(0, 46),
                                        onSelected: (value) async {
                                          navigatorKey.currentState!.pushNamed(
                                              Routes.aiChat,
                                              arguments: AiChatArgs(
                                                  bot: value,
                                                  prompts: message,
                                                  isTool: widget.args.isTool ??
                                                      context
                                                          .read<
                                                              HistoryAiChatState>()
                                                          .bots));
                                        },
                                        itemBuilder: (BuildContext context) {
                                          final bots = widget.args.isTool ??
                                              context
                                                  .read<HistoryAiChatState>()
                                                  .bots;
                                          return <PopupMenuEntry>[
                                            ...List.generate(
                                              bots.length,
                                              (index) => PopupMenuItem(
                                                value: bots[index],
                                                height: 72,
                                                child: Container(
                                                  constraints:
                                                      const BoxConstraints(
                                                          maxWidth: 200),
                                                  child: Row(
                                                    children: [
                                                      SkeletonImage(
                                                        imageUrl: bots[index]
                                                            .image
                                                            .toString(),
                                                        width: 42,
                                                        height: 42,
                                                        borderRadius:
                                                            BorderRadius
                                                                .circular(360),
                                                      ),
                                                      const SizedBox(width: 12),
                                                      Expanded(
                                                        child: Directionality(
                                                          textDirection:
                                                              TextDirection.ltr,
                                                          child: DidvanText(
                                                            bots[index]
                                                                .name
                                                                .toString(),
                                                            maxLines: 1,
                                                            overflow:
                                                                TextOverflow
                                                                    .ellipsis,
                                                          ),
                                                        ),
                                                      ),
                                                    ],
                                                  ),
                                                ),
                                              ),
                                            )
                                          ];
                                        },
                                        child: const SizedBox(),
                                        // Container(
                                        //   alignment: Alignment.center,
                                        //   margin: const EdgeInsets.all(8),
                                        //   padding: const EdgeInsets.symmetric(
                                        //       horizontal: 8),
                                        //   constraints: const BoxConstraints(
                                        //       maxWidth: 100),
                                        //   decoration: BoxDecoration(
                                        //       borderRadius:
                                        //           DesignConfig.lowBorderRadius,
                                        //       border: Border.all(
                                        //           color: Theme.of(context)
                                        //               .colorScheme
                                        //               .title)),
                                        //   child: Row(
                                        //     children: [
                                        //       Expanded(
                                        //         child: Directionality(
                                        //           textDirection:
                                        //               TextDirection.ltr,
                                        //           child: DidvanText(
                                        //             '${widget.args.assistantsName ?? widget.args.bot.name}',
                                        //             maxLines: 1,
                                        //             overflow:
                                        //                 TextOverflow.ellipsis,
                                        //           ),
                                        //         ),
                                        //       ),
                                        //       const Icon(
                                        //           DidvanIcons.angle_down_light),
                                        //     ],
                                        //   ),
                                        // )
                                        ),
                                  if (message.role
                                          .toString()
                                          .contains('user') &&
                                      index ==
                                          state.messages[mIndex].prompts
                                                  .length -
                                              2 &&
                                      (widget.args.bot.editable != null &&
                                          widget.args.bot.editable!))
                                    Padding(
                                      padding: const EdgeInsets.all(8.0),
                                      child: InkWell(
                                        onTap: () async {
                                          state.isEdite = true;
                                          state.message.text =
                                              message.text.toString();
                                          state.update();
                                        },
                                        child: Icon(
                                          Icons.edit_outlined,
                                          size: 18,
                                          color: Theme.of(context)
                                              .colorScheme
                                              .focusedBorder,
                                        ),
                                      ),
                                    ),
                                  if (message.file != null && kIsWeb)
                                    Padding(
                                      padding: const EdgeInsets.all(8.0),
                                      child: InkWell(
                                        onTap: () async {
                                          final url =
                                              '${RequestHelper.baseUrl + message.file.toString()}?accessToken=${RequestService.token}';
                                          MediaService.downloadFileFromWeb(url);
                                        },
                                        child: Icon(
                                          DidvanIcons.download_solid,
                                          size: 18,
                                          color: Theme.of(context)
                                              .colorScheme
                                              .focusedBorder,
                                        ),
                                      ),
                                    ),
                                  if (message.file != null && !kIsWeb)
                                    Padding(
                                      padding: const EdgeInsets.all(8.0),
                                      child: InkWell(
                                        onTap: () async {
                                          debugPrint(
                                              "Download button tapped on iOS");
                                          final url =
                                              '${RequestHelper.baseUrl + message.file.toString()}?accessToken=${RequestService.token}';
                                          await MediaService.downloadFile(url,
                                              name: message.fileName);
                                        },
                                        child: Icon(
                                          DidvanIcons.download_solid,
                                          size: 18,
                                          color: Theme.of(context)
                                              .colorScheme
                                              .focusedBorder,
                                        ),
                                      ),
                                    ),
                                  if (message.error != null && message.error!)
                                    Padding(
                                      padding: const EdgeInsets.all(8.0),
                                      child: InkWell(
                                        onTap: () async {
                                          state.messages.last.prompts
                                              .remove(message);
                                          state.messages.last.prompts.add(
                                              message.copyWith(error: false));
                                          state.file = file;
                                          state.update();
                                          await state.postMessage(
                                              widget.args.bot,
                                              widget.args.assistantsName !=
                                                  null);
                                        },
                                        child: Icon(
                                          DidvanIcons.refresh_solid,
                                          size: 18,
                                          color: Theme.of(context)
                                              .colorScheme
                                              .focusedBorder,
                                        ),
                                      ),
                                    ),
                                  if (message.text != null && message.text!.isNotEmpty && (file == null || !file.isImage()))
                                    Padding(
                                      padding: const EdgeInsets.all(8.0),
                                      child: InkWell(
                                        onTap: () async {
                                          await Clipboard.setData(ClipboardData(
                                              text: state.messages[mIndex]
                                                  .prompts[index].text
                                                  .toString()));
                                          Future.delayed(
                                            Duration.zero,
                                            () => ActionSheetUtils(context)
                                                .showAlert(AlertData(
                                                    message:
                                                        "متن با موفقیت کپی شد",
                                                    aLertType:
                                                        ALertType.success)),
                                          );
                                        },
                                        child: Icon(
                                          DidvanIcons.copy_regular,
                                          size: 18,
                                          color: Theme.of(context)
                                              .colorScheme
                                              .focusedBorder,
                                        ),
                                      ),
                                    ),
                                  Padding(
                                    padding: const EdgeInsets.all(8.0),
                                    child: InkWell(
                                      onTap: () async {
                                        if (message.id != null) {
                                          state.deleteMessage(
                                              message.id!, mIndex, index);
                                        } else {
                                          state.messages[mIndex].prompts
                                              .removeAt(index);
                                          state.update();
                                        }
                                      },
                                      child: Icon(
                                        DidvanIcons.trash_solid,
                                        size: 18,
                                        color: Theme.of(context)
                                            .colorScheme
                                            .focusedBorder,
                                      ),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                            const SizedBox(height: 8),
                          ],
                        ),
                ),
              )
            ],
          ),
          const SizedBox(height: 4),
          Row(
            mainAxisSize: MainAxisSize.min,
            children: [
              DidvanText(
                DateTimeUtils.timeWithAmPm(message.createdAt.toString()),
                style: Theme.of(context).textTheme.labelSmall,
                color: Theme.of(context).colorScheme.caption,
              ),
            ],
          ),
        ],
      ),
    );
  }

  Container messageFile(
      BuildContext context, Prompts message, AiChatState state) {
    final String fileName = message.fileName ?? message.fileLocal?.name ?? '';
    return Container(
      decoration: BoxDecoration(
        borderRadius: DesignConfig.mediumBorderRadius,
        color: Theme.of(context).colorScheme.border,
      ),
      padding: const EdgeInsets.fromLTRB(12, 8, 12, 8),
      margin: const EdgeInsets.fromLTRB(8, 8, 8, 0),
      child: Row(
        children: [
          const Icon(Icons.file_copy),
          const SizedBox(
            width: 12,
          ),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                SizedBox(
                  width: MediaQuery.sizeOf(context).width,
                  child: MarqueeText(
                    text: fileName,
                    style: const TextStyle(fontSize: 14),
                    stop: const Duration(seconds: 3),
                    textDirection: fileName.startsWithEnglish()
                        ? TextDirection.ltr
                        : TextDirection.rtl,
                  ),
                ),
              ],
            ),
          )
        ],
      ),
    );
  }

  Widget messageImage(FilesModel file) {
    return GestureDetector(
      onTap: () => ActionSheetUtils(context)
          .openInteractiveViewer(context, file.path, !file.isNetwork()),
      child: file.isNetwork()
          ? file.path.startsWith('blob:')
              ? ClipRRect(
                  borderRadius: DesignConfig.lowBorderRadius,
                  child: Image.network(file.path))
              : SkeletonImage(
                  pWidth: MediaQuery.sizeOf(context).width / 1,
                  pHeight: MediaQuery.sizeOf(context).height / 6,
                  imageUrl: file.path,
                )
          : ClipRRect(
              borderRadius: DesignConfig.lowBorderRadius,
              child: Image.file(file.main)),
    );
  }
}