import 'package:cross_file/cross_file.dart';
import 'package:hoshan/data/model/ai/bots_model.dart';

class MessagesModel {
  int? id;
  String? title;
  String? createdAt;
  Bots? bot;
  List<Messages>? messages;

  MessagesModel({this.id, this.title, this.createdAt, this.bot, this.messages});

  MessagesModel.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    title = json['title'];
    createdAt = json['created_at'];
    bot = json['bot'] != null ? Bots.fromJson(json['bot']) : null;
    if (json['messages'] != null) {
      messages = <Messages>[];
      json['messages'].forEach((v) {
        messages!.add(Messages.fromJson(v));
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['id'] = id;
    data['title'] = title;
    data['created_at'] = createdAt;
    if (bot != null) {
      data['bot'] = bot!.toJson();
    }
    if (messages != null) {
      data['messages'] = messages!.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class Messages {
  String? id;
  List<Content>? content;
  String? query;
  String? role;
  String? fileUrl;
  bool? like;
  bool? fromBot;
  bool? error;
  XFile? file;
  bool? retry;
  String? createdAt;

  Messages(
      {this.id,
      this.content,
      this.query,
      this.role,
      this.like,
      this.file,
      this.createdAt,
      this.error = false,
      this.retry = false}) {
    fromBot = (role == 'ai');
    if (content != null && content!.isNotEmpty) {
      // Sort content list: "image" first, then "text"
      content!.sort((a, b) {
        if (a.type == 'image_url' && b.type != 'image_url') {
          return -1; // a comes before b
        } else if (a.type != 'image_url' && b.type == 'image_url') {
          return 1; // b comes before a
        }
        return 0; // maintain original order if both are the same type
      });
    }

    // _getFile();
  }

  // Future<void> _getFile() async {
  //   file = await ChatbotRepository.createXFileFromUrl(fileUrl ?? '');
  // }

  Messages.fromJson(Map<String, dynamic> json) {
    error = false;
    id = json['id'];
    if (json['content'] != null) {
      if (json['content'] is List) {
        content = <Content>[];
        json['content'].forEach((v) {
          content!.add(Content.fromJson(v));
        });
      } else if (json['content'] is String) {
        content = [Content(type: 'text', text: json['content'])];
      }
    }
    role = json['role'];
    like = json['like'];
    createdAt = json['created_at'];

    fromBot = role == 'ai';
    if (content != null && content!.isNotEmpty) {
      // Sort content list: "image" first, then "text"
      content!.sort((a, b) {
        if (a.type == 'image_url' && b.type != 'image_url') {
          return -1; // a comes before b
        } else if (a.type != 'image_url' && b.type == 'image_url') {
          return 1; // b comes before a
        }
        return 0; // maintain original order if both are the same type
      });
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['id'] = id;
    if (content != null) {
      data['content'] = content!.map((v) => v.toJson()).toList();
    }
    data['role'] = role;
    data['like'] = like;
    data['created_at'] = createdAt;
    return data;
  }

  Messages copyWith(
      {String? id,
      List<Content>? content,
      String? role,
      String? createdAt,
      bool? like,
      bool? error,
      bool? retry,
      String? query,
      XFile? file}) {
    return Messages(
        id: id ?? this.id,
        content: content ?? this.content,
        like: like ?? this.like,
        error: error ?? this.error,
        role: role ?? this.role,
        file: file ?? this.file,
        createdAt: createdAt ?? this.createdAt,
        query: query ?? this.query,
        retry: retry ?? this.retry);
  }
}

class Content {
  String? type;
  String? text;
  FileUrl? imageUrl;
  FileUrl? audioUrl;
  FileUrl? pdfUrl;
  FileUrl? videoUrl;

  Content(
      {this.type,
      this.text,
      this.imageUrl,
      this.audioUrl,
      this.pdfUrl,
      this.videoUrl});

  Content.fromJson(Map<String, dynamic> json) {
    type = json['type'];
    text = json['text'];
    imageUrl =
        json['image_url'] != null ? FileUrl.fromJson(json['image_url']) : null;
    audioUrl =
        json['audio_url'] != null ? FileUrl.fromJson(json['audio_url']) : null;
    pdfUrl = json['pdf_url'] != null ? FileUrl.fromJson(json['pdf_url']) : null;
    videoUrl =
        json['video_url'] != null ? FileUrl.fromJson(json['video_url']) : null;
    
    // اگر سرور audioUrl/imageUrl/pdfUrl/videoUrl را ارسال نکرده باشد،
    // از روی text چک می‌کنیم که آیا URL است یا نه
    if (text != null && text!.isNotEmpty) {
      final trimmedText = text!.trim();
      if (trimmedText._isURL()) {
        if (audioUrl == null && trimmedText._isAudio()) {
          audioUrl = FileUrl(url: trimmedText);
          type = 'audio';
        } else if (imageUrl == null && trimmedText._isImage()) {
          imageUrl = FileUrl(url: trimmedText);
          type = 'image';
        } else if (pdfUrl == null && trimmedText._isDocument()) {
          pdfUrl = FileUrl(url: trimmedText);
          type = 'doc';
        } else if (videoUrl == null && trimmedText._isVideo()) {
          videoUrl = FileUrl(url: trimmedText);
          type = 'video';
        }
      }
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['type'] = type;
    data['text'] = text;
    if (imageUrl != null) {
      data['image_url'] = imageUrl!.toJson();
    }
    if (audioUrl != null) {
      data['audio_url'] = audioUrl!.toJson();
    }
    if (pdfUrl != null) {
      data['pdf_url'] = pdfUrl!.toJson();
    }
    if (videoUrl != null) {
      data['video_url'] = videoUrl!.toJson();
    }
    return data;
  }
}

class FileUrl {
  String? url;
  String? query;
  bool? attachment;

  FileUrl({this.url});
  FileUrl.fromJson(Map<String, dynamic> json) {
    url = json['url'];
    query = json['query'];
    attachment = json['attachment'];
  }
  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['url'] = url;
    data['query'] = query;
    data['attachment'] = attachment;
    return data;
  }
}

// توابع کمکی برای چک کردن نوع URL
extension _StringUrlCheck on String {
  bool _isURL() {
    return startsWith('http://') || startsWith('https://');
  }

  bool _isImage() {
    final lower = toLowerCase();
    return lower.endsWith('.jpg') ||
        lower.endsWith('.jpeg') ||
        lower.endsWith('.png') ||
        lower.endsWith('.gif') ||
        lower.endsWith('.webp') ||
        lower.endsWith('.bmp') ||
        lower.contains('.jpg?') ||
        lower.contains('.jpeg?') ||
        lower.contains('.png?') ||
        lower.contains('.gif?') ||
        lower.contains('.webp?');
  }

  bool _isAudio() {
    final lower = toLowerCase();
    return lower.endsWith('.mp3') ||
        lower.endsWith('.wav') ||
        lower.endsWith('.ogg') ||
        lower.endsWith('.m4a') ||
        lower.endsWith('.aac') ||
        lower.endsWith('.flac') ||
        lower.contains('.mp3?') ||
        lower.contains('.wav?') ||
        lower.contains('.ogg?') ||
        lower.contains('.m4a?') ||
        lower.contains('.aac?');
  }

  bool _isDocument() {
    final lower = toLowerCase();
    return lower.endsWith('.pdf') ||
        lower.endsWith('.doc') ||
        lower.endsWith('.docx') ||
        lower.contains('.pdf?') ||
        lower.contains('.doc?') ||
        lower.contains('.docx?');
  }

  bool _isVideo() {
    final lower = toLowerCase();
    return lower.endsWith('.mp4') ||
        lower.endsWith('.avi') ||
        lower.endsWith('.mov') ||
        lower.endsWith('.mkv') ||
        lower.endsWith('.webm') ||
        lower.contains('.mp4?') ||
        lower.contains('.avi?') ||
        lower.contains('.mov?') ||
        lower.contains('.mkv?');
  }
}
