import 'dart:async';
import 'dart:io';

import 'package:calendar_date_picker2/calendar_date_picker2.dart';
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/router/app_route.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/payment_status.dart';
import 'package:niogu_app/core/enums/stock_card_type.dart';
import 'package:niogu_app/core/widgets/custom_snackbar.dart';
import 'package:niogu_app/features/report/transaction/presentation/providers/transaction_report_provider.dart';
import 'package:niogu_app/features/stock_in/presentation/widgets/empty_item.dart';
import 'package:niogu_app/features/stock_in/presentation/widgets/item_quantity_amount.dart';
import 'package:niogu_app/features/stock_in/domain/entities/stock_in.dart';
import 'package:niogu_app/features/stock_in/presentation/provider/stock_in_provider.dart';
import 'package:niogu_app/features/stock_in/presentation/provider/stock_in_purchase_provider.dart';
import 'package:niogu_app/features/stock_in/presentation/widgets/financial_section.dart';
import 'package:niogu_app/features/stock_in/presentation/widgets/header_stock_in_purchase_section.dart';
import 'package:niogu_app/core/widgets/custom_proof_image_uploader.dart';
import 'package:niogu_app/features/stock_in/presentation/widgets/purchase_item_card.dart';
import 'package:sizer/sizer.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/utils/currency_format.dart';
import 'package:niogu_app/core/utils/extension_format.dart';

class StockInPurchaseScreen extends ConsumerStatefulWidget {
  const StockInPurchaseScreen({super.key});

  @override
  ConsumerState<StockInPurchaseScreen> createState() =>
      StockInPurchaseScreenState();
}

