import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:image_picker/image_picker.dart';
import 'package:niogu_app/core/components/top_back_bar_app.dart';
import 'package:niogu_app/core/constants/app_color.dart';
import 'package:niogu_app/core/constants/app_font_size.dart';
import 'package:niogu_app/core/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/stock_card_type.dart';
import 'package:niogu_app/core/enums/stock_type.dart';
import 'package:niogu_app/core/system/system_setting.dart';
import 'package:niogu_app/core/widgets/custom_selector.dart';
import 'package:niogu_app/core/widgets/custom_snackbar.dart';
import 'package:niogu_app/core/widgets/custom_text_form_field.dart';
import 'package:niogu_app/features/goods/domain/entities/stock_card.dart';
import 'package:niogu_app/features/goods/products/domain/entities/category.dart';
import 'package:niogu_app/features/goods/products/domain/entities/product.dart';
import 'package:niogu_app/features/goods/products/presentation/providers/category_provider.dart';
import 'package:niogu_app/features/goods/products/presentation/providers/product_provider.dart';
import 'package:niogu_app/features/goods/products/presentation/screens/add_product_category_screen.dart';
import 'package:niogu_app/features/goods/products/presentation/screens/edit_product_category_screen.dart';
import 'package:niogu_app/features/goods/products/presentation/widgets/add_photo_button.dart';
import 'package:niogu_app/features/goods/presentation/widgets/dropdown_with_action.dart';
import 'package:niogu_app/features/goods/products/presentation/widgets/image_preview_card.dart';
import 'package:niogu_app/features/goods/products/presentation/widgets/selection_card.dart';
import 'package:niogu_app/features/goods/units/domain/entities/unit.dart';
import 'package:niogu_app/features/goods/units/presentation/providers/unit_provider.dart';
import 'package:niogu_app/features/goods/units/presentation/screens/add_unit_screen.dart';
import 'package:niogu_app/features/goods/units/presentation/screens/edit_unit_screen.dart';
import 'package:niogu_app/features/goods/domain/entities/outlet_inventory.dart';
import 'package:niogu_app/features/outlets/presentation/providers/outlet_provider.dart';
import 'package:sizer/sizer.dart';

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

  @override
  ConsumerState<AddProductScreen> createState() => _AddProductScreenState();
}

class _AddProductScreenState extends ConsumerState<AddProductScreen> {
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  final TextEditingController _nameController = TextEditingController();
  final TextEditingController _costPriceController = TextEditingController();
  final TextEditingController _sellingPriceController = TextEditingController();
  final TextEditingController _stockController = TextEditingController();

  final ImagePicker _picker = ImagePicker();

  List<String> _productImages = [];

  bool _hasVariant = false;

  bool _isStockAlwaysAvailable = false;

  String? _selectedCategory;

  String? _selectedUnit;

  final List<String> _pathImageRemoves = [];

  final List<String?> _pathImageTemps = [];

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

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

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

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

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

        if (isSellingPrice) return message2;

