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

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.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/widgets/custom_error_screen.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/enums/user_role.dart';
import 'package:niogu_app/core/widgets/custom_empty_screen.dart';
import 'package:niogu_app/core/widgets/custom_snackbar.dart';
import 'package:niogu_app/core/widgets/pop_up_notification.dart';
import 'package:niogu_app/features/goods/raw_materials/domain/entities/raw_material.dart';
import 'package:niogu_app/features/goods/raw_materials/presentation/providers/raw_material_provider.dart';
import 'package:niogu_app/features/goods/raw_materials/presentation/widgets/product_usage_raw_material_shimmer.dart';
import 'package:niogu_app/features/goods/raw_materials/presentation/widgets/checkbox_product_card.dart';
import 'package:niogu_app/features/goods/raw_materials/presentation/widgets/quantity_usage.dart';
import 'package:sizer/sizer.dart';

class ProductUsageRawMaterialScreen extends ConsumerStatefulWidget {
  final String? rawMaterialId;
  final String unitName;
  final bool isMainOutlet;
  final bool isEditing;
  const ProductUsageRawMaterialScreen({
    super.key,
    this.rawMaterialId,
    required this.unitName,
    this.isMainOutlet = false,
    this.isEditing = true,
  });

  @override
  ConsumerState<ProductUsageRawMaterialScreen> createState() =>
      _ProductUsageRawMaterialScreenState();
}

