import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:image_picker/image_picker.dart';
import 'package:niogu_app/core/components/top_back_bar_app.dart';
import 'package:niogu_app/core/constants/app_color.dart';
import 'package:niogu_app/core/constants/app_font_size.dart';
import 'package:niogu_app/core/providers/app_provider.dart';
import 'package:niogu_app/core/router/app_route.dart';
import 'package:niogu_app/core/utils/extension_format.dart';
import 'package:niogu_app/core/utils/image_service.dart';
import 'package:niogu_app/core/enums/item_type.dart';
import 'package:niogu_app/core/utils/log_message.dart';
import 'package:niogu_app/core/enums/stock_card_type.dart';
import 'package:niogu_app/core/enums/stock_type.dart';
import 'package:niogu_app/core/system/system_setting.dart';
import 'package:niogu_app/core/enums/user_role.dart';
import 'package:niogu_app/core/widgets/custom_confirmation.dart';
import 'package:niogu_app/core/widgets/custom_selector.dart';
import 'package:niogu_app/core/widgets/custom_snackbar.dart';
import 'package:niogu_app/core/widgets/custom_text_form_field.dart';
import 'package:niogu_app/core/widgets/pop_up_notification.dart';
import 'package:niogu_app/features/goods/domain/entities/stock_card.dart';
import 'package:niogu_app/features/goods/products/domain/entities/category.dart';
import 'package:niogu_app/features/goods/products/domain/entities/product.dart';
import 'package:niogu_app/features/goods/products/presentation/providers/category_provider.dart';
import 'package:niogu_app/features/goods/products/presentation/providers/product_provider.dart';
import 'package:niogu_app/features/goods/products/presentation/screens/add_product_category_screen.dart';
import 'package:niogu_app/features/goods/products/presentation/screens/edit_product_category_screen.dart';
import 'package:niogu_app/features/goods/products/presentation/widgets/edit_product_shimmer.dart';
import 'package:niogu_app/features/goods/products/presentation/widgets/add_photo_button.dart';
import 'package:niogu_app/features/goods/presentation/widgets/dropdown_with_action.dart';
import 'package:niogu_app/features/goods/products/presentation/widgets/image_preview_card.dart';
import 'package:niogu_app/features/goods/products/presentation/widgets/selection_card.dart';
import 'package:niogu_app/features/goods/units/domain/entities/unit.dart';
import 'package:niogu_app/features/goods/units/presentation/providers/unit_provider.dart';
import 'package:niogu_app/features/goods/units/presentation/screens/add_unit_screen.dart';
import 'package:niogu_app/features/goods/units/presentation/screens/edit_unit_screen.dart';
import 'package:niogu_app/features/goods/domain/entities/outlet_inventory.dart';
import 'package:niogu_app/features/outlets/presentation/providers/outlet_provider.dart';
import 'package:sizer/sizer.dart';

class EditProductScreen extends ConsumerStatefulWidget {
  final String productId;
  final bool isMainOutlet;
  final bool isEditing;
  final bool hasNewVariant;
  final int newVariantCount;
  const EditProductScreen({
    super.key,
    required this.productId,
    this.isMainOutlet = true,
    this.isEditing = true,
    this.hasNewVariant = false,
    this.newVariantCount = 0,
  });

  @override
  ConsumerState<EditProductScreen> createState() => _EditProductScreenState();
}

