import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:image_picker/image_picker.dart';
import 'package:niogu_app/core/components/top_back_bar_app.dart';
import 'package:niogu_app/core/constants/app_color.dart';
import 'package:niogu_app/core/constants/app_font_size.dart';
import 'package:niogu_app/core/providers/app_provider.dart';
import 'package:niogu_app/core/utils/extension_format.dart';
import 'package:niogu_app/core/utils/image_service.dart';
import 'package:niogu_app/core/utils/log_message.dart';
import 'package:niogu_app/core/enums/user_role.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/products/domain/entities/product.dart';
import 'package:niogu_app/features/goods/products/presentation/providers/product_provider.dart';
import 'package:niogu_app/features/goods/products/presentation/widgets/product_variant_model.dart';
import 'package:niogu_app/features/goods/products/presentation/widgets/manage_varian_shimmer.dart';
import 'package:niogu_app/features/goods/products/presentation/widgets/variant_product_card.dart';
import 'package:sizer/sizer.dart';

class EditProductVariantScreen extends ConsumerStatefulWidget {
  final String productId;
  final bool isMainOutlet;
  final bool isEditing;
  final bool hasNewVariant;
  final bool isStockFixed;

  const EditProductVariantScreen({
    super.key,
    required this.productId,
    this.isMainOutlet = true,
    this.isEditing = true,
    this.hasNewVariant = false,
    required this.isStockFixed,
  });

  @override
  ConsumerState<EditProductVariantScreen> createState() =>
      _EditProductVariantScreenState();
}

