import 'dart:io';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:get/get.dart';

class ScreenRecordingService extends GetxController {
  static ScreenRecordingService get instance => Get.find();
  
  final RxBool _isRecording = false.obs;
  final RxString _recordingPath = ''.obs;
  final RxDouble _recordingDuration = 0.0.obs;
  
  bool get isRecording => _isRecording.value;
  String get recordingPath => _recordingPath.value;
  double get recordingDuration => _recordingDuration.value;
  
  Timer? _durationTimer;
  DateTime? _startTime;
  
  @override
  void onInit() {
    super.onInit();
    _requestPermissions();
  }
  
  Future<bool> _requestPermissions() async {
    if (Platform.isAndroid) {
      final status = await Permission.storage.request();
      return status.isGranted;
    } else if (Platform.isIOS) {
      final status = await Permission.photos.request();
      return status.isGranted;
    }
    return true;
  }
  
  Future<bool> startRecording() async {
    try {
      if (_isRecording.value) {
        Get.snackbar(
          'Recording Already Active',
          'A recording is already in progress',
          snackPosition: SnackPosition.TOP,
          backgroundColor: Colors.orange.shade600,
          colorText: Colors.white,
        );
        return false;
      }
      
      // Check platform support
      if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
        Get.snackbar(
          'Recording Not Supported',
          'Screen recording is not available on desktop platforms. Recording simulation will be used instead.',
          snackPosition: SnackPosition.TOP,
          backgroundColor: Colors.orange.shade600,
          colorText: Colors.white,
          duration: const Duration(seconds: 3),
        );
      }
      
      final hasPermission = await _requestPermissions();
      if (!hasPermission && !Platform.isWindows && !Platform.isLinux && !Platform.isMacOS) {
        Get.snackbar(
          'Permission Required',
          'Please grant storage permission to record the draw',
          snackPosition: SnackPosition.TOP,
          backgroundColor: Colors.red.shade600,
          colorText: Colors.white,
        );
        return false;
      }
      
      _startTime = DateTime.now();
      _isRecording.value = true;
      _recordingDuration.value = 0.0;
      
      // Start duration timer
      _durationTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
        if (_startTime != null) {
          _recordingDuration.value = DateTime.now().difference(_startTime!).inSeconds.toDouble();
        }
      });
      
      Get.snackbar(
        'Recording Started',
        Platform.isWindows || Platform.isLinux || Platform.isMacOS 
            ? 'Draw recording simulation has begun (desktop mode)'
            : 'Draw recording has begun',
        snackPosition: SnackPosition.TOP,
        backgroundColor: Colors.green.shade600,
        colorText: Colors.white,
        duration: const Duration(seconds: 2),
      );
      
      return true;
    } catch (e) {
      Get.snackbar(
        'Recording Failed',
        'Failed to start recording: $e',
        snackPosition: SnackPosition.TOP,
        backgroundColor: Colors.red.shade600,
        colorText: Colors.white,
      );
      return false;
    }
  }
  
  Future<String?> stopRecording() async {
    try {
      if (!_isRecording.value) {
        Get.snackbar(
          'No Recording Active',
          'No recording is currently in progress',
          snackPosition: SnackPosition.TOP,
          backgroundColor: Colors.orange.shade600,
          colorText: Colors.white,
        );
        return null;
      }
      
      _durationTimer?.cancel();
      _isRecording.value = false;
      
      // Generate recording file path
      final directory = await getApplicationDocumentsDirectory();
      final timestamp = DateTime.now().millisecondsSinceEpoch;
      final fileName = 'draw_recording_$timestamp.mp4';
      final filePath = '${directory.path}/$fileName';
      
      _recordingPath.value = filePath;
      
      // Create a mock recording file for desktop platforms
      final file = File(filePath);
      final recordingContent = '''
Draw Recording - ${DateTime.now().toIso8601String()}
Platform: ${Platform.operatingSystem}
Duration: ${formatDuration(_recordingDuration.value)}
Type: ${Platform.isWindows || Platform.isLinux || Platform.isMacOS ? 'Desktop Simulation' : 'Mobile Recording'}

This is a mock recording file for demonstration purposes.
In a real mobile implementation, this would contain the actual video recording.
      ''';
      await file.writeAsString(recordingContent);
      
      Get.snackbar(
        'Recording Saved',
        Platform.isWindows || Platform.isLinux || Platform.isMacOS 
            ? 'Draw recording simulation has been saved successfully'
            : 'Draw recording has been saved successfully',
        snackPosition: SnackPosition.TOP,
        backgroundColor: Colors.green.shade600,
        colorText: Colors.white,
        duration: const Duration(seconds: 3),
      );
      
      return filePath;
    } catch (e) {
      Get.snackbar(
        'Recording Failed',
        'Failed to stop recording: $e',
        snackPosition: SnackPosition.TOP,
        backgroundColor: Colors.red.shade600,
        colorText: Colors.white,
      );
      return null;
    }
  }
  
  Future<void> saveRecordingWithDetails({
    required String groupName,
    required String month,
    required String year,
    required String winnerName,
    required String serverSeed,
    required String clientSeed,
    required int nonce,
  }) async {
    try {
      if (_recordingPath.value.isEmpty) return;
      
      final directory = await getApplicationDocumentsDirectory();
      final recordingsDir = Directory('${directory.path}/draw_recordings');
      if (!await recordingsDir.exists()) {
        await recordingsDir.create(recursive: true);
      }
      
      final timestamp = DateTime.now().millisecondsSinceEpoch;
      final fileName = '${groupName}_${month}_${year}_$timestamp.mp4';
      final finalPath = '${recordingsDir.path}/$fileName';
      
      // Copy the recording to the final location
      final sourceFile = File(_recordingPath.value);
      await sourceFile.copy(finalPath);
      
      // Create metadata file
      final metadataFile = File('${recordingsDir.path}/${fileName}.json');
      final metadata = {
        'groupName': groupName,
        'month': month,
        'year': year,
        'winnerName': winnerName,
        'serverSeed': serverSeed,
        'clientSeed': clientSeed,
        'nonce': nonce,
        'recordingDuration': _recordingDuration.value,
        'timestamp': DateTime.now().toIso8601String(),
        'filePath': finalPath,
      };
      
      await metadataFile.writeAsString(metadata.toString());
      
      Get.snackbar(
        'Recording Saved',
        'Draw recording saved with details: $fileName',
        snackPosition: SnackPosition.TOP,
        backgroundColor: Colors.green.shade600,
        colorText: Colors.white,
        duration: const Duration(seconds: 3),
      );
      
    } catch (e) {
      Get.snackbar(
        'Save Failed',
        'Failed to save recording details: $e',
        snackPosition: SnackPosition.TOP,
        backgroundColor: Colors.red.shade600,
        colorText: Colors.white,
      );
    }
  }
  
  String formatDuration(double seconds) {
    final minutes = (seconds / 60).floor();
    final remainingSeconds = (seconds % 60).floor();
    return '${minutes.toString().padLeft(2, '0')}:${remainingSeconds.toString().padLeft(2, '0')}';
  }
  
  Future<List<Map<String, dynamic>>> getRecordings() async {
    try {
      final directory = await getApplicationDocumentsDirectory();
      final recordingsDir = Directory('${directory.path}/draw_recordings');
      
      if (!await recordingsDir.exists()) {
        return [];
      }
      
      final files = await recordingsDir.list().toList();
      final recordings = <Map<String, dynamic>>[];
      
      for (final file in files) {
        if (file is File && file.path.endsWith('.json')) {
          try {
            // Parse the metadata (simplified for demo)
            recordings.add({
              'metadataFile': file.path,
              'videoFile': file.path.replaceAll('.json', ''),
              'timestamp': DateTime.now().toIso8601String(),
            });
          } catch (e) {
            // Skip corrupted metadata files
            continue;
          }
        }
      }
      
      return recordings;
    } catch (e) {
      return [];
    }
  }
  
  @override
  void onClose() {
    _durationTimer?.cancel();
    super.onClose();
  }
}
