import 'package:base_project/data/response/status.dart';
import 'dart:typed_data';
import 'package:dio/dio.dart';
import 'package:http_parser/http_parser.dart';
import '../../../../utils/toast_messages/toast_message_util.dart';
import '../../../../BuilderField/shared/utils/entity_field_store.dart';
import 'package:flutter/material.dart';
import '../Forma_Repo/Forma_repo_screen.dart';

class FormaViewModelScreen extends ChangeNotifier{
  final FormaRepoScreen repo = FormaRepoScreen();

 
  // State variables
  List<Map<String, dynamic>> _formaList = [];
  List<Map<String, dynamic>> _filteredList = [];
  bool _isLoading = false;
  String _errorMessage = '';
  int _currentPage = 0;
  int _pageSize = 10;
  bool _hasMoreData = true;
  String _searchQuery = '';

  // Getters
  List<Map<String, dynamic>> get formaList => _formaList;
  List<Map<String, dynamic>> get filteredList => _filteredList;
  bool get isLoading => _isLoading;
  String get errorMessage => _errorMessage;
  bool get hasMoreData => _hasMoreData;
  String get searchQuery => _searchQuery;

  // Set loading state
  void _setLoading(bool loading) {
    _isLoading = loading;
    notifyListeners();
  }

  // Set error message
  void _setError(String error) {
    _errorMessage = error;
    notifyListeners();
  }

  // Clear error
  void clearError() {
    _errorMessage = '';
    notifyListeners();
  }

  // Get forma list
  Future<void> getEntities() async {
    _setLoading(true);
    _setError('');

    try {
      final response = await repo.getEntities();

      if (response.status == Status.SUCCESS) {
        _formaList = response.data ?? [];
        _filteredList = List.from(_formaList);
        _currentPage = 0;
        _hasMoreData = true;
      } else {
        _setError(response.message ?? 'Failed to fetch forma list');
      }
    } catch (e) {
      _setError('Failed to fetch forma list: $e');
    } finally {
      _setLoading(false);
    }
  }

  // Get forma list with pagination
  Future<void> getAllWithPagination({bool refresh = false}) async {
    if (refresh) {
      _currentPage = 0;
      _formaList.clear();
      _filteredList.clear();
      _hasMoreData = true;
    }

    if (!_hasMoreData || _isLoading) return;

    _setLoading(true);
    _setError('');

    try {
      final response = await repo.getAllWithPagination(_currentPage, _pageSize);

      if (response.status == Status.SUCCESS) {
        final newItems = response.data ?? [];

        if (refresh) {
          _formaList = newItems;
        } else {
          _formaList.addAll(newItems);
        }

        _filteredList = List.from(_formaList);
        _currentPage++;

        // Check if we have more data
        _hasMoreData = newItems.length == _pageSize;
      } else {
        _setError(response.message ?? 'Failed to fetch Forma list');
      }
    } catch (e) {
      _setError('Failed to fetch forma list: $e');
    } finally {
      _setLoading(false);
    }
  }







// Variable to store image files
  List<Map<String, dynamic>> _fileupload_fieldFiles = [];

// Variable to store image files
  List<Map<String, dynamic>> _imageupload_fieldimageFiles = [];

// Variable to store image files
  List<Map<String, dynamic>> _video_fieldvideoFiles = [];

// Variable to store image files
  List<Map<String, dynamic>> _audio_fieldaudioFiles = [];







