import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:medora/controllers/patient_controller.dart';
import 'package:medora/data/models/patient.dart';
import 'package:path/path.dart' as path;

class PatientProfileService {
  static final String patientProfileCollectionName =
      dotenv.env['PATIENT_PROFILE_COLLECTION_NAME']!;
  static final FirebaseFirestore db = FirebaseFirestore.instance;
  static final FirebaseStorage storage = FirebaseStorage.instanceFor(
      bucket: dotenv.env['FIREBASE_STORAGE_BUCKET']!);

  static Future<String?> uploadProfileImage(File imageFile) async {
    try {
      final User? user = FirebaseAuth.instance.currentUser;
      if (user == null) {
        print('No user logged in');
        return null;
      }
      final String uid = user.uid;
      final String fileName =
          'profile_${uid}_${DateTime.now().millisecondsSinceEpoch}${path.extension(imageFile.path)}';
      final Reference storageRef =
          storage.ref().child('profile_images/$fileName');
      final UploadTask uploadTask = storageRef.putFile(
        imageFile,
        SettableMetadata(
          contentType: 'image/${path.extension(imageFile.path).substring(1)}',
          customMetadata: {
            'userId': uid,
            'uploadedAt': DateTime.now().toIso8601String(),
          },
        ),
      );
      final TaskSnapshot snapshot = await uploadTask;
      final String downloadUrl = await snapshot.ref.getDownloadURL();

      print('Profile image uploaded successfully');
      return downloadUrl;
    } catch (e) {
      print('Error uploading profile image: $e');
      return null;
    }
  }

  static Future<bool> deleteProfileImage(String imageUrl) async {
    try {
      final Reference storageRef = storage.refFromURL(imageUrl);
      await storageRef.delete();
      print('Profile image deleted successfully');
      return true;
    } catch (e) {
      print('Error deleting profile image: $e');
      return false;
    }
  }

  static Future<bool> savePatientProfile(PatientController controller) async {
    try {
      final User? user = FirebaseAuth.instance.currentUser;
      if (user == null) {
        print('No user logged in');
        return false;
      }

      final String uid = user.uid;
      final PatientModel patientData = controller.model;
      String? imageUrl;
      if (patientData.profileImagePath != null) {
        final File imageFile = File(patientData.profileImagePath!);
        imageUrl = await uploadProfileImage(imageFile);
        if (imageUrl == null) {
          print('Failed to upload profile image');
          return false;
        }
      }

      final Map<String, dynamic> patientJson = patientData.toJson();
      patientJson['createdAt'] = FieldValue.serverTimestamp();
      patientJson['updatedAt'] = FieldValue.serverTimestamp();
      patientJson['uid'] = uid;
      patientJson['profileImageUrl'] = imageUrl;

      await db
          .collection(patientProfileCollectionName)
          .doc(uid)
          .set(patientJson);

      print('Patient profile saved successfully');
      return true;
    } catch (e) {
      print('Error saving patient profile: $e');
      return false;
    }
  }

  static Future<bool> updatePatientProfile(PatientModel patient) async {
    try {
      final User? user = FirebaseAuth.instance.currentUser;
      if (user == null) {
        print('No user logged in');
        return false;
      }

      final String uid = user.uid;
      String? imageUrl;
      if (patient.profileImagePath != null) {
        final DocumentSnapshot oldDoc =
            await db.collection(patientProfileCollectionName).doc(uid).get();
        if (oldDoc.exists) {
          final oldData = oldDoc.data() as Map<String, dynamic>;
          final String? oldImageUrl = oldData['profileImageUrl'];
          if (oldImageUrl != null) {
            await deleteProfileImage(oldImageUrl);
          }
        }
        final File imageFile = File(patient.profileImagePath!);
        imageUrl = await uploadProfileImage(imageFile);
        if (imageUrl == null) {
          print('Failed to upload new profile image');
          return false;
        }
      }

      final Map<String, dynamic> patientJson = patient.toJson();
      patientJson['updatedAt'] = FieldValue.serverTimestamp();
      if (imageUrl != null) {
        patientJson['profileImageUrl'] = imageUrl;
      }

      await db
          .collection(patientProfileCollectionName)
          .doc(uid)
          .update(patientJson);

      print('Patient profile updated successfully');
      return true;
    } catch (e) {
      print('Error updating patient profile: $e');
      return false;
    }
  }

  static Future<bool> deletePatientProfile() async {
    try {
      final User? user = FirebaseAuth.instance.currentUser;
      if (user == null) {
        print('No user logged in');
        return false;
      }

      final String uid = user.uid;
      final DocumentSnapshot doc =
          await db.collection(patientProfileCollectionName).doc(uid).get();
      if (doc.exists) {
        final data = doc.data() as Map<String, dynamic>;
        final String? imageUrl = data['profileImageUrl'];
        if (imageUrl != null) {
          await deleteProfileImage(imageUrl);
        }
      }

      await db.collection(patientProfileCollectionName).doc(uid).delete();

      print('Patient profile deleted successfully');
      return true;
    } catch (e) {
      print('Error deleting patient profile: $e');
      return false;
    }
  }

  static Future<PatientModel?> getPatientProfile() async {
    try {
      final User? user = FirebaseAuth.instance.currentUser;
      if (user == null) {
        print('No user logged in');
        return null;
      }
      final String uid = user.uid;
      final DocumentSnapshot doc =
          await db.collection(patientProfileCollectionName).doc(uid).get();
      if (!doc.exists) {
        print('No patient profile found for this user');
        return null;
      }
      final data = doc.data() as Map<String, dynamic>;
      return PatientModel.fromJson(data);
    } catch (e) {
      print('Error fetching patient profile: $e');
      return null;
    }
  }
}
