import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import 'package:chepuhagram/data/models/message_model.dart';

class LocalDbService {
  static final LocalDbService _instance = LocalDbService._internal();
  static Database? _database;

  factory LocalDbService() => _instance;
  LocalDbService._internal();

  Future<Database> get database async {
    if (_database != null) return _database!;
    _database = await _initDb();
    return _database!;
  }

  Future<Database> _initDb() async {
    String path = join(await getDatabasesPath(), 'chat_app.db');
    return await openDatabase(
      path,
      version: 4,
      onCreate: (db, version) async {
        await db.execute('''
          CREATE TABLE messages(
            id INTEGER PRIMARY KEY,
            sender_id INTEGER,
            receiver_id INTEGER,
            content TEXT,
            timestamp TEXT,
            delivered_at TEXT,
            read_at TEXT,
            reply_to_id INTEGER,
            reply_to_text TEXT,
            edited_at TEXT
          )
        ''');
      },
      onUpgrade: (db, oldVersion, newVersion) async {
        if (oldVersion < 2) {
          await db.execute('ALTER TABLE messages ADD COLUMN delivered_at TEXT');
          await db.execute('ALTER TABLE messages ADD COLUMN read_at TEXT');
        }
        if (oldVersion < 3) {
          await db.execute(
            'ALTER TABLE messages ADD COLUMN reply_to_id INTEGER',
          );
          await db.execute(
            'ALTER TABLE messages ADD COLUMN reply_to_text TEXT',
          );
        }
        if (oldVersion < 4) {
          await db.execute('ALTER TABLE messages ADD COLUMN edited_at TEXT');
        }
      },
    );
  }

  Future<void> clearDatabase() async {
    final db = await database;
    await db.delete('messages');
  }

  // Сохранение списка сообщений (из истории)
  Future<void> saveMessages(List<dynamic> messages) async {
    final db = await database;
    Batch batch = db.batch();
    for (var msg in messages) {
      if (msg is MessageModel) {
        batch.insert('messages', {
          'id': msg.id,
          'sender_id': msg.senderId,
          'receiver_id': msg.receiverId,
          'content': msg.text, // ВАЖНО: сохраняй зашифрованный текст!
          'timestamp': msg.createdAt.toIso8601String(),
          'delivered_at': null,
          'read_at': null,
          'reply_to_id': msg.replyToId,
          'reply_to_text': msg.replyToText,
          'edited_at': msg.editedAt?.toIso8601String(),
        }, conflictAlgorithm: ConflictAlgorithm.replace);
      } else {
        // Если это Map из API
        batch.insert('messages', {
          'id': msg['id'],
          'sender_id': msg['sender_id'],
          'receiver_id':
              msg['receiver_id'], // Убедись, что ключ совпадает с API
          'content': msg['content'],
          'timestamp': msg['timestamp'],
          'delivered_at': msg['delivered_at'],
          'read_at': msg['read_at'],
          'reply_to_id': msg['reply_to_id'],
          'reply_to_text': msg['reply_to_text'],
          'edited_at': msg['edited_at'],
        }, conflictAlgorithm: ConflictAlgorithm.replace);
      }
    }
    await batch.commit(noResult: true);
  }

  // Получение сообщений конкретного чата
  Future<List<Map<String, dynamic>>> getChatHistory(
    int contactId,
    int myId,
  ) async {
    final db = await database;
    return await db.query(
      'messages',
      where:
          '(sender_id = ? AND receiver_id = ?) OR (sender_id = ? AND receiver_id = ?)',
      whereArgs: [contactId, myId, myId, contactId],
      orderBy: 'timestamp ASC',
    );
  }

  Future<int> deleteChatHistory(int contactId, int myId) async {
    final db = await database;
    return await db.delete(
      'messages',
      where:
          '(sender_id = ? AND receiver_id = ?) OR (sender_id = ? AND receiver_id = ?)',
      whereArgs: [contactId, myId, myId, contactId],
    );
  }

  Future<Map<String, dynamic>?> getLastMessage(int contactId, int myId) async {
    final db = await database;
    final rows = await db.query(
      'messages',
      columns: ['sender_id', 'receiver_id', 'content', 'timestamp'],
      where:
          '(sender_id = ? AND receiver_id = ?) OR (sender_id = ? AND receiver_id = ?)',
      whereArgs: [contactId, myId, myId, contactId],
      orderBy: 'timestamp DESC',
      limit: 1,
    );
    if (rows.isEmpty) return null;
    return rows.first;
  }

  Future<void> updateDeliveredAt(int messageId, DateTime deliveredAt) async {
    final db = await database;
    await db.update(
      'messages',
      {'delivered_at': deliveredAt.toIso8601String()},
      where: 'id = ?',
      whereArgs: [messageId],
    );
  }

  Future<void> updateReadAt(int messageId, DateTime readAt) async {
    final db = await database;
    await db.update(
      'messages',
      {'read_at': readAt.toIso8601String()},
      where: 'id = ?',
      whereArgs: [messageId],
    );
  }

  Future<void> updateMessageContent(
    int messageId,
    String content,
    DateTime? editedAt,
  ) async {
    final db = await database;
    await db.update(
      'messages',
      {'content': content, 'edited_at': editedAt?.toIso8601String()},
      where: 'id = ?',
      whereArgs: [messageId],
    );
  }

  Future<void> deleteMessage(int messageId) async {
    final db = await database;
    await db.delete('messages', where: 'id = ?', whereArgs: [messageId]);
  }
}
