import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
import 'package:uuid/uuid.dart';
import '../database/database_helper.dart';
import '../models/session.dart';
import '../models/target_analysis.dart';
import '../models/shot.dart';
import '../models/weapon.dart';
import '../models/maintenance.dart';

class SessionRepository {
  final DatabaseHelper _databaseHelper;
  final Uuid _uuid;

  SessionRepository({
    DatabaseHelper? databaseHelper,
    Uuid? uuid,
  })  : _databaseHelper = databaseHelper ?? DatabaseHelper(),
        _uuid = uuid ?? const Uuid();

  Future<Session> createSession({
    String? id,
    required String weapon,
    String? weaponId,
    required int maxShotsPerTarget,
    required List<TargetAnalysis> analyses,
    String? notes,
    int distance = 25,
    DateTime? date,
  }) async {
    final session = Session(
      id: id ?? _uuid.v4(),
      weapon: weapon,
      weaponId: weaponId,
      maxShotsPerTarget: maxShotsPerTarget,
      analyses: analyses,
      createdAt: date ?? DateTime.now(),
      notes: notes,
      distance: distance,
    );

    await _databaseHelper.insertSession(session);
    return session;
  }

  Future<void> addAnalysisToSession(String sessionId, TargetAnalysis analysis) async {
    await _databaseHelper.insertTargetAnalysis(analysis, sessionId);
  }

  Future<TargetAnalysis> prepareTargetAnalysis({
    required String imagePath,
    required String sessionId,
    required dynamic targetType, // TargetType
    required List<Shot> shots,
    required int totalScore,
    double? groupingDiameter,
    double? groupingCenterX,
    double? groupingCenterY,
    String? notes,
    double? targetCenterX,
    double? targetCenterY,
    double? targetRadius,
  }) async {
    // Copy image to app documents directory
    final savedImagePath = await _saveImage(imagePath);

    return TargetAnalysis(
      id: _uuid.v4(),
      sessionId: sessionId,
      targetType: targetType,
      imagePath: savedImagePath,
      shots: shots,
      totalScore: totalScore,
      groupingDiameter: groupingDiameter,
      groupingCenterX: groupingCenterX,
      groupingCenterY: groupingCenterY,
      createdAt: DateTime.now(),
      notes: notes,
      targetCenterX: targetCenterX,
      targetCenterY: targetCenterY,
      targetRadius: targetRadius,
    );
  }

  Future<String> _saveImage(String sourcePath) async {
    final appDir = await getApplicationDocumentsDirectory();
    final imagesDir = Directory(path.join(appDir.path, 'target_images'));

    if (!await imagesDir.exists()) {
      await imagesDir.create(recursive: true);
    }

    final fileName = '${_uuid.v4()}${path.extension(sourcePath)}';
    final destPath = path.join(imagesDir.path, fileName);

    final sourceFile = File(sourcePath);
    await sourceFile.copy(destPath);

    return destPath;
  }

  Future<Session?> getSession(String id) async {
    return await _databaseHelper.getSession(id);
  }

  Future<List<Session>> getAllSessions({
    int? limit,
    int? offset,
  }) async {
    return await _databaseHelper.getAllSessions(
      limit: limit,
      offset: offset,
    );
  }

  Future<void> deleteSession(String id) async {
    final session = await getSession(id);
    if (session != null) {
      for (final analysis in session.analyses) {
        final imageFile = File(analysis.imagePath);
        if (await imageFile.exists()) {
          await imageFile.delete();
        }
      }
    }
    await _databaseHelper.deleteSession(id);
  }

  Future<Map<String, dynamic>> getStatistics() async {
    return await _databaseHelper.getStatistics();
  }

  String generateId() {
    return _uuid.v4();
  }

  // Weapon Repository methods
  Future<Weapon> addWeapon({
    required String name,
    required WeaponType type,
    required String caliber,
    required int magazineCount,
    required int magazineCapacity,
    String? notes,
    String? optic,
    String? silencer,
    String? trigger,
    String? customName,
  }) async {
    final weapon = Weapon(
      id: _uuid.v4(),
      name: name,
      type: type,
      caliber: caliber,
      magazineCount: magazineCount,
      magazineCapacity: magazineCapacity,
      notes: notes,
      createdAt: DateTime.now(),
      optic: optic,
      silencer: silencer,
      trigger: trigger,
      customName: customName,
    );
    await _databaseHelper.insertWeapon(weapon);
    return weapon;
  }

  Future<List<Weapon>> getWeapons() async {
    return await _databaseHelper.getAllWeapons();
  }

  Future<void> updateWeapon(Weapon weapon) async {
    await _databaseHelper.updateWeapon(weapon);
  }

  Future<void> deleteWeapon(String id) async {
    await _databaseHelper.deleteWeapon(id);
  }

  Future<int> getRoundsFiredForWeapon(String weaponId) async {
    return await _databaseHelper.getRoundsFiredForWeapon(weaponId);
  }

  Future<void> addMaintenanceEntry({
    required String weaponId,
    required MaintenanceType type,
    required String description,
    int? roundsSinceLast,
  }) async {
    final entry = MaintenanceEntry(
      id: _uuid.v4(),
      weaponId: weaponId,
      type: type,
      description: description,
      date: DateTime.now(),
      roundsSinceLastMaintenance: roundsSinceLast,
    );
    await _databaseHelper.insertMaintenance(entry);
  }

  Future<List<MaintenanceEntry>> getMaintenanceHistory(String weaponId) async {
    return await _databaseHelper.getMaintenanceForWeapon(weaponId);
  }

  Future<void> deleteMaintenanceEntry(String id) async {
    await _databaseHelper.deleteMaintenance(id);
  }
}
