import 'package:ai_chat_assistant/utils/common_util.dart';
import 'package:ai_chat_assistant/widgets/rotating_image.dart';
import 'package:t_basic_intl/intl.dart';
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import '../enums/message_status.dart';
import '../models/chat_message.dart';
import 'package:provider/provider.dart';
import '../services/message_service.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import '../utils/assets_util.dart';

class ChatBubble extends StatefulWidget {
  final ChatMessage message;

  const ChatBubble({super.key, required this.message});

  @override
  State<ChatBubble> createState() => _ChatBubbleState();
}

class _ChatBubbleState extends State<ChatBubble> {
  bool _liked = false;
  bool _disliked = false;

  ChatMessage get message => widget.message;

  @override
  Widget build(BuildContext context) {
    final isThinking = message.status == MessageStatus.thinking;
    final content = Container(
      constraints: const BoxConstraints(minWidth: 50),
      padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
      decoration: BoxDecoration(
        color: message.isUser
            ? CommonUtil.commonColor
            : Colors.white.withOpacity(0.12),
        borderRadius: message.isUser
            ? const BorderRadius.only(
                topLeft: Radius.circular(12),
                bottomLeft: Radius.circular(12),
                bottomRight: Radius.circular(12),
              )
            : const BorderRadius.only(
                topRight: Radius.circular(12),
                bottomLeft: Radius.circular(12),
                bottomRight: Radius.circular(12),
              ),
      ),
      child: message.isUser
          ? _buildUserContent()
          : _buildAssistantContent(isThinking),
    );

    // 用户气泡做宽度自适应处理
    final wrappedContent = message.isUser
        ? ConstrainedBox(
            constraints: const BoxConstraints(
              maxWidth: double.infinity,
            ),
            child: IntrinsicWidth(child: content),
          )
        : content;

    return Align(
      alignment: message.isUser ? Alignment.centerRight : Alignment.centerLeft,
      child: Column(
        crossAxisAlignment:
            message.isUser ? CrossAxisAlignment.end : CrossAxisAlignment.start,
        children: [wrappedContent],
      ),
    );
  }

