import 'dart:convert';
import 'package:siro_rider/constant/table_names.dart';
import 'package:siro_rider/main.dart';

class DbSql {
  static final DbSql instance = DbSql._();
  DbSql._();

  // Helper to read data as a list of maps from GetStorage
  List<Map<String, dynamic>> _readTable(String table) {
    String? dataString = box.read(table);
    if (dataString == null) return [];
    try {
      List<dynamic> parsed = jsonDecode(dataString);
      return parsed.map((e) => Map<String, dynamic>.from(e)).toList();
    } catch (e) {
      return [];
    }
  }

  // Helper to write data back to GetStorage
  void _writeTable(String table, List<Map<String, dynamic>> data) {
    box.write(table, jsonEncode(data));
  }

  Future<List<Map<String, dynamic>>> getAllData(String table) async {
    return _readTable(table);
  }

  Future<List<Map<String, dynamic>>> getCustomQuery(String query) async {
    String q = query.toLowerCase();
    String targetTable = TableName.recentLocations; // Default target
    
    // Determine the table
    if (q.contains(TableName.recentLocations.toLowerCase())) {
      targetTable = TableName.recentLocations;
    } else if (q.contains(TableName.carLocations.toLowerCase())) {
      targetTable = TableName.carLocations;
    } else if (q.contains(TableName.placesFavorite.toLowerCase())) {
      targetTable = TableName.placesFavorite;
    }

    List<Map<String, dynamic>> data = _readTable(targetTable);

    // Apply DISTINCT logic if needed based on query
    if (q.contains('distinct latitude, longitude, name, rate')) {
      // Manual distinct by name and location
      Map<String, Map<String, dynamic>> distinctMap = {};
      for (var item in data) {
        String key = '${item['latitude']}_${item['longitude']}_${item['name']}';
        if (!distinctMap.containsKey(key)) {
          distinctMap[key] = item;
        }
      }
      data = distinctMap.values.toList();
    }

    // Apply ORDER BY createdAt DESC logic
    if (q.contains('order by createdat desc')) {
      data.sort((a, b) {
        String dateA = a['createdAt'] ?? '';
        String dateB = b['createdAt'] ?? '';
        return dateB.compareTo(dateA);
      });
    }

    return data;
  }

  Future<int> insertData(Map<String, dynamic> map, String table) async {
    List<Map<String, dynamic>> data = _readTable(table);
    // Generate simple ID
    int newId = data.isEmpty ? 1 : (data.last['id'] as int? ?? 0) + 1;
    Map<String, dynamic> newMap = Map<String, dynamic>.from(map);
    newMap['id'] = newId;
    data.add(newMap);
    _writeTable(table, data);
    return newId;
  }

  Future<int> insertMapLocation(Map<String, dynamic> map, String table) async {
    List<Map<String, dynamic>> data = _readTable(table);
    
    // Check if exists
    int existingIndex = data.indexWhere((element) => 
        element['latitude'] == map['latitude'] &&
        element['longitude'] == map['longitude'] &&
        element['name'] == map['name']);
        
    if (existingIndex != -1) {
      // Update
      data[existingIndex] = Map<String, dynamic>.from(data[existingIndex]);
      data[existingIndex]['createdAt'] = DateTime.now().toIso8601String();
      for (var key in map.keys) {
        if (key != 'latitude' && key != 'longitude' && key != 'name') {
          data[existingIndex][key] = map[key];
        }
      }
      _writeTable(table, data);
      return data[existingIndex]['id'] as int? ?? 1;
    } else {
      // Insert
      int newId = data.isEmpty ? 1 : ((data.last['id'] as int?) ?? 0) + 1;
      Map<String, dynamic> newMap = Map<String, dynamic>.from(map);
      newMap['id'] = newId;
      newMap['createdAt'] = DateTime.now().toIso8601String();
      data.add(newMap);
      _writeTable(table, data);
      return newId;
    }
  }

  Future<int> updateData(Map<String, dynamic> map, String table, int id) async {
    List<Map<String, dynamic>> data = _readTable(table);
    int index = data.indexWhere((element) => element['id'] == id);
    if (index != -1) {
      data[index] = {...data[index], ...map};
      _writeTable(table, data);
      return 1;
    }
    return 0;
  }

  Future<int> deleteData(String table, int id) async {
    List<Map<String, dynamic>> data = _readTable(table);
    int initialLength = data.length;
    data.removeWhere((element) => element['id'] == id);
    if (data.length < initialLength) {
      _writeTable(table, data);
      return 1;
    }
    return 0;
  }

  Future<int> deleteAllData(String table) async {
    _writeTable(table, []);
    return 1;
  }
}
