import 'package:sqflite/sqflite.dart';
import 'package:uuid/uuid.dart';

import '../models/inventory_models.dart';
import 'database_helper.dart';

class InventoryRepository {
  InventoryRepository();

  final DatabaseHelper _dbHelper = DatabaseHelper();
  final Uuid _uuid = const Uuid();

  Future<List<InventorySummary>> fetchSummaries({bool includeHidden = false}) async {
    final db = await _dbHelper.database;
    final whereClauses = <String>[];
    if (!includeHidden) {
      whereClauses.add('COALESCE(mh.is_hidden, p.is_hidden, 0) = 0');
    }
    final whereSql = whereClauses.isEmpty ? '' : 'WHERE ${whereClauses.join(' AND ')}';

    final rows = await db.rawQuery('''
      SELECT p.id, p.name, p.category, p.default_unit_price, p.stock_quantity,
             MAX(m.created_at) AS last_movement_at
      FROM products p
      LEFT JOIN master_hidden mh ON mh.master_type = 'product' AND mh.master_id = p.id
      LEFT JOIN inventory_movements m ON m.product_id = p.id
      $whereSql
      GROUP BY p.id
      ORDER BY p.name COLLATE NOCASE ASC
    ''');

    return rows.map((row) {
      return InventorySummary(
        productId: row['id'] as String,
        productName: row['name'] as String? ?? '-',
        stockQuantity: row['stock_quantity'] as int? ?? 0,
        category: row['category'] as String?,
        defaultUnitPrice: row['default_unit_price'] as int?,
        lastMovementAt: row['last_movement_at'] != null ? DateTime.parse(row['last_movement_at'] as String) : null,
      );
    }).toList();
  }

  Future<List<InventoryMovement>> fetchMovements(String productId, {int limit = 50}) async {
    final db = await _dbHelper.database;
    final rows = await db.query(
      'inventory_movements',
      where: 'product_id = ?',
      whereArgs: [productId],
      orderBy: 'created_at DESC',
      limit: limit,
    );
    return rows.map(InventoryMovement.fromMap).toList();
  }

  Future<InventorySummary> recordMovement({
    required String productId,
    required InventoryMovementType type,
    required int quantity,
    required int quantityDelta,
    String? reference,
    String? notes,
  }) async {
    final db = await _dbHelper.database;
    late InventorySummary summary;
    await db.transaction((txn) async {
      final productRows = await txn.query('products', where: 'id = ?', whereArgs: [productId], limit: 1);
      if (productRows.isEmpty) {
        throw StateError('product not found: $productId');
      }
      final product = productRows.first;
      final currentStock = product['stock_quantity'] as int? ?? 0;
      final nextStock = currentStock + quantityDelta;
      final now = DateTime.now();
      final movement = InventoryMovement(
        id: _uuid.v4(),
        productId: productId,
        productNameSnapshot: product['name'] as String? ?? '-',
        type: type,
        quantity: quantity,
        quantityDelta: quantityDelta,
        reference: reference,
        notes: notes,
        createdAt: now,
      );

      await txn.insert('inventory_movements', movement.toMap(), conflictAlgorithm: ConflictAlgorithm.replace);
      await txn.update('products', {'stock_quantity': nextStock}, where: 'id = ?', whereArgs: [productId]);

      summary = InventorySummary(
        productId: productId,
        productName: product['name'] as String? ?? '-',
        stockQuantity: nextStock,
        category: product['category'] as String?,
        defaultUnitPrice: product['default_unit_price'] as int?,
        lastMovementAt: now,
      );
    });
    return summary;
  }
}