  // Create Forma
  Future<bool> createEntity(Map<String, dynamic> entity) async {
    _setLoading(true);
    _setError('');

    try {






  // Always source image selections from EntityFieldStore for simplicity
      final List<UploadItem> storefilefileupload_field = EntityFieldStore.instance
              .get<List<UploadItem>>('fileupload_field') ??
          <UploadItem>[];

      _fileupload_fieldFiles = storefilefileupload_field
          .map((u) => {'path': u.fileName, 'bytes': u.bytes})
          .toList();


      entity.remove('fileupload_field');


  // Always source image selections from EntityFieldStore for simplicity
      final List<UploadItem> storeImgsimageupload_field = EntityFieldStore.instance
              .get<List<UploadItem>>('imageupload_field') ??
          <UploadItem>[];

      _imageupload_fieldimageFiles = storeImgsimageupload_field
          .map((u) => {'path': u.fileName, 'bytes': u.bytes})
          .toList();


      entity.remove('imageupload_field');


  // Always source image selections from EntityFieldStore for simplicity
      final List<UploadItem> storevideovideo_field = EntityFieldStore.instance
              .get<List<UploadItem>>('video_field') ??
          <UploadItem>[];

      _video_fieldvideoFiles = storevideovideo_field
          .map((u) => {'path': u.fileName, 'bytes': u.bytes})
          .toList();


      entity.remove('video_field');


  // Always source image selections from EntityFieldStore for simplicity
      final List<UploadItem> storeaudioaudio_field = EntityFieldStore.instance
              .get<List<UploadItem>>('audio_field') ??
          <UploadItem>[];

      _audio_fieldaudioFiles = storeaudioaudio_field
          .map((u) => {'path': u.fileName, 'bytes': u.bytes})
          .toList();


      entity.remove('audio_field');








      final response = await repo.createEntity(entity);

      if (response.status == Status.SUCCESS) {
// Get the response ID for image upload

        final responseId = response.data!['id'].toString();






// Upload File if available
        if (_fileupload_fieldFiles.isNotEmpty) {
          await _uploadfileupload_field(responseId, _fileupload_fieldFiles);
          _fileupload_fieldFiles.clear(); // Clear after upload
        }

// Upload images if available
        if (_imageupload_fieldimageFiles.isNotEmpty) {
          await _uploadimageupload_field(responseId, _imageupload_fieldimageFiles);
          _imageupload_fieldimageFiles.clear(); // Clear after upload
        }

// Upload Video if available
        if (_video_fieldvideoFiles.isNotEmpty) {
          await _uploadvideo_field(responseId, _video_fieldvideoFiles);
          _video_fieldvideoFiles.clear(); // Clear after upload
        }

// Upload Audio if available
        if (_audio_fieldaudioFiles.isNotEmpty) {
          await _uploadaudio_field(responseId, _audio_fieldaudioFiles);
          _audio_fieldaudioFiles.clear(); // Clear after upload
        }







        ToastMessageUtil.showToast(
          message: 'forma created successfully',
          toastType: ToastType.success,
        );

        // Refresh the list
        await getEntities();






        EntityFieldStore.instance.remove('fileupload_field');


        EntityFieldStore.instance.remove('imageupload_field');


        EntityFieldStore.instance.remove('video_field');


        EntityFieldStore.instance.remove('audio_field');








        return true;
      } else {
        _setError(response.message ?? 'Failed to create Forma');
        ToastMessageUtil.showToast(
          message: response.message ?? 'Failed to create Forma',
          toastType: ToastType.error,
        );
        return false;
      }
    } catch (e) {
      _setError('Failed to create forma: $e');
      ToastMessageUtil.showToast(
        message: 'Failed to create Forma: $e',
        toastType: ToastType.error,
      );
      return false;
    } finally {
      _setLoading(false);
    }
  }