class _ProductUsageRawMaterialScreenState
    extends ConsumerState<ProductUsageRawMaterialScreen> {
  late final String? _rawMaterialId;

  late final String _unitName;

  late final bool _isMainOutlet;

  late final bool _isEditing;

  final FocusNode _searchFocusNode = FocusNode();

  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  final Map<String, TextEditingController> _controllers = {};

  Color _searchIconColor = Colors.grey;

  Timer? _debounce;

  Map<String, SelectedProductUsageMaterial> _initialProductUsages = {};

  final List<DeleteProductUsageMaterial> _deleteProductUsageMaterials = [];

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

    _rawMaterialId = widget.rawMaterialId;

    _unitName = widget.unitName;

    _isMainOutlet = widget.isMainOutlet;

    _isEditing = widget.isEditing;

    _searchFocusNode.addListener(() {
      setState(() {
        _searchIconColor = _searchFocusNode.hasFocus
            ? Colors.black
            : Colors.grey;
      });
    });

    WidgetsBinding.instance.addPostFrameCallback((_) {
      _initialProductUsages = ref.read(selectedProductUsageMaterialProvider);
    });
  }

  @override
  void dispose() {
    // TODO: implement dispose
    _searchFocusNode.dispose();

    for (final controller in _controllers.values) {
      controller.dispose();
    }

    _debounce?.cancel();
    super.dispose();
  }

  TextEditingController _controllerOf(String productUsageId) {
    return _controllers.putIfAbsent(productUsageId, () {
      final quantity = ref
          .read(selectedProductUsageMaterialProvider.notifier)
          .quantityOf(productUsageId);

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

  void _onSearchChanged(String value) {
    if (_debounce?.isActive ?? false) _debounce?.cancel();
    _debounce = Timer(const Duration(milliseconds: 800), () async {
      ref.read(productUsageMaterialSearchProvider.notifier).state = value;
    });
  }

  void _deleteProductUsageMaterial(String productUsageId) {
    final bool isSelected = ref
        .read(selectedProductUsageMaterialProvider)
        .containsKey(productUsageId);

    if (isSelected && _rawMaterialId != null) {
      _deleteProductUsageMaterials.removeWhere((product) {
        return product.productUsageId == productUsageId;
      });
    } else if (!isSelected && _rawMaterialId != null) {
      _deleteProductUsageMaterials.add(
        DeleteProductUsageMaterial(
          rawMaterialId: _rawMaterialId,
          productUsageId: productUsageId,
        ),
      );
    }
  }

  void _commitAllQuantity() {
    _controllers.forEach((key, value) {
      final String val = _controllers[key]?.text ?? '';
      final double quantity = double.tryParse(val) ?? 0.0;
      ref
          .read(selectedProductUsageMaterialProvider.notifier)
          .setQuantity(key, quantity);
    });
  }

  String? _validator({
    required String? value,
    required String message,
    required String errorMessage,
  }) {
    try {
      if (value != null && value.isNotEmpty) {
        final double val = double.parse(value);

        if (val <= 0) {
          return message;
        }
      }
    } catch (e) {
      return errorMessage;
    }

    return null;
  }

  void _saveProductUsage() {
    final selectProductUsageMaterial = ref.read(
      selectedProductUsageMaterialProvider,
    );

    if (selectProductUsageMaterial.values.isEmpty) {
      CustomSnackbar.showWarning(
        context,
        "Pilih minimal satu produk yang menggunakan bahan baku ini",
      );
      return;
    }

    if (!_formKey.currentState!.validate()) return;

    if (_deleteProductUsageMaterials.isNotEmpty) {
      ref.read(deleteProductUsageMaterialProvider.notifier).state =
          _deleteProductUsageMaterials;
    }

    _commitAllQuantity();

    CustomSnackbar.showSuccess(
      context,
      "${selectProductUsageMaterial.values.length} "
      "penggunaan bahan baku berhasil dibuat",
    );

    context.pop();
  }

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

        const backgroundColor = Color(0xFFF9FAFB);

        final messageActivity = ref.watch(messageActivityProvider);

        final currentUserRole = ref.watch(currentUserRoleProvider);

        final productUsageMaterialState = ref.watch(
          filteredProductUsageMaterialProvider(_isEditing),
        );

        final productUsageMaterialEmptyState = ref.watch(
          productUsageMaterialEmptyProvider(_isEditing),
        );

        final selectedProduct = ref.watch(selectedProductUsageMaterialProvider);

        return SafeArea(
          top: false,
          bottom: true,
          right: false,
          left: false,
          child: Stack(
            children: [
              Scaffold(
                backgroundColor: backgroundColor,
                appBar: TopBackBarApp(
                  title: "Penggunaan Bahan Baku",
                  onTap: () {
                    context.pop();

                    WidgetsBinding.instance.addPostFrameCallback((_) {
                      ref
                          .read(selectedProductUsageMaterialProvider.notifier)
                          .restore(_initialProductUsages);
                    });
                  },
                ),
                body: Column(
                  children: [
                    Container(
                      height: 12.h,
                      padding: EdgeInsets.fromLTRB(5.w, 3.h, 5.w, 2.h),
                      color: backgroundColor,
                      child: Container(
                        decoration: BoxDecoration(
                          color: Colors.white,
                          borderRadius: BorderRadius.circular(2.5.w),
                          boxShadow: [
                            BoxShadow(
                              color: Colors.black.withOpacity(0.03),
                              blurRadius: 10,
                              offset: const Offset(0, 4),
                            ),
                          ],
                        ),
                        child: TextField(
                          focusNode: _searchFocusNode,
                          onChanged: (value) => _onSearchChanged(value),
                          style: TextStyle(
                            color: Colors.black87,
                            fontSize: isTablet
                                ? AppFontSize.medium.sp
                                : AppFontSize.small.sp,
                          ),
                          decoration: InputDecoration(
                            hintText: "Cari produk...",
                            hintStyle: TextStyle(
                              color: _searchIconColor,
                              fontSize: isTablet
                                  ? AppFontSize.medium.sp
                                  : AppFontSize.small.sp,
                            ),
                            prefixIcon: Icon(
                              Icons.search,
                              color: Colors.grey,
                              size: 5.w,
                            ),
                            border: InputBorder.none,
                            contentPadding: EdgeInsets.symmetric(
                              horizontal: 4.w,
                              vertical: 1.5.h,
                            ),
                          ),
                        ),
                      ),
                    ),
                    Expanded(
                      child: Form(
                        key: _formKey,
                        child: productUsageMaterialState.when(
                          data: (productUsageMaterials) {
                            switch (productUsageMaterialEmptyState) {
                              case ProductUsageRawMaterialEmpty.loading:
                                return const SizedBox();
                              case ProductUsageRawMaterialEmpty.empty_database:
                                return CustomEmptyScreen(
                                  title: "Tidak Ada Produk",
                                  body: "Kamu belum memiliki produk",
                                  textButton: "Buat Produk Pertamamu",
                                  onPressed: () => context.pushNamed(
                                    AppRoute.addProductScreen,
                                  ),
                                );
                              case ProductUsageRawMaterialEmpty
                                  .empty_search_result:
                                return SingleChildScrollView(
                                  physics:
                                      const AlwaysScrollableScrollPhysics(),
                                  padding: EdgeInsets.symmetric(vertical: 3.h),
                                  child: Center(
                                    child: Column(
                                      mainAxisAlignment:
                                          MainAxisAlignment.center,
                                      children: [
                                        Text(
                                          "Produk Tidak Ditemukan",
                                          style: TextStyle(
                                            fontSize: AppFontSize.large.sp,
                                            fontWeight: FontWeight.bold,
                                            color: Colors.black,
                                          ),
                                        ),

                                        SizedBox(height: 1.5.h),

                                        Icon(
                                          Icons.search_off_rounded,
                                          size: 15.h,
                                          color: Colors.grey.shade300,
                                        ),
                                      ],
                                    ),
                                  ),
                                );

                              case ProductUsageRawMaterialEmpty.has_data:
                                return ListView.builder(
                                  padding: EdgeInsets.fromLTRB(
                                    5.w,
                                    0,
                                    5.w,
                                    12.h,
                                  ),
                                  itemCount: productUsageMaterials.length,
                                  itemBuilder: (context, index) {
                                    var productUsageMaterial =
                                        productUsageMaterials[index];

                                    final activeProduct = productUsageMaterial
                                        .variants
                                        .where((variant) {
                                          return !variant.hasBeenDelete;
                                        })
                                        .toList();

                                    final historyProduct = productUsageMaterial
                                        .variants
                                        .where((variant) {
                                          return variant.hasBeenDelete;
                                        })
                                        .toList();

                                    final bool isTablet = 100.w >= 600;

                                    final bool imagePathAvailable =
                                        productUsageMaterial.imagePath !=
                                            null &&
                                        productUsageMaterial
                                            .imagePath!
                                            .isNotEmpty;

                                    final File imageFile = File(
                                      imagePathAvailable
                                          ? productUsageMaterial.imagePath!
                                          : 'image not found',
                                    );

                                    final bool imageFileExists = imageFile
                                        .existsSync();

                                    final isExpanded = ref.watch(
                                      expandedProductProvider(
                                        productUsageMaterial.id,
                                      ),
                                    );

                                    return AnimatedContainer(
                                      duration: const Duration(
                                        milliseconds: 200,
                                      ),
                                      margin: EdgeInsets.only(bottom: 2.h),
                                      decoration: BoxDecoration(
                                        color: Colors.white,
                                        borderRadius: BorderRadius.circular(
                                          4.w,
                                        ),
                                        border: Border.all(
                                          color: Colors.grey.shade200,
                                          width: 1,
                                        ),
                                        boxShadow: [
                                          BoxShadow(
                                            color: Colors.black.withOpacity(
                                              0.03,
                                            ),
                                            blurRadius: 8,
                                            offset: const Offset(0, 4),
                                          ),
                                        ],
                                      ),
                                      child: Column(
                                        children: _buildItems(
                                          isTablet: isTablet,
                                          userRole: currentUserRole!,
                                          selectedProduct: selectedProduct,
                                          productUsageMaterial:
                                              productUsageMaterial,
                                          activeProduct: activeProduct,
                                          historyProduct: historyProduct,
                                          imageFileExists: imageFileExists,
                                          imageFile: imageFile,
                                          isExpanded: isExpanded,
                                        ),
                                      ),
                                    );
                                  },
                                );
                            }
                          },
                          error: (error, stackTrace) {
                            return CustomErrorScreen(
                              message: "Ups, terjadi kesalahan",
                              onRefresh: () {},
                            );
                          },
                          loading: () => const ProductUsageRawMaterialShimmer(),
                        ),
                      ),
                    ),
                  ],
                ),

                bottomNavigationBar: !_isEditing
                    ? null
                    : productUsageMaterialState.maybeWhen(
                        data: (_) {
                          switch (productUsageMaterialEmptyState) {
                            case ProductUsageRawMaterialEmpty.loading:
                              return const SizedBox();
                            case ProductUsageRawMaterialEmpty.empty_database:
                              return const SizedBox();
                            case ProductUsageRawMaterialEmpty
                                .empty_search_result:
                              return _buildSaveButton();
                            case ProductUsageRawMaterialEmpty.has_data:
                              return _buildSaveButton();
                          }
                        },
                        orElse: () => const SizedBox(),
                      ),
              ),

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

  List<Widget> _buildItems({
    required bool isTablet,
    required UserRole userRole,
    required Map<String, SelectedProductUsageMaterial> selectedProduct,
    required ProductUsageMaterial productUsageMaterial,
    required List<VariantUsageMaterial> activeProduct,
    required List<VariantUsageMaterial> historyProduct,
    required bool imageFileExists,
    required File imageFile,
    required bool isExpanded,
  }) {
    final readOnly =
        (userRole == UserRole.owner && !_isMainOutlet) ||
        userRole == UserRole.admin;
    return [
      InkWell(
        onTap: () {
          if (productUsageMaterial.hasVariant) {
            ref
                .read(expandedProductProvider(productUsageMaterial.id).notifier)
                .state = !ref.read(
              expandedProductProvider(productUsageMaterial.id),
            );
          } else if (_isEditing) {
            final productUsageId = activeProduct.single.id;

            final receiptItemIdState = ref.read(receiptItemIdProvider);

            final receiptItemId = receiptItemIdState[productUsageId];

            ref
                .read(selectedProductUsageMaterialProvider.notifier)
                .toggle(productUsageId, receiptItemId);

            _deleteProductUsageMaterial(productUsageId);
          }
        },
        borderRadius: BorderRadius.vertical(
          top: Radius.circular(4.w),
          bottom: isExpanded || historyProduct.isNotEmpty
              ? Radius.zero
              : Radius.circular(4.w),
        ),
        child: Padding(
          padding: EdgeInsets.all(3.w),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Container(
                width: 20.w,
                height: 20.w,
                decoration: BoxDecoration(
                  color: Colors.grey[100],
                  borderRadius: BorderRadius.circular(2.5.w),
                  border: Border.all(color: Colors.grey.shade300),
                ),
                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,
                              size: 7.w,
                            );
                          },
                        ),
                      )
                    : Icon(
                        Icons.image,
                        color: Colors.grey[400],
                        size: 7.w,
                      ), // Placeholder
              ),
              SizedBox(width: 4.w),

              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      productUsageMaterial.name,
                      overflow: TextOverflow.ellipsis,
                      style: TextStyle(
                        fontSize: isTablet
                            ? AppFontSize.medium.sp
                            : AppFontSize.small.sp,
                        fontWeight: FontWeight.bold,
                        color: activeProduct.isEmpty
                            ? Colors.grey
                            : Colors.black87,
                        decoration: activeProduct.isEmpty
                            ? TextDecoration.lineThrough
                            : null,
                      ),
                    ),

                    if (activeProduct.isNotEmpty) ...[
                      SizedBox(height: 1.h),

                      if (productUsageMaterial.hasVariant)
                        Text(
                          "${activeProduct.length} Varian",
                          style: TextStyle(
                            fontSize: isTablet
                                ? AppFontSize.medium.sp
                                : AppFontSize.small.sp,
                            color: Colors.grey,
                          ),
                        )
                      else ...[
                        if (selectedProduct.containsKey(
                          activeProduct.single.id,
                        ))
                          QuantityUsage(
                            hasVariant: productUsageMaterial.hasVariant,
                            unitName: _unitName,
                            controller: _controllerOf(activeProduct.single.id),
                            validator: (value) => _validator(
                              value: value,
                              message: "Jumlah penggunaan harus lebih dari 0",
                              errorMessage: "Jumlah penggunaan tidak valid",
                            ),
                            readOnly: readOnly,
                          ),
                      ],
                    ],
                  ],
                ),
              ),
              if (activeProduct.isNotEmpty) ...[
                if (productUsageMaterial.hasVariant)
                  Icon(
                    isExpanded
                        ? Icons.keyboard_arrow_up_rounded
                        : Icons.keyboard_arrow_down_rounded,
                    color: Colors.grey,
                    size: 7.w,
                  )
                else
                  CheckboxProductCard(
                    isSelected: selectedProduct.containsKey(
                      activeProduct.single.id,
                    ),
                  ),
              ],
            ],
          ),
        ),
      ),

      if (activeProduct.isNotEmpty &&
          productUsageMaterial.hasVariant &&
          isExpanded) ...[
        Container(height: 1, color: Colors.grey[100]),

        Padding(
          padding: EdgeInsets.symmetric(vertical: 1.h),
          child: Column(
            children: activeProduct.map((variant) {
              return InkWell(
                onTap: !_isEditing
                    ? null
                    : () {
                        final receiptItemIdState = ref.read(
                          receiptItemIdProvider,
                        );

                        final receiptItemId = receiptItemIdState[variant.id];
                        ref
                            .read(selectedProductUsageMaterialProvider.notifier)
                            .toggle(variant.id, receiptItemId);

                        _deleteProductUsageMaterial(variant.id);
                      },
                child: Padding(
                  padding: EdgeInsets.symmetric(
                    horizontal: 4.w,
                    vertical: 1.5.h,
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Row(
                        children: [
                          SizedBox(width: 4.w),
                          CheckboxProductCard(
                            isSelected: selectedProduct.containsKey(variant.id),
                          ),

                          SizedBox(width: 3.w),

                          Expanded(
                            child: Text(
                              variant.name,
                              style: TextStyle(
                                fontSize: isTablet
                                    ? AppFontSize.medium.sp
                                    : AppFontSize.small.sp,
                                color: Colors.black,
                              ),
                            ),
                          ),
                        ],
                      ),

                      if (selectedProduct.containsKey(variant.id))
                        Padding(
                          padding: EdgeInsets.only(left: 14.w),
                          child: QuantityUsage(
                            hasVariant: productUsageMaterial.hasVariant,
                            unitName: widget.unitName,
                            controller: _controllerOf(variant.id),
                            validator: (value) => _validator(
                              value: value,
                              message: "Jumlah penggunaan harus lebih dari 0",
                              errorMessage: "Jumlah penggunaan tidak valid",
                            ),
                            readOnly: readOnly,
                          ),
                        ),
                    ],
                  ),
                ),
              );
            }).toList(),
          ),
        ),
      ],

      if (historyProduct.isNotEmpty) ...[
        Divider(height: 1, color: Colors.grey.shade200),

        Theme(
          data: Theme.of(context).copyWith(dividerColor: Colors.transparent),
          child: ExpansionTile(
            tilePadding: EdgeInsets.symmetric(horizontal: 4.w),
            visualDensity: VisualDensity.compact,
            title: Row(
              children: [
                Icon(Icons.history, size: 4.5.w, color: Colors.grey[400]),
                SizedBox(width: 2.w),
                Text(
                  "Lihat riwayat / item terhapus",
                  style: TextStyle(
                    fontSize: isTablet
                        ? AppFontSize.medium.sp
                        : AppFontSize.small.sp,
                    color: Colors.grey[500],
                    fontWeight: FontWeight.w500,
                  ),
                ),
                SizedBox(width: 2.w),
                Container(
                  padding: EdgeInsets.symmetric(
                    horizontal: 1.5.w,
                    vertical: 0.5.w,
                  ),
                  decoration: BoxDecoration(
                    color: Colors.grey[200],
                    borderRadius: BorderRadius.circular(1.w),
                  ),
                  child: Text(
                    "${historyProduct.length}",
                    style: TextStyle(
                      fontSize: isTablet
                          ? AppFontSize.medium.sp
                          : AppFontSize.small.sp,
                      color: Colors.grey[600],
                    ),
                  ),
                ),
              ],
            ),
            children: historyProduct.map((variant) {
              return Container(
                color: Colors.grey[50],
                padding: EdgeInsets.symmetric(horizontal: 4.w, vertical: 1.5.h),
                child: Row(
                  children: [
                    Icon(Icons.block, color: Colors.grey[400], size: 5.w),
                    SizedBox(width: 3.w),
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            variant.name,
                            style: TextStyle(
                              fontSize: isTablet
                                  ? AppFontSize.medium.sp
                                  : AppFontSize.small.sp,
                              color: Colors.grey[500],
                              decoration: TextDecoration.lineThrough, // Coret
                            ),
                          ),

                          Text(
                            variant.isProductVariant
                                ? "Varian Dihapus"
                                : "Tipe Produk Sebelumnya (Tanpa varian)",
                            style: TextStyle(
                              fontSize: isTablet
                                  ? (AppFontSize.medium - 2).sp
                                  : (AppFontSize.small - 2).sp,
                              color: Colors.red[300],
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              );
            }).toList(),
          ),
        ),
      ],
    ];
  }

  Widget _buildSaveButton() {
    final rawMaterialControllerState = ref.watch(rawMaterialControllerProvider);
    return 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: SizedBox(
        height: 6.5.h,
        child: ElevatedButton(
          onPressed: rawMaterialControllerState.isLoading
              ? null
              : _saveProductUsage,
          style: ElevatedButton.styleFrom(
            backgroundColor: rawMaterialControllerState.isLoading
                ? Colors.grey
                : AppColor.primaryColor,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(2.5.w),
            ),
            elevation: 0,
          ),
          child: Text(
            "Simpan",
            style: TextStyle(
              color: Colors.white,
              fontSize: AppFontSize.medium.sp,
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
      ),
    );
  }
}