class _EditProductVariantScreenState
    extends ConsumerState<EditProductVariantScreen> {
  late final String _productId;

  late final bool _hasNewVariant;

  final List<GlobalKey<FormState>> _formKeys = [];

  Map<String, bool> _selectedNewVariants = {};

  final List<ProductVariantModel> _variantModels = [];

  final ScrollController _scrollController = ScrollController();

  final ImagePicker _picker = ImagePicker();

  final List<String?> _pathImageTemps = [];

  final List<ProductVariantModel> _deleteVariantModels = [];

  bool _isLoading = true;

  @override
  void initState() {
    super.initState();
    _productId = widget.productId;

    _hasNewVariant = widget.hasNewVariant;

    WidgetsBinding.instance.addPostFrameCallback((_) {
      Future.delayed(const Duration(milliseconds: 800), () {
        _fecthVariants();
      });
    });
  }

  @override
  void dispose() {
    for (final variant in _variantModels) {
      variant.dispose();
    }

    for (final variant in _deleteVariantModels) {
      variant.dispose();
    }
    _scrollController.dispose();
    super.dispose();
  }

  Future<void> _fecthVariants() async {
    final variants = [...ref.read(productWithVariantProvider)];

    if (_hasNewVariant) {
      final newVariants = await ref
          .read(productRepositoryProvider)
          .fetchNewVariants(_productId);

      final List<ProductWithVariant> nVariants = [];

      for (final variant in newVariants) {
        if (!variants.any(
          (v) => v.productVariantId == variant.productVariantId,
        )) {
          nVariants.add(variant);
        }
      }

      final selectedNewVariants = ref.read(selectedNewVariantProvider);

      if (selectedNewVariants.isNotEmpty) {
        _selectedNewVariants = {...selectedNewVariants};
      } else {
        _selectedNewVariants = {
          for (final variant in nVariants) variant.productVariantId!: false,
        };
      }

      variants.addAll(nVariants);
    }

    if (variants.isNotEmpty) {
      for (int i = 0; i < variants.length; i++) {
        _formKeys.add(GlobalKey<FormState>());

        _variantModels.add(ProductVariantModel());

        _variantModels[i].productVariantId = variants[i].productVariantId;

        _variantModels[i].outletInventoryId = variants[i].outletInventoryId;

        _variantModels[i].imagePath = variants[i].imagePath;

        _variantModels[i].nameController.text = variants[i].name;

        _variantModels[i].stockController.text = variants[i].stock
            .toStringWithoutTrailingZero();

        _variantModels[i].costPriceController.text = variants[i].costPrice
            .toStringWithoutTrailingZero();

        _variantModels[i].sellingPriceController.text = variants[i].sellingPrice
            .toStringWithoutTrailingZero();
      }
    } else {
      _formKeys.add(GlobalKey<FormState>());

      _variantModels.add(ProductVariantModel());
    }

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

  void _onSelectedNewVariant(ProductVariantModel variant) {
    final id = variant.productVariantId;

    setState(() {
      _selectedNewVariants[id!] = !_selectedNewVariants[id]!;
    });
  }

  void _addVariant() {
    setState(() {
      _formKeys.add(GlobalKey<FormState>());
      _variantModels.add(ProductVariantModel());
    });

    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (_scrollController.hasClients) {
        _scrollController.animateTo(
          _scrollController.position.maxScrollExtent,
          duration: const Duration(milliseconds: 300),
          curve: Curves.easeOut,
        );
      }
    });
  }

  Future<void> _removeVariant(int index) async {
    _deleteVariantModels.add(_variantModels[index]);
    setState(() {
      _formKeys.removeAt(index);
      _variantModels[index].dispose();
      _variantModels.removeAt(index);
    });
  }

  Future<void> _showPickerOptions(int index) 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, index);
                    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, index);
                    context.pop();
                  },
                ),
              ],
            ),
          ),
        );
      },
    );
  }

  Future<void> _getImage(ImageSource ImageSource, int index) async {
    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_variant_images",
        );

        if (savedPath != null) {
          _pathImageTemps.add(savedPath);
          ref.read(variantImageTempProvider.notifier).state = _pathImageTemps;
          setState(() {
            _variantModels[index].imagePath = savedPath;
          });
        }
      }
    } catch (e, st) {
      LogMessage.log.w(e.toString(), error: e, stackTrace: st);
      CustomSnackbar.showWarning(context, "Akses ditolak");
    }
  }

  Future<void> _removeImage(int index) async {
    setState(() {
      _variantModels[index].imagePath = null;
    });
  }

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

  void _saveVariant() {
    final lastKey = _formKeys.last;

    if (!lastKey.currentState!.validate()) {
      return;
    }

    final List<ProductWithVariant> variants = [];

    try {
      for (var variantModel in _variantModels) {
        final String? productVariantId = variantModel.productVariantId;

        final String? outletInventoryId = variantModel.outletInventoryId;

        final String? imagePath = variantModel.imagePath;

        final String name = variantModel.nameController.text.trim();

        final double stock = widget.isStockFixed
            ? double.parse(variantModel.stockController.text.trim())
            : 0.0;

        final double costPrice = double.parse(
          variantModel.costPriceController.text.trim(),
        );

        final double sellingPrice = double.parse(
          variantModel.sellingPriceController.text.trim(),
        );

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

        final isSelected = _selectedNewVariants[variantModel.productVariantId];

        if (isSelected != null && !isSelected) continue;

        final productWithVariant = ProductWithVariant(
          productVariantId: productVariantId,
          outletInventoryId: outletInventoryId,
          imagePath: imagePath,
          name: name,
          stock: stock,
          costPrice: costPrice,
          sellingPrice: sellingPrice,
        );
        variants.add(productWithVariant);
      }
    } catch (e, st) {
      LogMessage.log.e(e.toString(), error: e, stackTrace: st);
      CustomSnackbar.showError(context, "Format angka tidak valid");
      return;
    }

    final List<DeleteProductVariant> deleteVariants = [];

    for (var variant in _deleteVariantModels) {
      if (variant.productVariantId != null &&
          variant.outletInventoryId != null) {
        deleteVariants.add(
          DeleteProductVariant(
            productId: _productId,
            productVariantId: variant.productVariantId!,
            outletInventoryId: variant.outletInventoryId!,
          ),
        );
      }
    }

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

    final Map<String, bool> selectedNewVariants = {};

    for (final selected in _selectedNewVariants.entries) {
      final key = selected.key;

      final value = selected.value;

      if (value) selectedNewVariants.putIfAbsent(key, () => value);
    }

    ref.read(selectedNewVariantProvider.notifier).state = selectedNewVariants;

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

    CustomSnackbar.showSuccess(context, "Varian produk diperbarui");

    context.pop();
  }

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

        const backgroundColor = Color(0xFFF9FAFB);

        final messageActivity = ref.watch(messageActivityProvider);

        final currentUserRole = ref.watch(currentUserRoleProvider);

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

            await _cleanUpImages();

            context.pop();
          },
          child: SafeArea(
            top: false,
            bottom: true,
            right: false,
            left: false,
            child: Stack(
              children: [
                Scaffold(
                  resizeToAvoidBottomInset: false,
                  backgroundColor: backgroundColor,
                  appBar: TopBackBarApp(
                    title: "Atur Varian Produk",
                    onTap: () async {
                      await _cleanUpImages();

                      context.pop();
                    },
                  ),
                  body: _isLoading
                      ? const ManageVariantShimmer()
                      : SingleChildScrollView(
                          controller: _scrollController,
                          padding: EdgeInsets.fromLTRB(5.w, 3.h, 5.w, 12.h),
                          child: Column(
                            children: [
                              Container(
                                padding: EdgeInsets.symmetric(
                                  horizontal: 2.w,
                                  vertical: 1.h,
                                ),
                                margin: EdgeInsets.only(bottom: 2.h),
                                decoration: BoxDecoration(
                                  color: Colors.blue[50],
                                  borderRadius: BorderRadius.circular(4.w),
                                ),
                                child: Row(
                                  children: [
                                    Icon(
                                      Icons.info_outline,
                                      color: AppColor.primaryColor,
                                      size: 5.w,
                                    ),

                                    SizedBox(width: 3.w),

                                    Expanded(
                                      child: Text(
                                        "Setiap varian dapat memiliki harga dan stok yang berbeda.",
                                        style: TextStyle(
                                          color: AppColor.primaryColor,
                                          fontSize: isTablet
                                              ? AppFontSize.medium.sp
                                              : AppFontSize.small.sp,
                                        ),
                                      ),
                                    ),
                                  ],
                                ),
                              ),

                              ..._variantModels.asMap().entries.map((entry) {
                                final index = entry.key;

                                final variant = _variantModels[index];

                                final id = variant.productVariantId;

                                final isSelected =
                                    _selectedNewVariants[id] ?? false;

                                return Padding(
                                  padding: EdgeInsets.only(bottom: 3.h),
                                  child: VariantProductCard(
                                    userRole: currentUserRole!,
                                    isMainOutlet: widget.isMainOutlet,
                                    isEditing: widget.isEditing,
                                    isSelected: isSelected,
                                    formKey: _formKeys[index],
                                    length: _variantModels.length,
                                    variant: variant,
                                    index: index,
                                    isStockFixed: widget.isStockFixed,
                                    nameController: variant.nameController,
                                    stockController: variant.stockController,
                                    costPriceController:
                                        variant.costPriceController,
                                    sellingPriceController:
                                        variant.sellingPriceController,
                                    onTapSelected: () =>
                                        _onSelectedNewVariant(variant),
                                    onTapRemoveVarian: () async =>
                                        await _removeVariant(index),
                                    onTapVariantImageAdd: () async =>
                                        await _showPickerOptions(index),
                                    onTapVariantImageRemove: () async =>
                                        await _removeImage(index),
                                  ),
                                );
                              }),

                              if (currentUserRole == UserRole.owner &&
                                  widget.isMainOutlet)
                                GestureDetector(
                                  onTap: () async {
                                    FocusScope.of(context).unfocus();

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

                                    final lastKey = _formKeys.last;

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

                                    for (var variant in _variantModels) {
                                      final double costPrice = double.parse(
                                        variant.costPriceController.text.trim(),
                                      );
                                      final double sellingPrice = double.parse(
                                        variant.sellingPriceController.text
                                            .trim(),
                                      );

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

                                    _addVariant();
                                  },
                                  child: Container(
                                    width: double.infinity,
                                    padding: EdgeInsets.symmetric(
                                      horizontal: 4.w,
                                      vertical: 2.h,
                                    ),
                                    decoration: BoxDecoration(
                                      color: Colors.white,
                                      borderRadius: BorderRadius.circular(3.w),
                                    ),
                                    child: Row(
                                      mainAxisAlignment:
                                          MainAxisAlignment.center,
                                      children: [
                                        Icon(
                                          Icons.add_circle_outline_rounded,
                                          color: AppColor.primaryColor,
                                        ),

                                        SizedBox(width: 3.w),

                                        Text(
                                          "Tambah Varian Baru",
                                          style: TextStyle(
                                            color: AppColor.primaryColor,
                                            fontSize: AppFontSize.medium.sp,
                                            fontWeight: FontWeight.bold,
                                          ),
                                        ),
                                      ],
                                    ),
                                  ),
                                ),
                            ],
                          ),
                        ),

                  bottomNavigationBar: _isLoading
                      ? const SizedBox()
                      : 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: _saveVariant,
                              style: ElevatedButton.styleFrom(
                                backgroundColor: AppColor.primaryColor,
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(2.5.w),
                                ),
                                elevation: 0,
                              ),
                              child: Text(
                                "Simpan Perubahan",
                                style: TextStyle(
                                  color: Colors.white,
                                  fontSize: AppFontSize.medium.sp,
                                  fontWeight: FontWeight.bold,
                                ),
                              ),
                            ),
                          ),
                        ),
                ),

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