  // Update forma
  Future<bool> updateEntity(int id, Map<String, dynamic> entity) async {
    _setLoading(true);
    _setError('');

    try {
      final response = await repo.updateEntity(id, entity);

      if (response.status == Status.SUCCESS) {
        ToastMessageUtil.showToast(
          message: 'Forma updated successfully',
          toastType: ToastType.success,
        );

        // Update the item in the list
        final index = _formaList.indexWhere((item) => item['id'] == id);
        if (index != -1) {
          _formaList[index] = response.data!;
          _filteredList = List.from(_formaList);
          notifyListeners();
        }
        return true;
      } else {
        _setError(response.message ?? 'Failed to update Forma');
        ToastMessageUtil.showToast(
          message: response.message ?? 'Failed to update Forma',
          toastType: ToastType.error,
        );
        return false;
      }
    } catch (e) {
      _setError('Failed to update forma: $e');
      ToastMessageUtil.showToast(
        message: 'Failed to update Forma: $e',
        toastType: ToastType.error,
      );
      return false;
    } finally {
      _setLoading(false);
    }
  }

  // Delete forma
  Future<bool> deleteEntity(int id) async {
    _setLoading(true);
    _setError('');

    try {
      final response = await repo.deleteEntity(id);

      if (response.status == Status.SUCCESS) {
        ToastMessageUtil.showToast(
          message: 'Forma deleted successfully',
          toastType: ToastType.success,
        );

        // Remove the item from the list
        _formaList.removeWhere((item) => item['id'] == id);
        _filteredList = List.from(_formaList);
        notifyListeners();
        return true;
      } else {
        _setError(response.message ?? 'Failed to delete Forma');
        ToastMessageUtil.showToast(
          message: response.message ?? 'Failed to delete Forma',
          toastType: ToastType.error,
        );
        return false;
      }
    } catch (e) {
      _setError('Failed to delete forma: $e');
      ToastMessageUtil.showToast(
        message: 'Failed to delete Forma: $e',
        toastType: ToastType.error,
      );
      return false;
    } finally {
      _setLoading(false);
    }
  }

  // Search forma
  void searchforma(String query) {
    _searchQuery = query;

    if (query.isEmpty) {
      _filteredList = List.from(_formaList);
    } else {
      _filteredList = _formaList.where((item) {
        return

             
(item['name']?.toString().toLowerCase().contains(query.toLowerCase()) ??false) ||




             
(item['radio_field']?.toString().toLowerCase().contains(query.toLowerCase()) ??false) ||










             
(item['video_field']?.toString().toLowerCase().contains(query.toLowerCase()) ??false) ||




             
(item['audio_field']?.toString().toLowerCase().contains(query.toLowerCase()) ??false) ||




             
(item['currency']?.toString().toLowerCase().contains(query.toLowerCase()) ??false) ||




             
(item['qrcode_field']?.toString().toLowerCase().contains(query.toLowerCase()) ??false) ||




             
(item['barcode_field']?.toString().toLowerCase().contains(query.toLowerCase()) ??false) 


;
      }).toList();
    }
    notifyListeners();
  }

  // Clear search
  void clearSearch() {
    _searchQuery = '';
    _filteredList = List.from(_formaList);
    notifyListeners();
  }

  // Refresh data
  Future<void> refreshData() async {
    await getAllWithPagination(refresh: true);
  }