  Widget _buildUserContent() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        if (message.text.trim().isEmpty) ...[
          _buildStatusRow(hasBottomMargin: false),
        ] else ...[
          _buildStatusRow(hasBottomMargin: true),
          Text(
            message.text,
            style: TextStyle(color: Colors.white, fontSize: 14),
          )
        ],
      ],
    );
  }

  Widget _buildAssistantContent(bool isThinking) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        _buildStatusRow(hasBottomMargin: message.text.trim().isNotEmpty),
        if (message.text.trim().isNotEmpty) _buildMarkdownBody(),
        _buildDisclaimer(isThinking),
      ],
    );
  }

  Widget _buildStatusRow({required bool hasBottomMargin}) {
    Widget icon;
    Color color;

    switch (message.status) {
      case MessageStatus.listening:
      case MessageStatus.recognizing:
      case MessageStatus.thinking:
        icon = RotatingImage(imagePath: 'thinking_circle.png');
        color = Colors.white;
        break;
      case MessageStatus.executing:
        icon = const SizedBox(
          width: 16,
          height: 16,
          child: CircularProgressIndicator(
              strokeWidth: 2,
              valueColor: AlwaysStoppedAnimation<Color>(Colors.blue)),
        );
        color = Colors.white;
        break;
      case MessageStatus.completed:
      case MessageStatus.success:
        icon = AssetsUtil.getImageWidget(
          'checked.png',
          width: 20,
          height: 20,
        );
        color = Colors.white;
        break;
      case MessageStatus.failure:
        icon = const Icon(Icons.error, size: 16, color: Colors.red);
        color = Colors.red;
        break;
      case MessageStatus.aborted:
        icon = const Icon(Icons.block, size: 16, color: Colors.grey);
        color = Colors.grey;
        break;
      default:
        return const SizedBox.shrink();
    }
    return _statusRow(
        icon: icon, color: color, hasBottomMargin: hasBottomMargin);
  }

  Widget _statusRow({
    required Widget icon,
    required Color color,
    required bool hasBottomMargin,
    Color? backgroundColor,
    BorderRadius? borderRadius,
  }) {
    return Container(
      margin: hasBottomMargin ? const EdgeInsets.only(bottom: 6) : null,
      decoration: backgroundColor != null
          ? BoxDecoration(
              color: backgroundColor,
              borderRadius: borderRadius ?? BorderRadius.circular(0))
          : null,
      padding: backgroundColor != null ? const EdgeInsets.all(6) : null,
      child: Row(
        mainAxisAlignment:
            message.isUser ? MainAxisAlignment.end : MainAxisAlignment.start,
        children: [
          icon,
          const SizedBox(width: 6),
          Text(
            Intl.getCurrentLocale().startsWith('zh')
                ? message.status.chinese
                : message.status.english,
            style: TextStyle(
                fontSize: 16, color: color, fontWeight: FontWeight.bold),
          ),
        ],
      ),
    );
  }

  Widget _buildMarkdownBody() {
    return MarkdownBody(
      data: message.text,
      styleSheet: _markdownStyleSheet,
      sizedImageBuilder: (config) {
        return Image.network(
          config.uri.toString(),
          width: config.width,
          height: config.height,
          errorBuilder: (context, error, stackTrace) {
            return const SizedBox.shrink();
          },
        );
      },
      onTapLink: (text, href, title) {
        // todo
      },
    );
  }

  static final MarkdownStyleSheet _markdownStyleSheet = MarkdownStyleSheet(
    p: const TextStyle(fontSize: 14, color: Colors.white, height: 1.5),
    h1: const TextStyle(
        fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white),
    h2: const TextStyle(
        fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white),
    h3: const TextStyle(
        fontSize: 16, fontWeight: FontWeight.bold, color: Colors.white),
    h4: const TextStyle(color: Colors.white, fontSize: 12, height: 1.5),
    h5: const TextStyle(color: Colors.white, fontSize: 12, height: 1.5),
    h6: const TextStyle(color: Colors.white, fontSize: 12, height: 1.5),
    strong: const TextStyle(
        color: Colors.white,
        fontSize: 15,
        height: 1.5,
        fontWeight: FontWeight.bold),
    em: const TextStyle(
        color: Colors.white,
        fontSize: 12,
        height: 1.5,
        fontStyle: FontStyle.italic),
    code: const TextStyle(
        fontSize: 16, backgroundColor: Color(0xFFF5F5F5), color: Colors.white),
    codeblockDecoration: BoxDecoration(
        color: const Color(0xFFF5F5F5), borderRadius: BorderRadius.circular(4)),
    blockquote: const TextStyle(color: Colors.white, fontSize: 12, height: 1.5),
    blockquoteDecoration: BoxDecoration(
        border: Border(left: BorderSide(color: Colors.grey, width: 4))),
    listBullet: const TextStyle(color: Colors.white, fontSize: 12, height: 1.5),
    tableHead: const TextStyle(
        color: Colors.white,
        fontSize: 12,
        height: 1.5,
        fontWeight: FontWeight.bold),
    tableBody: const TextStyle(color: Colors.white, fontSize: 12, height: 1.5),
    tableBorder: TableBorder.all(color: Colors.grey, width: 1),
    tableCellsPadding: const EdgeInsets.all(8),
    tableColumnWidth: const FlexColumnWidth(),
  );

  Widget _buildDisclaimer(bool isThinking) {
    if (!isThinking && message.status != MessageStatus.completed) {
      return const SizedBox.shrink();
    }
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const SizedBox(height: 6),
        const Opacity(
          opacity: 0.08,
          child: Divider(color: Colors.white, height: 1),
        ),
        const SizedBox(height: 12),
        ConstrainedBox(
          constraints: const BoxConstraints(minHeight: 24),
          child: isThinking
              ? Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    InkWell(
                      onTap: () {
                        Provider.of<MessageService>(context, listen: false)
                            .abortReply();
                      },
                      child: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          const Icon(Icons.stop_circle_outlined,
                              size: 18, color: CommonUtil.commonColor),
                          const SizedBox(width: 4),
                          Text(
                              Intl.getCurrentLocale().startsWith('zh')
                                  ? '停止回答'
                                  : 'Stop',
                              style: const TextStyle(
                                  color: Colors.white, fontSize: 14)),
                        ],
                      ),
                    )
                  ],
                )
              : Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Expanded(
                      child: Text(
                        Intl.getCurrentLocale().startsWith('zh')
                            ? '内容由AI生成，具体以实际情况为准'
                            : 'Generated by AI, for reference only.',
                        style:
                            const TextStyle(fontSize: 11, color: Colors.grey),
                      ),
                    ),
                    Row(
                      children: [
                        InkWell(
                          onTap: () async {
                            await Clipboard.setData(ClipboardData(
                                text:
                                    CommonUtil.cleanText(message.text, false)));
                            Fluttertoast.showToast(
                                msg: Intl.getCurrentLocale().startsWith('zh')
                                    ? '已复制到剪贴板'
                                    : 'Copied to clipboard');
                          },
                          child: Padding(
                            padding: const EdgeInsets.only(left: 12),
                            child: AssetsUtil.getImageWidget('copy.png',
                                width: 22,
                                height: 22),
                          ),
                        ),
                        InkWell(
                          onTap: () {
                            setState(() {
                              _liked = !_liked;
                              if (_liked) _disliked = false;
                            });
                          },
                          child: Padding(
                            padding: const EdgeInsets.only(left: 12),
                            child: _liked
                                ? AssetsUtil.getImageWidget('liked2.png',
                                    width: 22,
                                    height: 22)
                                : AssetsUtil.getImageWidget('liked1.png',
                                    width: 22,
                                    height: 22),
                          ),
                        ),
                        InkWell(
                          onTap: () {
                            setState(() {
                              _disliked = !_disliked;
                              if (_disliked) _liked = false;
                            });
                          },
                          child: Padding(
                              padding: const EdgeInsets.only(left: 12),
                              child: _disliked
                                  ? AssetsUtil.getImageWidget('disliked2.png',
                                      width: 22,
                                      height: 22)
                                  : AssetsUtil.getImageWidget('disliked1.png',
                                      width: 22,
                                      height: 22)),
                        ),
                      ],
                    ),
                  ],
                ),
        ),
      ],
    );
  }
}