        if (isStock && !_isStockAlwaysAvailable) return message2;
      }
    } catch (e) {
      return errorMessage;
    }

    return null;
  }

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

                SizedBox(height: 2.h),

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

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

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

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

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

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

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

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

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

  Future<void> _saveProduct() async {
    final productWithVariant = ref.read(productWithVariantProvider);

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

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

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

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

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

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

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

    final List<UpsertProductVariant> productVariants = [];

    final List<UpsertOutletInventory> outletInventories = [];

    final outletId = await SystemSetting.getCurrentOutletId();

    final List<StockCard> stockCards = [];

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

    final userId = await SystemSetting.getCurrentUserId();

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

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

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

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

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

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

      stockCards.add(
        StockCard(
          outletInventoryId: outletInventories.single.localId,
          userId: userId!,
          stockCardType: StockCardType.initial_stock,
          qtyChange: stock,
          currentStock: stock,
          costPrice: costPrice,
          stockType: stockType,
        ),
      );
    }

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

      if (!mounted) return;

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

      ref.invalidate(variantImageTempProvider);

      CustomSnackbar.showSuccess(context, "Produk berhasil disimpan");

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

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

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

        final productWithVariantState = ref.watch(productWithVariantProvider);

        final bool showStockField = !_hasVariant && !_isStockAlwaysAvailable;

        final List<Category> categories = [];

        final categoryState = ref.watch(categoryStreamProvider);

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

        final List<Unit> units = [];

        final unitState = ref.watch(unitStreamProvider);

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

        final productControllerState = ref.watch(productControllerProvider);

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

            final variantImageTemps = ref.read(variantImageTempProvider);

            await _cleanUpImages(variantImageTemps);

            ref.invalidate(variantImageTempProvider);

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

                  await _cleanUpImages(variantImageTemps);

                  ref.invalidate(variantImageTempProvider);

                  context.canPop()
                      ? context.pop()
                      : context.goNamed(AppRoute.productScreen);
                },
              ),

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

                          SingleChildScrollView(
                            scrollDirection: Axis.horizontal,
                            child: Row(
                              children: [
                                ..._productImages.asMap().entries.map((entry) {
                                  final int index = entry.key;
                                  final String path = entry.value;

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

                                  final bool imageFileExists = imageFile
                                      .existsSync();

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

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

                      SizedBox(height: 3.h),

                      CustomTextFormField(
                        label: "Nama Produk",
                        hint: "Contoh: Kopi Susu Gula Aren",
                        controller: _nameController,
                        validator: (value) => _validator(
                          value: value,
                          message1: "Nama produk belum diisi",
                        ),
                      ),

                      SizedBox(height: 2.5.h),

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

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

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

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

                            if (category != null) {
                              showDialog(
                                context: context,
                                builder: (_) => EditProductCategoryScreen(
                                  category: category,
                                ),
                              );
                            } else {
                              CustomSnackbar.showError(
                                context,
                                "Kategori produk tidak tersedia",
                              );
                            }
                          }
                        },
                      ),

                      SizedBox(height: 3.h),

                      Text(
                        "Tipe Produk",
                        style: TextStyle(
                          fontSize: isTablet
                              ? AppFontSize.medium.sp
                              : AppFontSize.small.sp,
                          fontWeight: FontWeight.bold,
                        ),
                      ),

                      SizedBox(height: 1.5.h),

                      Row(
                        children: [
                          Expanded(
                            child: SelectionCard(
                              title: "Tanpa Varian",
                              isSelected: !_hasVariant,
                              onTap: () => setState(() => _hasVariant = false),
                            ),
                          ),

                          SizedBox(width: 4.w),

                          Expanded(
                            child: SelectionCard(
                              title: "Memiliki Varian",
                              isSelected: _hasVariant,
                              onTap: () => setState(() => _hasVariant = true),
                            ),
                          ),
                        ],
                      ),

                      SizedBox(height: 3.h),

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

                        SizedBox(height: 3.h),

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

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

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

                            context.pushNamed(
                              AppRoute.addVariantProductScreen,
                              // extra: !_isStockAlwaysAvailable,
                              extra: {
                                "is_main_outlet": isMainOutlet,
                                "is_stock_fixed": !_isStockAlwaysAvailable,
                              },
                            );
                          },
                        ),

                      SizedBox(height: 3.h),

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

                      Row(
                        children: [
                          Expanded(
                            child: SelectionCard(
                              title: "Tetap",
                              isSelected: !_isStockAlwaysAvailable,
                              onTap: () => setState(
                                () => _isStockAlwaysAvailable = false,
                              ),
                            ),
                          ),

                          SizedBox(width: 4.w),

                          Expanded(
                            child: SelectionCard(
                              title: "Selalu Ada",
                              isSelected: _isStockAlwaysAvailable,
                              onTap: () => setState(
                                () => _isStockAlwaysAvailable = true,
                              ),
                            ),
                          ),
                        ],
                      ),

                      SizedBox(height: 3.h),

                      if (showStockField) ...[
                        CustomTextFormField(
                          label: "Stok Awal",
                          hint: "100",
                          keyboardType: TextInputType.number,
                          controller: _stockController,
                          validator: (value) => _validator(
                            value: value,
                            message1: "Stok belum diisi",
                            message2: "Stok harus lebih dari 0",
                            isNumber: true,
                            isStock: true,
                            errorMessage: "Stok tidak valid",
                          ),
                        ),

                        SizedBox(height: 3.h),
                      ],

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

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

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

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

                            if (unit != null) {
                              showDialog(
                                context: context,
                                builder: (_) {
                                  return EditUnitScreen(unit: unit);
                                },
                              );
                            } else {
                              CustomSnackbar.showError(
                                context,
                                "Satuan produk tidak tersedia",
                              );
                            }
                          }
                        },
                      ),

                      SizedBox(height: 3.h),

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