  // Helper method to upload multiple image files
  Future<void> _uploadfileupload_field(
      String responseId, List<dynamic> Files) async {
    try {
      for (var File in Files) {
        if (File is Map<String, dynamic> &&
            File.containsKey('path')) {
          String filePath = File['path'];
          Uint8List fileBytes = File['bytes'];

          // Upload each image file
          await uploadfileupload_field(
              responseId, 'Forma', filePath, fileBytes);
        }
      }
    } catch (error) {
      print('Error uploading files: $error');
      ToastMessageUtil.showToast(
          message: "Failed to upload images", toastType: ToastType.error);
    }
  }

// Modify the uploadfileupload_fieldimage function
  Future<void> uploadfileupload_field(String ref, String refTableNmae,
      String selectedFilePath, Uint8List imageTimageBytes) async {
    try {

      final Uint8List fileBytes = imageTimageBytes!;
      final mimeType = fileupload_fieldlookupMimeType(selectedFilePath);

      FormData formData = FormData.fromMap({
        'file': MultipartFile.fromBytes(
          fileBytes,
          filename: selectedFilePath
              .split('/')
              .last, // Get the file name from the path
          contentType: MediaType.parse(mimeType!),
        ),
      });


      await repo.fileupload_fieldUpload(ref, refTableNmae, formData).then((value) {
        ToastMessageUtil.showToast(
            message: "File uploaded successfully",
            toastType: ToastType.success);
      }).onError(
        (error, stackTrace) {
          print("error--$error");
          ToastMessageUtil.showToast(
              message: "Failed to upload file", toastType: ToastType.error);
        },
      );
    } catch (error) {
      print('Error occurred during form submission: $error');
    }
  }

// Modify the lookupMimeType function if needed
  String fileupload_fieldlookupMimeType(String filePath) {
    final ext = filePath.split('.').last;
    switch (ext) {
      case 'jpg':
      case 'jpeg':
        return 'image/jpeg';
      case 'png':
        return 'image/png';
      case 'pdf':
        return 'application/pdf';
      // Add more cases for other file types as needed
      default:
        return 'application/octet-stream'; // Default MIME type
    }
  }



  // Helper method to upload multiple image files
  Future<void> _uploadimageupload_field(
      String responseId, List<dynamic> imageFiles) async {
    try {
      for (var imageFile in imageFiles) {
        if (imageFile is Map<String, dynamic> &&
            imageFile.containsKey('path')) {
          String filePath = imageFile['path'];
          Uint8List fileBytes = imageFile['bytes'];

          // Upload each image file
          await uploadimageupload_field(
              responseId, 'Forma', filePath, fileBytes);
        }
      }
    } catch (error) {
      print('Error uploading image files: $error');
      ToastMessageUtil.showToast(
          message: "Failed to upload images", toastType: ToastType.error);
    }
  }

// Modify the uploadimageupload_fieldimage function
  Future<void> uploadimageupload_field(String ref, String refTableNmae,
      String selectedFilePath, Uint8List image_timageBytes) async {
    try {

      final Uint8List fileBytes = image_timageBytes!;
      final mimeType = imageupload_fieldlookupMimeType(selectedFilePath);

      FormData formData = FormData.fromMap({
        'file': MultipartFile.fromBytes(
          fileBytes,
          filename: selectedFilePath
              .split('/')
              .last, // Get the file name from the path
          contentType: MediaType.parse(mimeType!),
        ),
      });
await repo.imageupload_fieldUpload(ref, refTableNmae, formData).then((value) {
        ToastMessageUtil.showToast(
            message: "File uploaded successfully",
            toastType: ToastType.success);
      }).onError(
        (error, stackTrace) {
          print("error--$error");
          ToastMessageUtil.showToast(
              message: "Failed to upload file", toastType: ToastType.error);
        },
      );
    } catch (error) {
      print('Error occurred during form submission: $error');
    }
  }

// Modify the lookupMimeType function if needed
  String imageupload_fieldlookupMimeType(String filePath) {
    final ext = filePath.split('.').last;
    switch (ext) {
      case 'jpg':
      case 'jpeg':
        return 'image/jpeg';
      case 'png':
        return 'image/png';
      case 'pdf':
        return 'application/pdf';
      // Add more cases for other file types as needed
      default:
        return 'application/octet-stream'; // Default MIME type
    }
  }