class _EditProductScreenState extends ConsumerState<EditProductScreen> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  late final String _productId;

  late final bool _isMainOutlet;

  late final bool _isEditing;

  late final bool _hasNewVariant;

  late final int _newVariantCount;

  final TextEditingController _nameController = TextEditingController();

  final TextEditingController _costPriceController = TextEditingController();

  final TextEditingController _sellingPriceController = TextEditingController();

  final TextEditingController _stockController = TextEditingController();

  final ImagePicker _picker = ImagePicker();

  List<String> _productImages = [];

  bool _hasVariant = false;

  StockType _initialStockType = StockType.fixed;

  StockType _stockType = StockType.fixed;

  bool _isStockAlwaysAvailable = false;

  String? _selectedCategory;

  String? _selectedUnit;

  String? _productVariantId;

  String? _outletInventoryId;

  final List<String> _pathImageRemoves = [];

  final List<String?> _pathImageTemps = [];

  final List<DeleteProductVariant> _deleteVariants = [];

  bool _isLoading = true;

  List<String> _outletInventoryIds = [];

  List<double> _stockPrevs = [];

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    _productId = widget.productId;

    _isMainOutlet = widget.isMainOutlet;

    _isEditing = widget.isEditing;

    _hasNewVariant = widget.hasNewVariant;

    _newVariantCount = widget.newVariantCount;

    WidgetsBinding.instance.addPostFrameCallback((_) {
      Future.microtask(() {
        ref.invalidate(deleteProductVariantProvider);
        ref.invalidate(variantImageTempProvider);
      });

      Future.delayed(const Duration(milliseconds: 800), () {
        _fetchProduct();
      });
    });
  }

  @override
  void dispose() {
    // TODO: implement dispose
    _nameController.dispose();
    _costPriceController.dispose();
    _sellingPriceController.dispose();
    _stockController.dispose();
    super.dispose();
  }

  Future<void> _fetchProduct() async {
    try {
      final productRepository = ref.read(productRepositoryProvider);

      final product = await productRepository.fetchProductById(
        _productId,
        _isEditing,
      );

      if (!mounted) return;

      _productImages = product.productImages ?? [];
      _nameController.text = product.name;
      _selectedCategory = product.categoryId;
      _hasVariant = product.hasVariant;
      if (_hasVariant) {
        final variants = product.variants.map((variant) {
          return ProductWithVariant(
            productVariantId: variant.productVariantId,
            outletInventoryId: variant.outletInventoryId,
            imagePath: variant.image,
            name: variant.name,
            stock: variant.stock,
            costPrice: variant.costPrice,
            sellingPrice: variant.sellingPrice,
          );
        }).toList();

        _outletInventoryIds = product.variants.map((variant) {
          return variant.outletInventoryId;
        }).toList();

        _stockPrevs = product.variants.map((variant) {
          return variant.stock;
        }).toList();

        ref.read(productWithVariantProvider.notifier).state = variants;

        _isStockAlwaysAvailable =
            product.variants.last.stockType == StockType.unlimited;
      } else {
        _productVariantId = product.variants.single.productVariantId;

        _outletInventoryId = product.variants.single.outletInventoryId;

        _costPriceController.text = product.variants.single.costPrice
            .toStringWithoutTrailingZero();

        _sellingPriceController.text = product.variants.single.sellingPrice
            .toStringWithoutTrailingZero();

        _isStockAlwaysAvailable =
            product.variants.single.stockType == StockType.unlimited;

        _stockController.text = product.variants.single.stock
            .toStringWithoutTrailingZero();

        _outletInventoryIds.add(product.variants.single.outletInventoryId);

        _stockPrevs.add(product.variants.single.stock);
      }

      _initialStockType = _isStockAlwaysAvailable
          ? StockType.unlimited
          : StockType.fixed;

      _stockType = _initialStockType;

      _selectedUnit = product.unitId;

      setState(() {
        _isLoading = false;
      });
    } catch (e, st) {
      if (!mounted) return;

      setState(() {
        _isLoading = false;
      });

      LogMessage.log.e(e.toString(), error: e, stackTrace: st);

      CustomSnackbar.showError(context, "Ups, terjadi kesalahan");

      context.pop();
    }
  }

  List<Widget> _images(UserRole userRole) {
    if (userRole == UserRole.owner && _isMainOutlet) {
      return [
        ..._productImages.asMap().entries.map((entry) {
          final int index = entry.key;
          final String path = entry.value;

          final File imageFile = File(
            path.isNotEmpty ? path : "image not found",
          );

          final bool imageFileExists = imageFile.existsSync();

          return Padding(
            padding: EdgeInsets.only(right: 3.w),
            child: ImagePreviewCard(
              imageFileExists: imageFileExists,
              imageFile: imageFile,
              onTap: () => _removeImage(index),
            ),
          );
        }).toList(),

        if (_productImages.length < 3)
          AddPhotoButton(onTap: _showPickerOptions),
      ];
    }

    return [
      if (_productImages.isEmpty)
        ...[0, 1, 2].map((_) {
          return Container(
            width: 30.w,
            height: 30.w,
            margin: EdgeInsets.only(right: 3.w),
            decoration: BoxDecoration(
              color: Colors.grey[200],
              borderRadius: BorderRadius.circular(3.w),
            ),
            child: Icon(
              Icons.image_outlined,
              color: Colors.grey[400],
              size: 8.w,
            ),
          );
        }).toList()
      else ...[
        ..._productImages.map((imagePath) {
          final bool imagePathAvailable = imagePath.isNotEmpty;

          final File imageFile = File(
            imagePathAvailable ? imagePath : "image not found",
          );

          final bool imageFileExists = imageFile.existsSync();

          return Container(
            width: 30.w,
            height: 30.w,
            margin: EdgeInsets.only(right: 2.w),
            decoration: BoxDecoration(
              color: Colors.grey[200],
              borderRadius: BorderRadius.circular(3.w),
            ),
            child: imageFileExists
                ? ClipRRect(
                    borderRadius: BorderRadius.circular(2.5.w),
                    child: Image.file(
                      imageFile,
                      fit: BoxFit.cover,
                      width: double.infinity,
                      height: double.infinity,
                      errorBuilder: (context, error, stackTrace) {
                        return Icon(
                          Icons.error,
                          color: Colors.grey[400],
                          size: 8.w,
                        );
                      },
                    ),
                  )
                : Icon(
                    Icons.image_outlined,
                    color: Colors.grey[400],
                    size: 8.w,
                  ),
          );
        }).toList(),
        if (_productImages.length < 3)
          ...(_productImages.length == 1 ? [0, 1] : [0]).map((_) {
            return Container(
              width: 30.w,
              height: 30.w,
              margin: EdgeInsets.only(right: 3.w),
              decoration: BoxDecoration(
                color: Colors.grey[200],
                borderRadius: BorderRadius.circular(3.w),
              ),
              child: Icon(
                Icons.image_outlined,
                color: Colors.grey[400],
                size: 8.w,
              ),
            );
          }).toList(),
      ],
    ];
  }

  String? _validator({
    String? value,
    required String message1,
    String? message2,
    bool isNumber = false,
    bool isCostPrice = false,
    bool isSellingPrice = false,
    String? errorMessage,
  }) {
    if (value == null || value.isEmpty) {
      return message1;
    }

    try {
      if (isNumber && double.parse(value) <= 0) {
        if (isCostPrice) return message2;

        if (isSellingPrice) return message2;
      }
    } catch (e) {
      return errorMessage;
    }

    return null;
  }

  Future<void> _showPickerOptions() async {
    final bool isTablet = 100.w >= 600;
    showModalBottomSheet(
      context: context,
      backgroundColor: Colors.white,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(2.5.w)),
      ),
      constraints: const BoxConstraints(maxWidth: double.infinity),
      builder: (BuildContext context) {
        return SafeArea(
          child: Container(
            width: 100.w,
            padding: EdgeInsets.symmetric(vertical: 2.h, horizontal: 5.w),
            clipBehavior: Clip.hardEdge,
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.vertical(top: Radius.circular(6.w)),
            ),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                ListTile(
                  leading: Icon(Icons.photo_library, size: 6.w),
                  title: Text(
                    'Galeri',
                    style: TextStyle(
                      fontSize: isTablet
                          ? AppFontSize.medium.sp
                          : AppFontSize.small.sp,
                    ),
                  ),
                  onTap: () async {
                    await _getImage(ImageSource.gallery);
                    context.pop();
                  },
                ),

                SizedBox(height: 2.h),

                ListTile(
                  leading: Icon(Icons.photo_camera, size: 6.w),
                  title: Text(
                    'Kamera',
                    style: TextStyle(
                      fontSize: isTablet
                          ? AppFontSize.medium.sp
                          : AppFontSize.small.sp,
                    ),
                  ),
                  onTap: () async {
                    await _getImage(ImageSource.camera);
                    context.pop();
                  },
                ),
              ],
            ),
          ),
        );
      },
    );
  }

  Future<void> _getImage(ImageSource ImageSource) async {
    if (_productImages.length >= 3) {
      CustomSnackbar.showError(context, "Maksimal 3 foto produk!");
      return;
    }

    try {
      final XFile? pickedFile = await _picker.pickImage(
        source: ImageSource,
        imageQuality: 70,
      );

      if (pickedFile != null) {
        File tempFile = File(pickedFile.path);

        String? savedPath = await ImageService.saveImageToLocalDirectory(
          tempFile,
          "product_images",
        );

        if (savedPath != null) {
          _pathImageTemps.add(savedPath);
          setState(() {
            _productImages.add(savedPath);
          });
        }
      }
    } catch (e, st) {
      LogMessage.log.w(e.toString(), error: e, stackTrace: st);
      CustomSnackbar.showWarning(context, "Akses ditolak");
    }
  }

  Future<void> _removeImage(int index) async {
    _pathImageRemoves.add(_productImages[index]);
    setState(() {
      _productImages.removeAt(index);
    });
  }

  Future<void> _cleanUpImages(List<String?> variantImageTemps) async {
    for (var path in _pathImageTemps) {
      if (path != null) {
        await ImageService.deleteLocalImage(path);
      }
    }

    for (var path in variantImageTemps) {
      if (path != null) {
        await ImageService.deleteLocalImage(path);
      }
    }
  }

  double _totalStock(List<ProductWithVariant> productWithVariant) {
    double totalStock = 0;
    for (var variant in productWithVariant) {
      if (variant.productVariantId != null &&
          variant.outletInventoryId != null) {
        totalStock += variant.stock;
      }
    }

    return totalStock;
  }

  void _handleProductHasNotVariant() {
    final productWithVariant = ref.read(productWithVariantProvider);

    if (_hasVariant && productWithVariant.isNotEmpty) {
      if (_totalStock(productWithVariant) > 0) {
        showDialog(
          context: context,
          builder: (context) {
            return CustomConfirmation(
              title: "Ubah Jenis Produk ?",
              body:
                  "Produk akan diubah menjadi 'Tidak Memiliki Varian'. Semua varian sebelumnya akan dihapus secara otomatis di seluruh outlet.",
              color: Color(0xFFFFA000),
              icon: Icons.warning_amber_rounded,
              onConfirm: () {
                for (var variant in productWithVariant) {
                  if (variant.productVariantId != null &&
                      variant.outletInventoryId != null) {
                    _deleteVariants.add(
                      DeleteProductVariant(
                        productId: _productId,
                        productVariantId: variant.productVariantId!,
                        outletInventoryId: variant.outletInventoryId!,
                      ),
                    );
                  }
                }

                ref.read(deleteProductVariantProvider.notifier).state = [
                  ..._deleteVariants,
                ];

                setState(() {
                  _hasVariant = false;
                  _stockController.text = "0";
                });

                ref.read(productWithVariantProvider.notifier).state = [];
                CustomSnackbar.showSuccess(context, "Jenis produk diubah");
              },
            );
          },
        );
      } else {
        for (var variant in productWithVariant) {
          if (variant.productVariantId != null &&
              variant.outletInventoryId != null) {
            _deleteVariants.add(
              DeleteProductVariant(
                productId: _productId,
                productVariantId: variant.productVariantId!,
                outletInventoryId: variant.outletInventoryId!,
              ),
            );
          }
        }

        ref.read(deleteProductVariantProvider.notifier).state = [
          ..._deleteVariants,
        ];

        setState(() {
          _hasVariant = false;
          _stockController.text = "0";
        });

        ref.read(productWithVariantProvider.notifier).state = [];
        CustomSnackbar.showSuccess(context, "Jenis produk diubah");
      }
    } else {
      ref.read(deleteProductVariantProvider.notifier).state = [];
      setState(() => _hasVariant = false);
    }
  }

  void _handleProductHasVariant() {
    if (!_hasVariant &&
        !_isStockAlwaysAvailable &&
        _stockController.text != "0") {
      showDialog(
        context: context,
        builder: (context) {
          return CustomConfirmation(
            title: "Ubah Jenis Produk ?",
            body:
                "Produk akan diubah menjadi 'Memiliki Varian'. Sisa stok sebelumnya akan dihapus secara otomatis di seluruh outlet.",
            color: Color(0xFFFFA000),
            icon: Icons.warning_amber_rounded,
            onConfirm: () {
              _deleteVariants.add(
                DeleteProductVariant(
                  productId: _productId,
                  productVariantId: _productVariantId!,
                  outletInventoryId: _outletInventoryId!,
                ),
              );

              ref.read(deleteProductVariantProvider.notifier).state = [
                ..._deleteVariants,
              ];

              setState(() {
                _hasVariant = true;
                _stockController.text = "0";
              });
              CustomSnackbar.showSuccess(context, "Jenis produk diubah");
            },
          );
        },
      );
    } else if (!_hasVariant && _isStockAlwaysAvailable) {
      if (_productVariantId != null && _outletInventoryId != null) {
        _deleteVariants.add(
          DeleteProductVariant(
            productId: _productId,
            productVariantId: _productVariantId!,
            outletInventoryId: _outletInventoryId!,
          ),
        );

        ref.read(deleteProductVariantProvider.notifier).state = [
          ..._deleteVariants,
        ];
      }
      setState(() {
        _hasVariant = true;
      });
    } else if (!_hasVariant &&
        !_isStockAlwaysAvailable &&
        _stockController.text == "0") {
      if (_productVariantId != null && _outletInventoryId != null) {
        _deleteVariants.add(
          DeleteProductVariant(
            productId: _productId,
            productVariantId: _productVariantId!,
            outletInventoryId: _outletInventoryId!,
          ),
        );

        ref.read(deleteProductVariantProvider.notifier).state = [
          ..._deleteVariants,
        ];
      }

      setState(() {
        _hasVariant = true;
      });
    }
  }

  void _handleStockFixed() {
    final productWithVariant = ref.read(productWithVariantProvider);

    if (_hasVariant && productWithVariant.isNotEmpty) {
      final variants = productWithVariant.map((variant) {
        final double stock =
            variant.productVariantId == null &&
                variant.outletInventoryId == null
            ? variant.stock
            : 0.0;

        return ProductWithVariant(
          productVariantId: variant.productVariantId,
          outletInventoryId: variant.outletInventoryId,
          imagePath: variant.imagePath,
          name: variant.name,
          stock: stock,
          costPrice: variant.costPrice,
          sellingPrice: variant.sellingPrice,
        );
      }).toList();

      ref.read(productWithVariantProvider.notifier).state = variants;
    }
    setState(() {
      _isStockAlwaysAvailable = false;
      _stockType = StockType.fixed;
    });
    CustomSnackbar.showSuccess(context, "Jenis stok diubah");
  }

  void _handleStockAlwaysAvailbale() {
    final productWithVariant = ref.read(productWithVariantProvider);

    if (!_isStockAlwaysAvailable &&
        _hasVariant &&
        productWithVariant.isNotEmpty) {
      if (_totalStock(productWithVariant) > 0) {
        showDialog(
          context: context,
          builder: (context) {
            return CustomConfirmation(
              title: "Ubah Jenis Stok ?",
              body:
                  "Stok produk akan diubah menjadi 'Selalu Ada'. Sisa stok semua varian sebelumnya akan dihapus secara otomatis.",
              color: Color(0xFFFFA000),
              icon: Icons.warning_amber_rounded,
              onConfirm: () {
                final variants = productWithVariant.map((variant) {
                  final double stock =
                      variant.productVariantId == null &&
                          variant.outletInventoryId == null
                      ? variant.stock
                      : 0.0;

                  return ProductWithVariant(
                    productVariantId: variant.productVariantId,
                    outletInventoryId: variant.outletInventoryId,
                    imagePath: variant.imagePath,
      
                    name: variant.name,
                    stock: stock,
                    costPrice: variant.costPrice,
                    sellingPrice: variant.sellingPrice,
                  );
                }).toList();

                ref.read(productWithVariantProvider.notifier).state = variants;

                setState(() {
                  _isStockAlwaysAvailable = true;
                  _stockType = StockType.unlimited;
                });
                CustomSnackbar.showSuccess(context, "Jenis stok diubah");
              },
            );
          },
        );
      } else {
        setState(() {
          _isStockAlwaysAvailable = true;
          _stockType = StockType.unlimited;
        });
        CustomSnackbar.showSuccess(context, "Jenis stok diubah");
      }

      return;
    }

    final double stock = double.parse(_stockController.text.trim());

    if (!_isStockAlwaysAvailable &&
        !_hasVariant &&
        stock > 0 &&
        productWithVariant.isEmpty) {
      showDialog(
        context: context,
        builder: (context) {
          return CustomConfirmation(
            title: "Ubah Jenis Stok ?",
            body:
                "Stok produk akan diubah menjadi 'Selalu Ada'. Sisa stok sebelumnya akan dihapus secara otomatis.",
            color: Color(0xFFFFA000),
            icon: Icons.warning_amber_rounded,
            onConfirm: () {
              setState(() {
                _isStockAlwaysAvailable = true;
                _stockType = StockType.unlimited;
                _stockController.text = "0";
              });
              CustomSnackbar.showSuccess(context, "Jenis stok diubah");
            },
          );
        },
      );
      return;
    }

    if (!_isStockAlwaysAvailable) {
      setState(() {
        _isStockAlwaysAvailable = true;
        _stockType = StockType.unlimited;
      });
      CustomSnackbar.showSuccess(context, "Jenis stok diubah");
    }
  }

  Future<void> _saveProduct() async {
    if (!_formKey.currentState!.validate()) return;

    if (_selectedCategory == null) {
      CustomSnackbar.showError(context, "Kategori produk belum dipilih");
      return;
    }

    if (_selectedUnit == null) {
      CustomSnackbar.showError(context, "Satuan produk belum dipilih");
      return;
    }

    final productWithVariant = ref.read(productWithVariantProvider);

    if (_hasVariant && productWithVariant.isEmpty) {
      CustomSnackbar.showError(context, "Varian produk belum diatur");
      return;
    }

    if (!_hasVariant) {
      final double costPrice = double.parse(_costPriceController.text.trim());
      final double sellingPrice = double.parse(
        _sellingPriceController.text.trim(),
      );

      if (costPrice >= sellingPrice) {
        CustomSnackbar.showError(
          context,
          "Harga jual harus lebih besar dari modal",
        );
        return;
      }
    }

    final product = UpsertProduct(
      localId: _productId,
      categoryId: _selectedCategory!,
      unitId: _selectedUnit!.trim(),
      name: _nameController.text,
      localImagePath: _productImages,
      hasVariant: _hasVariant,
    );

    final List<UpsertProductVariant> productVariants = [];

    final List<UpsertOutletInventory> outletInventories = [];

    final outletId = await SystemSetting.getCurrentOutletId();

    final userId = await SystemSetting.getCurrentUserId();

    final List<StockCard> stockCards = [];

    final stockType = _isStockAlwaysAvailable
        ? StockType.unlimited
        : StockType.fixed;

    bool modeChange = false;

    String? modeBeforeChange;

    String? modeAfterChange;

    if (_initialStockType != _stockType) {
      modeChange = true;
      modeBeforeChange = _initialStockType.type;
      modeAfterChange = _stockType.type;
    }

    modeChange =
        modeChange && modeBeforeChange != null && modeAfterChange != null;

    List<DeleteProductVariant>? deleteVariants;

    if (ref.read(deleteProductVariantProvider).isNotEmpty) {
      deleteVariants = ref.read(deleteProductVariantProvider);
    }

    if (_hasVariant && productWithVariant.isNotEmpty) {
      for (var variant in productWithVariant) {
        productVariants.add(
          UpsertProductVariant(
            localId: variant.productVariantId,
            productId: product.localId,
            outletInventoryId: variant.outletInventoryId,
            name: variant.name,
            localImagePath: variant.imagePath,
            stock: variant.stock,
            costPrice: variant.costPrice,
            sellingPrice: variant.sellingPrice,
            isProductVariant: true,
          ),
        );
      }

      for (var variant in productVariants) {
        outletInventories.add(
          UpsertOutletInventory(
            localId: !_isEditing ? null : variant.outletInventoryId,
            outletId: outletId!,
            itemType: ItemType.product_variant,
            itemId: variant.localId,
            stockType: stockType,
            stock: _isStockAlwaysAvailable ? 0.0 : variant.stock!,
            costPrice: variant.costPrice!,
            sellingPrice: variant.sellingPrice!,
            purchasePrice: 0.0,
          ),
        );
      }

      final dataIds = _outletInventoryIds.map((inventory) => inventory).toSet();

      final dataStocks = _stockPrevs.map((stock) => stock).toList();

      final results = outletInventories.where((inventory) {
        return !dataIds.contains(inventory.localId) ||
            (dataIds.contains(inventory.localId) &&
                inventory.stock !=
                    dataStocks[_outletInventoryIds.indexOf(
                      inventory.localId,
                    )]) ||
            modeChange;
      }).toList();

      if (results.isNotEmpty) {
        for (var inventory in results) {
          stockCards.add(
            StockCard(
              outletInventoryId: inventory.localId,
              userId: userId!,
              stockCardType: StockCardType.initial_stock,
              qtyChange: inventory.stock,
              currentStock: inventory.stock,
              costPrice: inventory.costPrice,
              stockType: stockType,
              modeChange: modeChange,
              modeBeforeChange: modeBeforeChange,
              modeAfterChange: modeAfterChange,
            ),
          );
        }
      }
    } else {
      productVariants.add(
        UpsertProductVariant(
          localId: _productVariantId,
          productId: product.localId,
          name: product.name.trim(),
          isProductVariant: false,
        ),
      );

      final double stock = _isStockAlwaysAvailable
          ? 0.0
          : double.parse(_stockController.text.trim());

      final double costPrice = double.parse(_costPriceController.text.trim());

      outletInventories.add(
        UpsertOutletInventory(
          localId: !_isEditing ? null : _outletInventoryId,
          outletId: outletId!,
          itemType: ItemType.product_variant,
          itemId: productVariants.single.localId,
          stockType: stockType,
          stock: stock,
          costPrice: costPrice,
          sellingPrice: double.parse(_sellingPriceController.text.trim()),
          purchasePrice: 0.0,
        ),
      );

      final results = outletInventories.where((inventory) {
        return !_outletInventoryIds.contains(inventory.localId) ||
            (_outletInventoryIds.contains(inventory.localId) &&
                inventory.stock != _stockPrevs.single) ||
            modeChange ||
            !_isEditing;
      }).toList();

      if (results.isNotEmpty) {
        stockCards.add(
          StockCard(
            outletInventoryId: results.single.localId,
            userId: userId!,
            stockCardType: StockCardType.initial_stock,
            qtyChange: stock,
            currentStock: stock,
            costPrice: costPrice,
            stockType: stockType,
            modeChange: modeChange,
            modeBeforeChange: modeBeforeChange,
            modeAfterChange: modeAfterChange,
          ),
        );
      }
    }

    try {
      await ref
          .read(productControllerProvider.notifier)
          .saveProduct(
            product: product,
            productVariants: productVariants,
            deleteVariants: deleteVariants,
            outletInventories: outletInventories,
            stockCards: stockCards,
            modeChange: modeChange,
            modeBeforeChange: modeBeforeChange,
            modeAfterChange: modeAfterChange,
          );

      if (!mounted) return;

      for (var path in _pathImageRemoves) {
        await ImageService.deleteLocalImage(path);
      }

      ref.invalidate(deleteProductVariantProvider);

      ref.invalidate(variantImageTempProvider);

      CustomSnackbar.showSuccess(
        context,
        _isEditing ? "Produk diperbarui" : "Produk berhasil disimpan",
      );

      context.pop();
    } catch (e, st) {
      LogMessage.log.e(e.toString(), error: e, stackTrace: st);

      CustomSnackbar.showError(context, "Ups, terjadi kesalahan");
    }
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        final bool isTablet = 100.w >= 600;

        final messageActivity = ref.watch(messageActivityProvider);

        final currentUserRole = ref.watch(currentUserRoleProvider);

        final productWithVariantState = ref.watch(productWithVariantProvider);

        final selectedNewVariantState = ref.watch(selectedNewVariantProvider);

        final bool showStockField = !_hasVariant && !_isStockAlwaysAvailable;

        final List<Category> categories = [];

        final categoryState = ref.watch(categoryStreamProvider);

        categoryState.whenData((c) => categories.addAll(c));

        final List<Unit> units = [];

        final unitState = ref.watch(unitStreamProvider);

        unitState.whenData((u) => units.addAll(u));

        final productControllerState = ref.watch(productControllerProvider);

        String selectorTitle = "Atur varian produk";

        if (productWithVariantState.isNotEmpty) {
          selectorTitle =
              "Lihat ${productWithVariantState.length} varian produk";

          if (_hasNewVariant && _newVariantCount > 0) {
            final bool hasNewVariant = selectedNewVariantState.isNotEmpty;

            if (hasNewVariant) {
              selectorTitle += " (termasuk varian baru)";
            } else {
              selectorTitle += " (+ ${_newVariantCount} varian baru)";
            }
          }
        }

        return PopScope(
          canPop: false,
          onPopInvokedWithResult: (didPop, result) async {
            if (didPop) return;

            final variantImageTemps = ref.read(variantImageTempProvider);

            await _cleanUpImages(variantImageTemps);

            ref.invalidate(deleteProductVariantProvider);

            ref.invalidate(variantImageTempProvider);

            context.pop();
          },
          child: SafeArea(
            top: false,
            bottom: true,
            right: false,
            left: false,
            child: Stack(
              children: [
                Scaffold(
                  backgroundColor: const Color(0xFFF9FAFB),
                  appBar: TopBackBarApp(
                    title: _isEditing ? "Edit Produk" : "Tambah Produk",
                    onTap: () async {
                      final variantImageTemps = ref.read(
                        variantImageTempProvider,
                      );

                      await _cleanUpImages(variantImageTemps);

                      ref.invalidate(deleteProductVariantProvider);

                      ref.invalidate(variantImageTempProvider);

                      context.pop();
                    },
                  ),

                  body: _isLoading
                      ? const EditProductShimmer()
                      : SingleChildScrollView(
                          padding: EdgeInsets.symmetric(
                            horizontal: 5.w,
                            vertical: 3.h,
                          ),
                          child: Form(
                            key: _formKey,
                            child: Column(
                              children: [
                                Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [
                                    Row(
                                      mainAxisAlignment:
                                          MainAxisAlignment.spaceBetween,
                                      children: [
                                        Text(
                                          "Foto Produk",
                                          style: TextStyle(
                                            fontSize: isTablet
                                                ? AppFontSize.medium.sp
                                                : AppFontSize.small.sp,
                                            fontWeight: FontWeight.bold,
                                            color: Colors.black87,
                                          ),
                                        ),
                                        Text(
                                          "${_productImages.length}/3",
                                          style: TextStyle(
                                            fontSize: isTablet
                                                ? AppFontSize.medium.sp
                                                : AppFontSize.small.sp,
                                            color: Colors.grey[600],
                                          ),
                                        ),
                                      ],
                                    ),
                                    SizedBox(height: 1.5.h),

                                    SingleChildScrollView(
                                      scrollDirection: Axis.horizontal,
                                      child: Row(
                                        children: _images(currentUserRole!),
                                      ),
                                    ),
                                  ],
                                ),

                                SizedBox(height: 3.h),

                                CustomTextFormField(
                                  label: "Nama Produk",
                                  hint: "Contoh: Kopi Susu Gula Aren",
                                  controller: _nameController,
                                  validator: (value) => _validator(
                                    value: value,
                                    message1: "Nama produk belum diisi",
                                  ),
                                  readOnly:
                                      (currentUserRole == UserRole.owner &&
                                          !_isMainOutlet) ||
                                      currentUserRole == UserRole.admin,
                                ),

                                SizedBox(height: 2.5.h),

                                if (currentUserRole == UserRole.owner &&
                                    _isMainOutlet)
                                  DropdownWithAction(
                                    label: "Kategori Produk",
                                    value: _selectedCategory,
                                    items: categories,
                                    onChanged: (val) =>
                                        setState(() => _selectedCategory = val),
                                    onAdd: () async {
                                      FocusScope.of(context).unfocus();

                                      await Future.delayed(
                                        const Duration(milliseconds: 400),
                                      );

                                      showDialog(
                                        context: context,
                                        builder: (_) =>
                                            const AddProductCategoryScreen(),
                                      );
                                    },
                                    onEdit: () async {
                                      if (_selectedCategory == null) {
                                        CustomSnackbar.showError(
                                          context,
                                          "Kategori belum dipilih",
                                        );
                                      } else {
                                        final categoryRepository = ref.read(
                                          categoryRepositoryProvider,
                                        );

                                        final category =
                                            await categoryRepository
                                                .fetchCategoryById(
                                                  _selectedCategory!,
                                                );

                                        if (category != null) {
                                          showDialog(
                                            context: context,
                                            builder: (_) =>
                                                EditProductCategoryScreen(
                                                  category: category,
                                                ),
                                          );
                                        } else {
                                          CustomSnackbar.showError(
                                            context,
                                            "Kategori produk tidak tersedia",
                                          );
                                        }
                                      }
                                    },
                                  )
                                else
                                  CustomTextFormField(
                                    label: "Kategori Produk",
                                    controller: TextEditingController(
                                      text: categories
                                          .firstWhere(
                                            (category) =>
                                                category.id ==
                                                _selectedCategory!,
                                          )
                                          .name,
                                    ),
                                    readOnly: true,
                                  ),
                                SizedBox(height: 3.h),

                                if (currentUserRole == UserRole.owner &&
                                    _isMainOutlet) ...[
                                  Text(
                                    "Tipe Produk",
                                    style: TextStyle(
                                      fontSize: isTablet
                                          ? AppFontSize.medium.sp
                                          : AppFontSize.small.sp,
                                      fontWeight: FontWeight.bold,
                                    ),
                                  ),

                                  SizedBox(height: 1.5.h),

                                  Row(
                                    children: [
                                      Expanded(
                                        child: SelectionCard(
                                          title: "Tanpa Varian",
                                          isSelected: !_hasVariant,
                                          onTap: _handleProductHasNotVariant,
                                        ),
                                      ),

                                      SizedBox(width: 4.w),

                                      Expanded(
                                        child: SelectionCard(
                                          title: "Memiliki Varian",
                                          isSelected: _hasVariant,
                                          onTap: _handleProductHasVariant,
                                        ),
                                      ),
                                    ],
                                  ),

                                  SizedBox(height: 3.h),
                                ],

                                if (!_hasVariant) ...[
                                  CustomTextFormField(
                                    label: "Harga Modal",
                                    hint: "0",
                                    keyboardType: TextInputType.number,
                                    controller: _costPriceController,
                                    validator: (value) => _validator(
                                      value: value,
                                      message1: "Harga modal belum diisi",
                                      message2: "Harga modal lebih dari 0",
                                      isNumber: true,
                                      isCostPrice: true,
                                      errorMessage: "Harga modal tidak valid",
                                    ),
                                  ),

                                  SizedBox(height: 3.h),

                                  CustomTextFormField(
                                    label: "Harga Jual",
                                    hint: "0",
                                    keyboardType: TextInputType.number,
                                    controller: _sellingPriceController,
                                    validator: (value) => _validator(
                                      value: value,
                                      message1: "Harga jual belum diisi",
                                      message2: "Harga jual harus lebih dari 0",
                                      isNumber: true,
                                      isSellingPrice: true,
                                      errorMessage: "Harga jual tidak valid",
                                    ),
                                  ),
                                ] else
                                  CustomSelector(
                                    isTablet: isTablet,
                                    title: selectorTitle,
                                    padding: EdgeInsets.symmetric(
                                      horizontal: 4.w,
                                      vertical: 2.h,
                                    ),
                                    fontSize: isTablet
                                        ? AppFontSize.medium.sp
                                        : AppFontSize.small.sp,
                                    onTap: () async {
                                      FocusScope.of(context).unfocus();

                                      final isMainOutlet = await ref
                                          .read(outletRepositoryProvider)
                                          .fetchIsMainOutlet();

                                      await Future.delayed(
                                        const Duration(milliseconds: 400),
                                      );

                                      context.pushNamed(
                                        AppRoute.editVariantProductScreen,
                                        pathParameters: {"id": _productId},
                                        extra: {
                                          "is_main_outlet": isMainOutlet,
                                          "is_editing": _isEditing,
                                          "has_new_variant": _hasNewVariant,
                                          "is_stock_fixed":
                                              !_isStockAlwaysAvailable,
                                        },
                                      );
                                    },
                                  ),

                                if (currentUserRole == UserRole.owner &&
                                    _isMainOutlet) ...[
                                  SizedBox(height: 3.h),

                                  Text(
                                    "Jenis Stok",
                                    style: TextStyle(
                                      fontSize: isTablet
                                          ? AppFontSize.medium.sp
                                          : AppFontSize.small.sp,
                                      fontWeight: FontWeight.bold,
                                    ),
                                  ),
                                  SizedBox(height: 1.5.h),

                                  Row(
                                    children: [
                                      Expanded(
                                        child: SelectionCard(
                                          title: "Tetap",
                                          isSelected: !_isStockAlwaysAvailable,
                                          onTap: _handleStockFixed,
                                        ),
                                      ),

                                      SizedBox(width: 4.w),

                                      Expanded(
                                        child: SelectionCard(
                                          title: "Selalu Ada",
                                          isSelected: _isStockAlwaysAvailable,
                                          onTap: _handleStockAlwaysAvailbale,
                                        ),
                                      ),
                                    ],
                                  ),
                                ],

                                if (showStockField) ...[
                                  SizedBox(height: 3.h),

                                  CustomTextFormField(
                                    label: _isEditing
                                        ? "Sisa Stok"
                                        : "Stok Awal",
                                    hint: "100",
                                    keyboardType: TextInputType.number,
                                    controller: _stockController,
                                    readOnly: _isEditing,
                                    onTapReadOnlyMessage:
                                        "Tambah stok di menu stok masuk",
                                  ),
                                ],

                                SizedBox(height: 3.h),

                                if (currentUserRole == UserRole.owner &&
                                    _isMainOutlet)
                                  DropdownWithAction(
                                    label: "Satuan",
                                    value: _selectedUnit,
                                    items: units,
                                    onChanged: (val) =>
                                        setState(() => _selectedUnit = val),
                                    onAdd: () async {
                                      FocusScope.of(context).unfocus();

                                      await Future.delayed(
                                        const Duration(milliseconds: 400),
                                      );

                                      showDialog(
                                        context: context,
                                        builder: (_) => const AddUnitScreen(),
                                      );
                                    },
                                    onEdit: () async {
                                      if (_selectedUnit == null) {
                                        CustomSnackbar.showError(
                                          context,
                                          "Satuan belum dipilih",
                                        );
                                      } else {
                                        final unitRepository = ref.read(
                                          unitRepositoryProvider,
                                        );

                                        final unit = await unitRepository
                                            .fetchUnitById(_selectedUnit!);

                                        if (unit != null) {
                                          showDialog(
                                            context: context,
                                            builder: (_) {
                                              return EditUnitScreen(unit: unit);
                                            },
                                          );
                                        } else {
                                          CustomSnackbar.showError(
                                            context,
                                            "Satuan produk tidak tersedia",
                                          );
                                        }
                                      }
                                    },
                                  )
                                else
                                  CustomTextFormField(
                                    label: "Satuan",
                                    controller: TextEditingController(
                                      text: units
                                          .firstWhere(
                                            (unit) => unit.id == _selectedUnit!,
                                          )
                                          .name,
                                    ),
                                    readOnly: true,
                                  ),

                                SizedBox(height: 3.h),

                                SizedBox(
                                  width: double.infinity,
                                  height: 6.5.h,
                                  child: ElevatedButton(
                                    onPressed: productControllerState.isLoading
                                        ? null
                                        : _saveProduct,
                                    style: ElevatedButton.styleFrom(
                                      backgroundColor: AppColor.primaryColor,
                                      shape: RoundedRectangleBorder(
                                        borderRadius: BorderRadius.circular(
                                          2.0.w,
                                        ),
                                      ),
                                      disabledBackgroundColor:
                                          Colors.grey.shade300,
                                      elevation: 4,
                                    ),
                                    child: Text(
                                      "Simpan",
                                      style: TextStyle(
                                        color: Colors.white,
                                        fontSize: AppFontSize.medium.sp,
                                        fontWeight: FontWeight.bold,
                                      ),
                                    ),
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ),
                ),

                if (messageActivity != null)
                  PopupNotification(
                    isOwner: currentUserRole == UserRole.owner,
                    messages: messageActivity.messages,
                    type: messageActivity.type,
                  ),
              ],
            ),
          ),
        );
      },
    );
  }
}