class StockInPurchaseScreenState extends ConsumerState<StockInPurchaseScreen>
    with AutomaticKeepAliveClientMixin {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  final TextEditingController _nameController = TextEditingController();

  final TextEditingController _phoneNumberController = TextEditingController();

  final TextEditingController _addressController = TextEditingController();

  final TextEditingController _discountController = TextEditingController();

  final TextEditingController _taxController = TextEditingController();

  final TextEditingController _noteController = TextEditingController();

  final TextEditingController _payController = TextEditingController();

  final ImagePicker _picker = ImagePicker();

  final List<String?> _imagePathTemps = [];

  DateTime _selectedDate = DateTime.now();

  bool _isSupplierFormVisible = false;

  bool _isOtherFormVisible = false;

  PaymentStatus _paymentStatus = PaymentStatus.paid;

  String _selectedPaymentStatus = "Lunas";

  bool _validateChange = false;

  double _changeAmount = 0.0;

  String? _imagePath;

  Timer? _debounce;

  @override
  // TODO: implement wantKeepAlive
  bool get wantKeepAlive => true;

  Map<String, TextEditingController> _controllers = {};

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

  @override
  void dispose() {
    _nameController.dispose();
    _phoneNumberController.dispose();
    _addressController.dispose();
    _discountController.dispose();
    _taxController.dispose();
    _payController.dispose();
    _noteController.dispose();
    _debounce?.cancel();
    super.dispose();
  }

  TextEditingController _controllerOf(SelectedItem item) {
    return _controllers.putIfAbsent(item.id, () {
      final double purchasePrice = item.itemType == ItemType.product_variant
          ? item.costPrice
          : item.purchasePrice;

      return TextEditingController(
        text: purchasePrice > 0
            ? purchasePrice.toStringWithoutTrailingZero()
            : '',
      );
    });
  }

  double _calculateTotalPurchase(List<SelectedItem> items) {
    return items.fold(0.0, (sum, item) {
      final double purchasePrice =
          double.tryParse(_controllerOf(item).text.trim()) ?? 0.0;
      return sum + item.quantity * purchasePrice;
    });
  }

  void _onPurchasePriceChange(String value) {
    final itemState = ref.read(selectedItemProvider(SelectedItemType.purchase));

    final items = itemState.values.where((item) {
      return item.type == SelectedItemType.purchase;
    }).toList();

    final double payAmount = double.tryParse(_payController.text.trim()) ?? 0.0;

    final double totalAmount = _calculateTotalAmount(items);

    _updateGlobalTotal(totalAmount);

    if (_debounce?.isActive ?? false) _debounce?.cancel();
    _debounce = Timer(const Duration(milliseconds: 400), () {
      setState(() {
        _validateChange = payAmount < totalAmount;
        if (payAmount >= totalAmount && items.isNotEmpty) {
          _changeAmount = payAmount - totalAmount;
        }
      });
    });
  }

  void _onCalculateChanged(String value) {
    final itemState = ref.read(selectedItemProvider(SelectedItemType.purchase));

    final items = itemState.values.where((item) {
      return item.type == SelectedItemType.purchase;
    }).toList();

    final double payAmount = double.tryParse(value) ?? 0.0;

    final double totalAmount = _calculateTotalAmount(items);

    _updateGlobalTotal(totalAmount);

    if (_debounce?.isActive ?? false) _debounce?.cancel();
    _debounce = Timer(const Duration(milliseconds: 400), () {
      setState(() {
        if (_paymentStatus == PaymentStatus.paid) {
          _validateChange = payAmount < totalAmount;
          _payController.text = value;

          if (payAmount >= totalAmount && items.isNotEmpty) {
            _changeAmount = payAmount - totalAmount;
          }
        } else if (_paymentStatus == PaymentStatus.partial) {
          _validateChange = payAmount >= totalAmount;
          _payController.text = value;

          if (totalAmount > payAmount && items.isNotEmpty) {
            _changeAmount = totalAmount - payAmount;
          }
        }
      });
    });
  }

  void _calculateChange(String value) {
    final itemState = ref.read(selectedItemProvider(SelectedItemType.purchase));

    final items = itemState.values.where((item) {
      return item.type == SelectedItemType.purchase;
    }).toList();

    final double payAmount = double.tryParse(value) ?? 0.0;

    final double totalAmount = _calculateTotalAmount(items);

    _updateGlobalTotal(totalAmount);

    if (_paymentStatus == PaymentStatus.paid) {
      _validateChange = payAmount < totalAmount;
      _payController.text = value;

      if (payAmount >= totalAmount && items.isNotEmpty) {
        _changeAmount = payAmount - totalAmount;
      }
    } else if (_paymentStatus == PaymentStatus.partial) {
      _validateChange = payAmount >= totalAmount;
      _payController.text = value;

      if (totalAmount > payAmount && items.isNotEmpty) {
        _changeAmount = totalAmount - payAmount;
      }
    }
  }

  void _discountOnChanged(String value) {
    final itemState = ref.read(selectedItemProvider(SelectedItemType.purchase));

    final items = itemState.values.where((item) {
      return item.type == SelectedItemType.purchase;
    }).toList();

    final double payAmount = double.tryParse(_payController.text.trim()) ?? 0.0;

    final double totalAmount = _calculateTotalAmount(items);

    _updateGlobalTotal(totalAmount);

    if (_debounce?.isActive ?? false) _debounce?.cancel();
    _debounce = Timer(const Duration(milliseconds: 400), () {
      setState(() {
        _validateChange = payAmount < totalAmount;
        _discountController.text = value;
      });
    });

    if (_payController.text.trim().isNotEmpty) {
      _calculateChange(_payController.text);
    }
  }

  void _taxOnChanged(String value) {
    final itemState = ref.read(selectedItemProvider(SelectedItemType.purchase));

    final items = itemState.values.where((item) {
      return item.type == SelectedItemType.purchase;
    }).toList();

    final double payAmount = double.tryParse(_payController.text.trim()) ?? 0.0;

    final double totalAmount = _calculateTotalAmount(items);

    if (_debounce?.isActive ?? false) _debounce?.cancel();
    _debounce = Timer(const Duration(milliseconds: 400), () {
      setState(() {
        _validateChange = payAmount < totalAmount;
        _taxController.text = value;
      });
    });

    if (_payController.text.trim().isNotEmpty) {
      _calculateChange(_payController.text);
    }
  }

  void _onChangePaymentStatus(String? value) {
    final itemState = ref.read(selectedItemProvider(SelectedItemType.purchase));

    final items = itemState.values.where((item) {
      return item.type == SelectedItemType.purchase;
    }).toList();

    final double payAmount = double.tryParse(_payController.text.trim()) ?? 0.0;

    final double totalAmount = _calculateTotalAmount(items);

    _updateGlobalTotal(totalAmount);

    setState(() {
      _selectedPaymentStatus = value!;
      if (value == 'Lunas') {
        _paymentStatus = PaymentStatus.paid;
        _validateChange = payAmount < totalAmount;
        if (payAmount >= totalAmount && items.isNotEmpty) {
          _changeAmount = payAmount - totalAmount;
        }
      } else if (value == 'Bayar Sebagian') {
        _paymentStatus = PaymentStatus.partial;
        _validateChange = payAmount >= totalAmount;
        if (totalAmount > payAmount && items.isNotEmpty) {
          _changeAmount = totalAmount - payAmount;
        }
      } else if (value == 'Hutang') {
        _paymentStatus = PaymentStatus.debt;
      }
    });
  }

  double _calculateTotalAmount(List<SelectedItem> items) {
    final double discount =
        double.tryParse(_discountController.text.trim()) ?? 0.0;

    final double tax = double.tryParse(_taxController.text.trim()) ?? 0.0;

    final double totalPurchase = _calculateTotalPurchase(items);

    return totalPurchase - discount + tax;
  }

  Future<void> _showPurchaseDatePicker(BuildContext context) async {
    final bool isTablet = 100.w >= 600;

    List<DateTime?> tempPickedDate = [_selectedDate];

    final List<DateTime?>? results = await showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      backgroundColor: Colors.transparent,
      constraints: const BoxConstraints(maxWidth: double.infinity),
      builder: (context) {
        return Container(
          height: 80.h,
          width: double.infinity,
          decoration: BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.vertical(top: Radius.circular(4.5.w)),
          ),
          constraints: BoxConstraints(
            maxHeight: 80.h,
            maxWidth: double.infinity,
          ),
          child: Column(
            children: [
              SizedBox(height: 1.5.h),
              Container(
                width: 12.w,
                height: 0.6.h,
                decoration: BoxDecoration(
                  color: Colors.grey[300],
                  borderRadius: BorderRadius.circular(2.5.w),
                ),
              ),
              Padding(
                padding: EdgeInsets.symmetric(vertical: 2.h),
                child: Text(
                  "Pilih Tanggal Diterima",
                  style: TextStyle(
                    fontSize: isTablet
                        ? AppFontSize.medium.sp
                        : AppFontSize.small.sp,
                    fontWeight: FontWeight.bold,
                    color: Colors.black87,
                  ),
                ),
              ),
              Divider(height: 1, color: Colors.grey[200]),

              Expanded(
                child: CalendarDatePicker2(
                  config: CalendarDatePicker2Config(
                    calendarType: CalendarDatePicker2Type.single,
                    selectedDayHighlightColor: AppColor.primaryColor,
                    weekdayLabels: [
                      'Min',
                      'Sen',
                      'Sel',
                      'Rab',
                      'Kam',
                      'Jum',
                      'Sab',
                    ],
                    weekdayLabelTextStyle: TextStyle(
                      color: Colors.grey[600],
                      fontWeight: FontWeight.bold,
                    ),
                    controlsTextStyle: TextStyle(
                      color: Colors.black,
                      fontWeight: FontWeight.bold,
                      fontSize: isTablet
                          ? AppFontSize.medium.sp
                          : AppFontSize.small.sp,
                    ),
                    dayTextStyle: TextStyle(
                      color: Colors.black87,
                      fontWeight: FontWeight.w500,
                    ),

                    centerAlignModePicker: true,
                    firstDayOfWeek: 1, // Senin
                  ),
                  value: tempPickedDate,
                  onValueChanged: (dates) {
                    tempPickedDate = dates;
                  },
                ),
              ),

              Container(
                padding: EdgeInsets.all(5.w),
                decoration: BoxDecoration(
                  color: Colors.white,
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black.withOpacity(0.05),
                      blurRadius: 10,
                      offset: const Offset(0, -5),
                    ),
                  ],
                ),
                child: Row(
                  children: [
                    Expanded(
                      child: OutlinedButton(
                        onPressed: () => context.pop(),
                        style: OutlinedButton.styleFrom(
                          padding: EdgeInsets.symmetric(vertical: 1.5.h),
                          side: BorderSide(color: AppColor.primaryColor),
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(2.5.w),
                          ),
                        ),
                        child: Text(
                          "Batal",
                          style: TextStyle(
                            color: AppColor.primaryColor,
                            fontWeight: FontWeight.bold,
                            fontSize: AppFontSize.medium.sp,
                          ),
                        ),
                      ),
                    ),
                    SizedBox(width: 3.w),

                    Expanded(
                      child: ElevatedButton(
                        onPressed: () {
                          context.pop(tempPickedDate);
                        },
                        style: ElevatedButton.styleFrom(
                          padding: EdgeInsets.symmetric(vertical: 1.5.h),
                          backgroundColor: AppColor.primaryColor,
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(2.5.w),
                          ),
                        ),
                        child: Text(
                          "Pilih",
                          style: TextStyle(
                            color: Colors.white,
                            fontWeight: FontWeight.bold,
                            fontSize: AppFontSize.medium.sp,
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        );
      },
    );

    if (results != null && results.isNotEmpty && results[0] != null) {
      setState(() {
        _selectedDate = results[0]!;
      });
    }
  }

  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 {
    try {
      final XFile? pickedFile = await _picker.pickImage(
        source: ImageSource,
        imageQuality: 70,
      );

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

        String? imagePath = await ImageService.saveImageToLocalDirectory(
          tempFile,
          "payment_proof_purchases",
        );

        if (imagePath != null) {
          _imagePathTemps.add(imagePath);
          ref.read(proofPaymentPurchaseTempProvider.notifier).state =
              _imagePathTemps;
          setState(() {
            _imagePath = imagePath;
          });
        }
      }
    } catch (e, st) {
      LogMessage.log.w(e.toString(), error: e, stackTrace: st);
      CustomSnackbar.showWarning(context, "Akses ditolak");
    }
  }

  Future<void> _removeImage() async {
    setState(() {
      _imagePath = null;
    });
  }

  void _updateGlobalTotal(double totalAmount) {
    ref.read(totalPurchaseAmountProvider.notifier).state = totalAmount;
  }

  void _updateGlobalTotalByCounter() {
    final selectedItemState = ref.watch(
      selectedItemProvider(SelectedItemType.purchase),
    );

    final selectedItems = selectedItemState.values.where((item) {
      return item.type == SelectedItemType.purchase;
    }).toList();

    final double totalAmount = _calculateTotalAmount(selectedItems);

    _updateGlobalTotal(totalAmount);
  }

  void _clear() {
    _nameController.clear();
    _phoneNumberController.clear();
    _addressController.clear();
    _discountController.clear();
    _taxController.clear();
    _noteController.clear();
    _payController.clear();
  }

  Future<void> updateStockItem() async {
    final selectedItemState = ref.read(
      selectedItemProvider(SelectedItemType.purchase),
    );

    final selectedItems = selectedItemState.values.where((item) {
      return item.type == SelectedItemType.purchase;
    }).toList();

    if (selectedItems.isEmpty) {
      CustomSnackbar.showWarning(context, "Tambah minimal 1 barang");
      return;
    }

    for (final item in selectedItems) {
      final controller = _controllerOf(item);

      if (double.tryParse(controller.text.trim()) == null) {
        CustomSnackbar.showError(context, "Nominal harga beli tidak valid");
        return;
      }

      final double purchasePrice = double.parse(controller.text.trim());

      if (purchasePrice <= 0) {
        CustomSnackbar.showError(context, "Harga beli harus lebih dari 0");
        return;
      }

      if (item.itemType == ItemType.product_variant &&
          purchasePrice >= item.sellingPrice) {
        CustomSnackbar.showError(
          context,
          "Harga jual harus lebih besar dari harga beli",
        );
        return;
      }
    }

    if (_paymentStatus != PaymentStatus.debt &&
        !_formKey.currentState!.validate())
      return;

    SupplierInformation? supplierInfo;

    final bool supplierInfoIsNotEmpty =
        _nameController.text.isNotEmpty ||
        _phoneNumberController.text.isNotEmpty ||
        _addressController.text.isNotEmpty;

    if (supplierInfoIsNotEmpty) {
      if (_nameController.text.isEmpty) {
        CustomSnackbar.showError(context, "Nama pemasok belum diisi");
        return;
      }

      final name = _nameController.text.trim();
      final phoneNumber = _phoneNumberController.text.trim();
      final address = _addressController.text.trim();

      supplierInfo = SupplierInformation(
        name: name,
        phoneNumber: phoneNumber,
        address: address,
      );
    }

    try {
      if (_discountController.text.isNotEmpty) {
        final double discount = double.parse(_discountController.text.trim());

        if (discount <= 0) {
          CustomSnackbar.showError(context, "Diskon harus lebih dari 0");
          return;
        }
      }
    } catch (e) {
      CustomSnackbar.showError(context, "Nominal diskon tidak valid");
      return;
    }

    try {
      if (_taxController.text.isNotEmpty) {
        final double tax = double.parse(_taxController.text.trim());

        if (tax <= 0) {
          CustomSnackbar.showError(context, "Pajak harus lebih dari 0");
          return;
        }
      }
    } catch (e) {
      CustomSnackbar.showError(context, "Nominal pajak tidak valid");
      return;
    }

    try {
      if (_payController.text.isNotEmpty && _validateChange) {
        final double payAmount = double.parse(_payController.text.trim());

        if (payAmount <= 0) {
          CustomSnackbar.showError(
            context,
            "Nominal pembayaran harus lebih dari 0",
          );
          return;
        }

        final double totalAmount = _calculateTotalAmount(selectedItems);

        if (_paymentStatus == PaymentStatus.paid && totalAmount > payAmount) {
          CustomSnackbar.showError(
            context,
            "Kurang ${CurrencyFormat.formatToIdr((totalAmount - payAmount), 0)}",
          );
          return;
        }

        if (_paymentStatus == PaymentStatus.partial &&
            payAmount >= totalAmount) {
          CustomSnackbar.showWarning(
            context,
            "Jumlah pembayaran telah melunasi pembelian, ubah status pembelian",
          );
          return;
        }
      }
    } catch (e) {
      CustomSnackbar.showError(context, "Nominal pembayaran tidak valid");
      return;
    }

    final selectedSupplierState = ref.read(selectedSupplierProvider);

    final String? supplierId = selectedSupplierState != null
        ? selectedSupplierState.id
        : supplierInfo != null
        ? supplierInfo.localId
        : null;

    final double changeAmount = _paymentStatus == PaymentStatus.paid
        ? _changeAmount
        : 0.0;

    final double underPaymentAmount = _paymentStatus == PaymentStatus.partial
        ? _changeAmount
        : 0.0;

    final double debtAmount = _paymentStatus == PaymentStatus.debt
        ? _calculateTotalAmount(selectedItems)
        : 0.0;

    final newPurchase = NewPurchase(
      supplierId: supplierId,
      totalPurchase: _calculateTotalPurchase(selectedItems),
      paymentStatus: _paymentStatus,
      totalAmount: _calculateTotalAmount(selectedItems),
      otherInformation: OtherInformation(
        discount: double.tryParse(_discountController.text.trim()) ?? 0.0,
        tax: double.tryParse(_taxController.text.trim()) ?? 0.0,
        note: _noteController.text.trim(),
      ),
      amountPaid: double.tryParse(_payController.text.trim()) ?? 0.0,
      changeAmount: changeAmount,
      underPaymentAmount: underPaymentAmount,
      debtAmount: debtAmount,
      paymentProofPath: _imagePath,
    );

    final List<ItemPurchase> itemPurchases = selectedItems.map((item) {
      final controller = _controllerOf(item);

      final double purchasePrice =
          double.tryParse(controller.text.trim()) ?? 0.0;

      return ItemPurchase(
        purchaseId: newPurchase.localId,
        itemType: item.itemType,
        itemId: item.itemId,
        quantity: item.quantity,
        imagePath: item.localImagePath,
        itemNameSnapshot: item.name,
        itemVariantNameSnapshot: item.variantName,
        purchasePriceSnaphot: purchasePrice,
        subtotal: item.quantity * purchasePrice,
      );
    }).toList();

    final items = selectedItems.map((item) {
      final controller = _controllerOf(item);

      final price = double.tryParse(controller.text.trim()) ?? 0.0;

      return UpdateStockItem(
        outletInventoryId: item.id,
        stockCardType: StockCardType.purchase,
        remainingStock: item.remainingStock,
        qtyChange: item.quantity,
        updateStock: item.remainingStock + item.quantity,
        currentStock: item.remainingStock + item.quantity,
        costPrice: item.itemType == ItemType.product_variant ? price : 0.0,
        purchasePrice: item.itemType == ItemType.raw_material ? price : 0.0,
        referenceId: newPurchase.localId,
      );
    }).toList();

    try {
      await ref
          .read(stockInControllerProvider.notifier)
          .updateStockItem(
            supplierInfo: supplierInfo,
            newPurchase: newPurchase,
            itemPurchases: itemPurchases,
            items: items,
          );

      if (!mounted) return;

      CustomSnackbar.showSuccess(context, "Stok barang berhasil diperbarui");

      ref.invalidate(selectedSupplierProvider);

      for (final path in _imagePathTemps) {
        if (path != null && _imagePath != null && path != _imagePath) {
          await ImageService.deleteLocalImage(path);
        }
      }

      setState(() {
        _selectedDate = DateTime.now();
        _imagePath = null;
        _imagePathTemps.clear();
      });

      ref.invalidate(selectedItemProvider);

      ref.invalidate(proofPaymentPurchaseTempProvider);

      _clear();

      final purchaseDetail = await ref
          .read(transactionReportRepositoryProvider)
          .getPurchaseDetail(newPurchase.localId);

      FocusScope.of(context).unfocus();

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

      context.pushNamed(
        AppRoute.transactionReportPurchaseDetailScreen,
        extra: purchaseDetail,
      );
    } catch (e, st) {
      LogMessage.log.e(e.toString(), error: e, stackTrace: st);
      CustomSnackbar.showError(context, "Ups, terjadi kesalahan");
    }
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);

    final selectedItemState = ref.watch(
      selectedItemProvider(SelectedItemType.purchase),
    );

    final selectedItems = selectedItemState.values.where((item) {
      return item.type == SelectedItemType.purchase;
    }).toList();

    final selectedSupplierState = ref.watch(selectedSupplierProvider);

    return Column(
      children: [
        Expanded(
          child: SingleChildScrollView(
            padding: EdgeInsets.all(5.w),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                HeaderStockInPurchaseSection(
                  selectedDate: _selectedDate,
                  isSupplierFormVisible: _isSupplierFormVisible,
                  selectedSupplier: selectedSupplierState,
                  nameController: _nameController,
                  phoneNumberController: _phoneNumberController,
                  addressController: _addressController,
                  onTap: () => _showPurchaseDatePicker(context),
                  onSupplierFormTap: () {
                    setState(() {
                      _isSupplierFormVisible = !_isSupplierFormVisible;
                    });
                  },
                  onTapCloseSelectedSupplier: selectedSupplierState == null
                      ? null
                      : () {
                          ref.read(selectedSupplierProvider.notifier).state =
                              null;
                        },
                ),

                SizedBox(height: 3.h),

                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Text(
                      "Barang Dibeli (${selectedItems.length})",
                      style: TextStyle(
                        fontSize: (AppFontSize.medium - 1.25).sp,
                        fontWeight: FontWeight.bold,
                        color: Colors.black87,
                      ),
                    ),
                    TextButton.icon(
                      onPressed: () => context.pushNamed(
                        AppRoute.selectGoodScreen,
                        extra: {
                          "type": SelectedItemType.purchase,
                          "on_pressed": () {
                            final itemState = ref.read(
                              selectedItemProvider(SelectedItemType.purchase),
                            );

                            final items = itemState.values.where((item) {
                              return item.type == SelectedItemType.purchase;
                            }).toList();

                            final double payAmount =
                                double.tryParse(_payController.text.trim()) ??
                                0.0;

                            final double totalAmount = _calculateTotalAmount(
                              items,
                            );

                            _updateGlobalTotal(totalAmount);

                            if (_payController.text.isNotEmpty) {
                              setState(() {
                                _validateChange = payAmount < totalAmount;
                                if (payAmount >= totalAmount &&
                                    items.isNotEmpty) {
                                  _changeAmount = payAmount - totalAmount;
                                }
                              });
                            }
                          },
                        },
                      ),
                      icon: Icon(
                        Icons.add_shopping_cart_rounded,
                        size: 5.w,
                        color: AppColor.primaryColor,
                      ),
                      label: Text(
                        "Tambah Barang",
                        style: TextStyle(
                          color: AppColor.primaryColor,
                          fontSize: (AppFontSize.medium - 1.25).sp,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ),
                  ],
                ),

                if (selectedItems.isEmpty)
                  const EmptyItem(
                    icon: Icons.hourglass_empty_outlined,
                    title: "Belum ada barang pembelian",
                    subtitle: "Tekan 'Tambah Barang' untuk memulai",
                  )
                else
                  ListView.separated(
                    shrinkWrap: true,
                    physics: const NeverScrollableScrollPhysics(),
                    itemCount: selectedItems.length,
                    separatorBuilder: (c, i) => SizedBox(height: 2.h),
                    itemBuilder: (context, index) {
                      final item = selectedItems[index];
                      return PurchaseItemCard(
                        item: item,
                        purchasePriceController: _controllerOf(item),
                        onChanged: _onPurchasePriceChange,
                        onDecrementTap: () {
                          ref
                              .read(
                                selectedItemProvider(
                                  SelectedItemType.purchase,
                                ).notifier,
                              )
                              .decrement(item.id);

                          _updateGlobalTotalByCounter();

                          if (_payController.text.trim().isNotEmpty) {
                            _calculateChange(_payController.text);
                          }
                        },
                        onIncrementTap: () {
                          ref
                              .read(
                                selectedItemProvider(
                                  SelectedItemType.purchase,
                                ).notifier,
                              )
                              .increment(item.id);

                          _updateGlobalTotalByCounter();

                          if (_payController.text.trim().isNotEmpty) {
                            _calculateChange(_payController.text);
                          }
                        },
                        onEditPressed: () {
                          showDialog(
                            context: context,
                            builder: (_) {
                              final ItemType itemType = item.itemType;

                              final String name = item.name;

                              final String? variantName = item.variantName;

                              final String remainingStock = item.remainingStock
                                  .toStringWithoutTrailingZero();

                              final String unit = item.unit;

                              final String initialQuantity = item.quantity
                                  .toStringWithoutTrailingZero();

                              return ItemQuantityAmount(
                                itemType: itemType,
                                variantName: variantName,
                                name: name,
                                remainingStock: remainingStock,
                                unit: unit,
                                initialQuantity: initialQuantity,
                                label: "Jumlah Diterima",
                                onPressed: (value) {
                                  try {
                                    final double quantity = double.parse(value);

                                    ref
                                        .read(
                                          selectedItemProvider(
                                            SelectedItemType.purchase,
                                          ).notifier,
                                        )
                                        .customQuantity(item.id, quantity);

                                    _updateGlobalTotalByCounter();

                                    if (_payController.text.trim().isNotEmpty) {
                                      _calculateChange(_payController.text);
                                    }
                                  } catch (e) {
                                    CustomSnackbar.showError(
                                      context,
                                      "Stok tidak valid",
                                    );
                                  }
                                },
                              );
                            },
                          );
                        },
                        onDeletePressed: () {
                          ref
                              .read(
                                selectedItemProvider(
                                  SelectedItemType.purchase,
                                ).notifier,
                              )
                              .delete(item.id);

                          _updateGlobalTotalByCounter();

                          if (_payController.text.trim().isNotEmpty) {
                            _calculateChange(_payController.text);
                          }
                        },
                      );
                    },
                  ),

                SizedBox(height: 3.h),

                FinancialSection(
                  formKey: _formKey,
                  totalPurchase: _calculateTotalPurchase(selectedItems),
                  isOtherFormVisible: _isOtherFormVisible,
                  items: selectedItems,
                  validateChange: _validateChange,
                  totalAmount: _calculateTotalAmount(selectedItems),
                  selectedPaymentStatus: _selectedPaymentStatus,
                  onOtherFormTap: () {
                    setState(() {
                      _isOtherFormVisible = !_isOtherFormVisible;
                    });
                  },
                  discountController: _discountController,
                  taxController: _taxController,
                  noteController: _noteController,
                  payController: _payController,
                  onCalculateChange: _onCalculateChanged,
                  changeAmount: _changeAmount,
                  discountOnChanged: _discountOnChanged,
                  taxOnChanged: _taxOnChanged,
                  onChanged: _onChangePaymentStatus,
                ),

                SizedBox(height: 2.h),

                if (_paymentStatus == PaymentStatus.paid ||
                    _paymentStatus == PaymentStatus.partial)
                  CustomProofImageUploader(
                    imagePath: _imagePath,
                    title: "Upload Foto Struk / Nota",
                    onTapImageAdd: _showPickerOptions,
                    onTapImageRemove: _removeImage,
                  ),
              ],
            ),
          ),
        ),
      ],
    );
  }
}