  // Helper method to upload multiple image files
  Future<void> _uploadvideo_field(
      String responseId, List<dynamic> Files) async {
    try {
      for (var File in Files) {
        if (File is Map<String, dynamic> &&
            File.containsKey('path')) {
          String filePath = File['path'];
          Uint8List fileBytes = File['bytes'];

          // Upload each image file
          await uploadvideo_field(
              responseId, 'Forma', filePath, fileBytes);
        }
      }
    } catch (error) {
      print('Error uploading files: $error');
      ToastMessageUtil.showToast(
          message: "Failed to upload images", toastType: ToastType.error);
    }
  }
// Modify the uploadvideo_fieldimage function
  Future<void> uploadvideo_field(String ref, String refTableNmae,
      String selectedFilePath, Uint8List image_timageBytes) async {
    try {

      final Uint8List fileBytes = image_timageBytes!;
      final mimeType = video_fieldlookupMimeType(selectedFilePath);

      FormData formData = FormData.fromMap({
        'file': MultipartFile.fromBytes(
          fileBytes,
          filename: selectedFilePath
              .split('/')
              .last, // Get the file name from the path
          contentType: MediaType.parse(mimeType!),
        ),
      });


  
     await repo.video_fieldUpload(ref, refTableNmae, formData).then((value) {
        ToastMessageUtil.showToast(
            message: "File uploaded successfully",
            toastType: ToastType.success);
      }).onError(
        (error, stackTrace) {
          print("error--$error");
          ToastMessageUtil.showToast(
              message: "Failed to upload file", toastType: ToastType.error);
        },
      );
    } catch (error) {
      print('Error occurred during form submission: $error');
    }
  }

// Modify the lookupMimeType function if needed
  String video_fieldlookupMimeType(String filePath) {
    final ext = filePath.split('.').last.toLowerCase();
    switch (ext) {
      case 'mp4':
        return 'video/mp4';
      case 'mov':
        return 'video/quicktime';
      case 'avi':
        return 'video/x-msvideo';
      case 'wmv':
        return 'video/x-ms-wmv';
      case 'flv':
        return 'video/x-flv';
      case 'mkv':
        return 'video/x-matroska';
      // Add more cases for other file types as needed
      default:
        return 'application/octet-stream'; // Default MIME type
    }
  }







  // Helper method to upload multiple image files
  Future<void> _uploadaudio_field(
      String responseId, List<dynamic> Files) async {
    try {
      for (var File in Files) {
        if (File is Map<String, dynamic> &&
            File.containsKey('path')) {
          String filePath = File['path'];
          Uint8List fileBytes = File['bytes'];

          // Upload each image file
          await uploadaudio_field(
              responseId, 'Forma', filePath, fileBytes);
        }
      }
    } catch (error) {
      print('Error uploading files: $error');
      ToastMessageUtil.showToast(
          message: "Failed to upload images", toastType: ToastType.error);
    }
  }
// Modify the uploadaudio_fieldimage function
  Future<void> uploadaudio_field(String ref, String refTableNmae,
      String selectedFilePath, Uint8List image_timageBytes) async {
    try {

      final Uint8List fileBytes = image_timageBytes!;
      final mimeType = audio_fieldlookupMimeType(selectedFilePath);

      FormData formData = FormData.fromMap({
        'file': MultipartFile.fromBytes(
          fileBytes,
          filename: selectedFilePath
              .split('/')
              .last, // Get the file name from the path
          contentType: MediaType.parse(mimeType!),
        ),
      });


     await repo.audio_fieldUpload(ref, refTableNmae, formData).then((value) {
        ToastMessageUtil.showToast(
            message: "File uploaded successfully",
            toastType: ToastType.success);
      }).onError(
        (error, stackTrace) {
          print("error--$error");
          ToastMessageUtil.showToast(
              message: "Failed to upload file", toastType: ToastType.error);
        },
      );
    } catch (error) {
      print('Error occurred during form submission: $error');
    }
  }

// Modify the lookupMimeType function if needed
  String audio_fieldlookupMimeType(String filePath) {
  final ext = filePath.split('.').last.toLowerCase();
  switch (ext) {
    case 'mp3':
      return 'audio/mpeg';
    case 'wav':
      return 'audio/wav';
    case 'm4a':
      return 'audio/mp4';
    case 'flac':
      return 'audio/flac';
    // Add more cases for other audio formats as needed
    default:
      return 'application/octet-stream'; // Default MIME type
  }
}







}