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/router/app_route.dart';
import 'package:niogu_app/core/utils/currency_format.dart';
import 'package:niogu_app/core/utils/extension_format.dart';
import 'package:niogu_app/core/enums/stock_type.dart';
import 'package:niogu_app/core/widgets/custom_empty_screen.dart';
import 'package:niogu_app/core/widgets/custom_snackbar.dart';
import 'package:niogu_app/features/goods/presentation/widgets/custom_item_detail.dart';
import 'package:niogu_app/features/goods/raw_materials/presentation/widgets/checkbox_product_card.dart';
import 'package:niogu_app/features/online_store/domain/entities/online_store.dart';
import 'package:niogu_app/features/online_store/presentation/providers/online_store_provider.dart';
import 'package:niogu_app/features/online_store/presentation/widgets/online_store_product_shimmer.dart';
import 'package:sizer/sizer.dart';

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

  @override
  ConsumerState<OnlineStoreProductScreen> createState() =>
      _OnlineStoreProductScreenState();
}

class _OnlineStoreProductScreenState
    extends ConsumerState<OnlineStoreProductScreen> {
  final FocusNode _searchFocusNode = FocusNode();

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

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

  Color _searchIconColor = Colors.grey;

  Timer? _debounce;

  Map<String, String> _initialOnlineStoreProducts = {};

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

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

    WidgetsBinding.instance.addPostFrameCallback((_) {
      _initialOnlineStoreProducts = ref.read(
        selectedOnlineStoreProductProvider,
      );
    });
  }

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

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

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

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

  void _saveOnlineStoreProduct() {
    final selectedOnlineStoreProduct = ref.read(
      selectedOnlineStoreProductProvider,
    );

    if (selectedOnlineStoreProduct.values.isEmpty) {
      CustomSnackbar.showWarning(context, "Pilih minimal satu produk");

      return;
    }

    CustomSnackbar.showSuccess(
      context,
      "${selectedOnlineStoreProduct.values.length} "
      "produk 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 filteredOnlineStoreProductState = ref.watch(
          filteredOnlineStoreProductProvider,
        );

        final onlineStoreProductEmptyState = ref.watch(
          onlineStoreProductEmptyProvider,
        );

        return SafeArea(
          top: false,
          bottom: true,
          right: false,
          left: false,
          child: Scaffold(
                backgroundColor: backgroundColor,
                appBar: TopBackBarApp(
                  title: "Produk Toko Online",
                  onTap: () {
                    context.pop();

                    WidgetsBinding.instance.addPostFrameCallback((_) {
                      ref
                              .read(selectedOnlineStoreProductProvider.notifier)
                              .state =
                          _initialOnlineStoreProducts;
                    });
                  },
                ),
                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: filteredOnlineStoreProductState.when(
                          data: (products) {
                            switch (onlineStoreProductEmptyState) {
                              case OnlineStoreProductEmpty.loading:
                                return const SizedBox();
                              case OnlineStoreProductEmpty.empty_database:
                                return CustomEmptyScreen(
                                  title: "Tidak Ada Produk",
                                  body: "Kamu belum memiliki produk",
                                  textButton: "Buat Produk Pertamamu",
                                  onPressed: () => context.pushNamed(
                                    AppRoute.addProductScreen,
                                  ),
                                );
                              case OnlineStoreProductEmpty.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 OnlineStoreProductEmpty.has_data:
                                return ListView.builder(
                                  padding: EdgeInsets.fromLTRB(
                                    5.w,
                                    0,
                                    5.w,
                                    12.h,
                                  ),
                                  itemCount: products.length,
                                  itemBuilder: (context, index) {
                                    final product = products[index];

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

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

                                    final bool isTablet = 100.w >= 600;

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

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

                                    final bool imageFileExists = imageFile
                                        .existsSync();

                                    final selectedOnlineStoreProduct = ref
                                        .watch(
                                          selectedOnlineStoreProductProvider,
                                        );

                                    final isExpanded = ref.watch(
                                      expandedOnlineStoreProductProvider(
                                        product.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: [
                                          InkWell(
                                            onTap: () {
                                              if (product.hasVariant) {
                                                ref
                                                    .read(
                                                      expandedOnlineStoreProductProvider(
                                                        product.id,
                                                      ).notifier,
                                                    )
                                                    .state = !ref.read(
                                                  expandedOnlineStoreProductProvider(
                                                    product.id,
                                                  ),
                                                );
                                              } else {
                                                final productId =
                                                    activeProduct.single.id;

                                                final selectedProductState = ref
                                                    .read(
                                                      selectedOnlineStoreProductProvider,
                                                    );

                                                final selectedProductNotifier =
                                                    ref.read(
                                                      selectedOnlineStoreProductProvider
                                                          .notifier,
                                                    );

                                                if (selectedProductState
                                                    .containsKey(productId)) {
                                                  selectedProductNotifier
                                                      .state = {
                                                    ...selectedProductState,
                                                  }..remove(productId);
                                                } else {
                                                  selectedProductNotifier
                                                      .state = {
                                                    ...selectedProductState,
                                                    productId: productId,
                                                  };
                                                }
                                              }
                                            },
                                            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(
                                                          product.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 (product
                                                              .hasVariant)
                                                            Text(
                                                              "${activeProduct.length} Varian",
                                                              style: TextStyle(
                                                                fontSize:
                                                                    isTablet
                                                                    ? AppFontSize
                                                                          .medium
                                                                          .sp
                                                                    : AppFontSize
                                                                          .small
                                                                          .sp,
                                                                color:
                                                                    Colors.grey,
                                                              ),
                                                            )
                                                          else ...[
                                                            CustomItemDetail(
                                                              label:
                                                                  product.stockType ==
                                                                      StockType
                                                                          .unlimited
                                                                  ? "Stok Selalu Ada"
                                                                  : "Sisa Stok",
                                                              value:
                                                                  product.stockType ==
                                                                      StockType
                                                                          .unlimited
                                                                  ? ""
                                                                  : ": ${product.remainingStock.toStringWithoutTrailingZero()} ${product.unit}",
                                                              width:
                                                                  product.stockType ==
                                                                      StockType
                                                                          .unlimited
                                                                  ? 24
                                                                  : 22,
                                                            ),

                                                            CustomItemDetail(
                                                              label:
                                                                  "Harga Jual",
                                                              value:
                                                                  ": ${CurrencyFormat.formatToIdr(product.sellingPrice, 0)}",
                                                              width: 22,
                                                            ),
                                                          ],
                                                        ],
                                                      ],
                                                    ),
                                                  ),
                                                  if (activeProduct
                                                      .isNotEmpty) ...[
                                                    if (product.hasVariant)
                                                      Icon(
                                                        isExpanded
                                                            ? Icons
                                                                  .keyboard_arrow_up_rounded
                                                            : Icons
                                                                  .keyboard_arrow_down_rounded,
                                                        color: Colors.grey,
                                                        size: 7.w,
                                                      )
                                                    else
                                                      CheckboxProductCard(
                                                        isSelected:
                                                            selectedOnlineStoreProduct
                                                                .containsKey(
                                                                  activeProduct
                                                                      .single
                                                                      .id,
                                                                ),
                                                      ),
                                                  ],
                                                ],
                                              ),
                                            ),
                                          ),

                                          if (activeProduct.isNotEmpty &&
                                              product.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: () {
                                                      final selectedProductState =
                                                          ref.read(
                                                            selectedOnlineStoreProductProvider,
                                                          );

                                                      final selectedProductNotifier =
                                                          ref.read(
                                                            selectedOnlineStoreProductProvider
                                                                .notifier,
                                                          );

                                                      if (selectedProductState
                                                          .containsKey(
                                                            variant.id,
                                                          )) {
                                                        selectedProductNotifier
                                                            .state = {
                                                          ...selectedProductState,
                                                        }..remove(variant.id);
                                                      } else {
                                                        selectedProductNotifier
                                                            .state = {
                                                          ...selectedProductState,
                                                          variant.id:
                                                              variant.id,
                                                        };
                                                      }
                                                    },
                                                    child: Padding(
                                                      padding:
                                                          EdgeInsets.symmetric(
                                                            horizontal: 4.w,
                                                            vertical: 1.5.h,
                                                          ),
                                                      child: Column(
                                                        crossAxisAlignment:
                                                            CrossAxisAlignment
                                                                .start,
                                                        children: [
                                                          Row(
                                                            crossAxisAlignment:
                                                                CrossAxisAlignment
                                                                    .start,
                                                            children: [
                                                              SizedBox(
                                                                width: 4.w,
                                                              ),
                                                              CheckboxProductCard(
                                                                isSelected:
                                                                    selectedOnlineStoreProduct
                                                                        .containsKey(
                                                                          variant
                                                                              .id,
                                                                        ),
                                                              ),

                                                              SizedBox(
                                                                width: 3.w,
                                                              ),

                                                              Expanded(
                                                                child: Column(
                                                                  mainAxisAlignment:
                                                                      MainAxisAlignment
                                                                          .start,
                                                                  crossAxisAlignment:
                                                                      CrossAxisAlignment
                                                                          .start,
                                                                  children: [
                                                                    Text(
                                                                      variant
                                                                          .name,
                                                                      style: TextStyle(
                                                                        fontWeight:
                                                                            FontWeight.w700,
                                                                        fontSize:
                                                                            isTablet
                                                                            ? AppFontSize.medium.sp
                                                                            : AppFontSize.small.sp,
                                                                        color: Colors
                                                                            .black,
                                                                      ),
                                                                    ),

                                                                    SizedBox(
                                                                      height:
                                                                          0.5.h,
                                                                    ),

                                                                    CustomItemDetail(
                                                                      label:
                                                                          variant.stockType ==
                                                                              StockType.unlimited
                                                                          ? "Stok Selalu Ada"
                                                                          : "Sisa Stok",
                                                                      value:
                                                                          variant.stockType ==
                                                                              StockType.unlimited
                                                                          ? ""
                                                                          : ": ${variant.remainingStock.toStringWithoutTrailingZero()} ${variant.unit}",
                                                                      width:
                                                                          variant.stockType ==
                                                                              StockType.unlimited
                                                                          ? 24
                                                                          : 22,
                                                                    ),

                                                                    CustomItemDetail(
                                                                      label:
                                                                          "Harga Jual",
                                                                      value:
                                                                          ": ${CurrencyFormat.formatToIdr(variant.sellingPrice, 0)}",
                                                                      width: 22,
                                                                    ),
                                                                  ],
                                                                ),
                                                              ),
                                                            ],
                                                          ),
                                                        ],
                                                      ),
                                                    ),
                                                  );
                                                }).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(),
                                              ),
                                            ),
                                          ],
                                        ],
                                      ),
                                    );
                                  },
                                );
                            }
                          },
                          error: (error, stackTrace) {
                            return CustomErrorScreen(
                              message: "Ups, terjadi kesalahan",
                              onRefresh: () {},
                            );
                          },
                          loading: () => const OnlineStoreProductShimmer(),
                        ),
                      ),
                    ),
                  ],
                ),
                bottomNavigationBar: filteredOnlineStoreProductState.maybeWhen(
                  data: (_) {
                    switch (onlineStoreProductEmptyState) {
                      case OnlineStoreProductEmpty.loading:
                        return const SizedBox();
                      case OnlineStoreProductEmpty.empty_database:
                        return const SizedBox();
                      case OnlineStoreProductEmpty.empty_search_result:
                        return _buildSaveButton();
                      case OnlineStoreProductEmpty.has_data:
                        return _buildSaveButton();
                    }
                  },
                  orElse: () => const SizedBox(),
                ),
              ),
              
        );
      },
    );
  }

  Widget _buildSaveButton() {
    final onlineStoreControllerState = ref.watch(onlineStoreControllerProvider);
    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: onlineStoreControllerState.isLoading
              ? null
              : _saveOnlineStoreProduct,
          style: ElevatedButton.styleFrom(
            backgroundColor: onlineStoreControllerState.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,
            ),
          ),
        ),
      ),
    );
  }
}
