import 'dart:convert';
import 'dart:developer';

import 'package:base_project/data/response/api_response.dart';
import 'package:base_project/model/user/user_profile.dart';
import 'package:base_project/repository/profile/profile_repo.dart';
import 'package:base_project/utils/managers/user_manager.dart';
import 'package:base_project/utils/toast_messages/toast_message_util.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:image_picker/image_picker.dart';

class ProfileViewModel extends ChangeNotifier {
  final _repo = ProfileRepo();
  Map<String, dynamic>? _sysAccount;
  Map<String, dynamic>? get sysAccount => _sysAccount;

  ApiResponse<UserProfile> userProfile = ApiResponse.loading();

  Uint8List? _profileImageBytes; // Variable for storing fetched image bytes

  bool _isUpdating = false;
  bool get isUpdating => _isUpdating;

  XFile? _profileImage;
  XFile? get profileImg => _profileImage;

  // Setters
  setUserProfile(ApiResponse<UserProfile> val) {
    userProfile = val;
    notifyListeners();
  }

  setUpdating(bool val) {
    _isUpdating = val;
    notifyListeners();
  }

  setImage(XFile? val) {
    _profileImage = val;
    notifyListeners();
  }

  setProfileImageBytes(Uint8List? val) {
    _profileImageBytes = val;
    notifyListeners();
  }

  // Picking an image from the gallery
  void pickImg(BuildContext context) async {
    final ImagePicker picker = ImagePicker();
    final XFile? image = await picker.pickImage(source: ImageSource.gallery);

    if (image != null) {
      setImage(image);
      updateImage(context);
    } else {
      ToastMessageUtil.showToast(
          message: "No image picked !!", toastType: ToastType.warning);
    }
  }

  // Fetching the user profile details
  Future<void> getProfile() async {
    setUserProfile(ApiResponse.loading());
    _repo.getProfileApi().then((value) {
      log("Profile Data--$value");
      setUserProfile(ApiResponse.success(UserProfile.fromJson(value)));
      try {
        _sysAccount =
            UserManager().account ?? value['sysAccount'] ?? value['account'];
      } catch (_) {}
    }).onError((error, stackTrace) {
      log("ERROR--$error");
      setUserProfile(ApiResponse.error(error.toString()));
      ToastMessageUtil.showToast(
          message: "Error fetching profile data", toastType: ToastType.error);
    });
  }

  Future<void> updateAccount(
      BuildContext context, Map<String, dynamic> form) async {
    setUpdating(true);
    try {
      final accId = UserManager().accountId;
      if (accId == null) {
        throw Exception('Account not found');
      }
      final body = {
        'companyName': form['companyName'],
        'workspace': form['workspace'],
        'gstNumber': form['gstNumber'],
        'mobile': form['mobile'],
        'email': form['email'],
        'pancard': form['pancard'],
        'working': form['working'],
        'active': form['active'],
      };
      final res = await _repo.updateAccountApi(accId, body);
      if (res is Map<String, dynamic>) {
        _sysAccount = res;
        await UserManager().setAccount(res);
      }
      ToastMessageUtil.showToast(
          message: 'Account Updated', toastType: ToastType.success);
      Navigator.pop(context);
    } catch (e) {
      ToastMessageUtil.showToast(
          message: 'Failed to update account', toastType: ToastType.error);
    } finally {
      setUpdating(false);
    }
  }

  // Fetching the profile image
  Future<void> getProfileImg() async {
    _repo.getProfileImgApi().then((value) {
      String base64Image = value['image'];
      // Remove data URL prefix and decode base64
      Uint8List imageBytes = base64Decode(base64Image.split(',').last);
      setProfileImageBytes(imageBytes); // Store image bytes
    }).onError((error, stackTrace) {
      log("Error Fetching Image--$error");
      ToastMessageUtil.showToast(
          message: "Error fetching profile image", toastType: ToastType.error);
    });
  }

  // Updating the profile details
  Future<void> updateProfile(BuildContext context, dynamic data) async {
    setUpdating(true);
    final uId = UserManager().userId;
    data['userId'] = uId.toString();
    print("Data--$data");
    _repo.updateProfileApi(data, uId).then((value) {
      log("Profile Update--$value");
      setUpdating(false);
      getProfile();
      ToastMessageUtil.showToast(
          message: "Profile Updated", toastType: ToastType.success);
      Navigator.pop(context); // Close dialog/screen after update
    }).onError((error, stackTrace) {
      log("Error Updating Profile--$error");
      setUpdating(false);
      ToastMessageUtil.showToast(
          message: "Error updating profile!!", toastType: ToastType.error);
    });
  }

  // Updating the profile image
  Future<void> updateImage(BuildContext context) async {
    if (_profileImage == null) return; // Ensure an image is selected

    setUpdating(true);
    Uint8List fileBytes = await _profileImage!.readAsBytes();

    FormData formData = FormData.fromMap({
      'imageFile': MultipartFile.fromBytes(
        fileBytes,
        filename: _profileImage!.name,
      ),
    });

    _repo.updateProfileImg(formData).then((value) {
      log("Image Update--$value");
      setUpdating(false);
      getProfileImg(); // Refresh the displayed image
      ToastMessageUtil.showToast(
          message: "Profile Image Updated", toastType: ToastType.success);
    }).onError((error, stackTrace) {
      log("Error Updating Image--$error");
      setUpdating(false);
      ToastMessageUtil.showToast(
          message: "Error updating image!!", toastType: ToastType.error);
    });
  }

  // Changing the password
  Future<void> changePassword(dynamic data) async {
    setUpdating(true);
    print("BODY--$data");

    _repo.changPassApi(data).then((value) {
      print("Password Change--$value");
      setUpdating(false);
      ToastMessageUtil.showToast(
          message: "Password updated", toastType: ToastType.success);
    }).onError((error, stackTrace) {
      print("Error Changing Password--$error");
      setUpdating(false);
      ToastMessageUtil.showToast(
          message: "Error updating password!!", toastType: ToastType.error);
    });
  }

  // Helper method to generate headers
  // Network headers are now centralized in NetworkApiService via UserManager

  // Method to return image bytes (can be used in the UI to display)
  Uint8List? get profileImageBytes => _profileImageBytes;

  void reset() {
    _profileImage = null;
    _profileImageBytes = null;
    userProfile = ApiResponse.loading(); // Or any default state
    notifyListeners();
  }
}
