package com.example.petstoremobile.fragments.listfragments.detailfragments;

import android.os.Bundle;
import android.view.*;
import android.widget.*;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.fragment.NavHostFragment;

import com.example.petstoremobile.databinding.FragmentProductSupplierDetailBinding;
import com.example.petstoremobile.dtos.*;
import com.example.petstoremobile.utils.DialogUtils;
import com.example.petstoremobile.utils.InputValidator;
import com.example.petstoremobile.utils.Resource;
import com.example.petstoremobile.utils.SpinnerUtils;
import com.example.petstoremobile.utils.UIUtils;
import com.example.petstoremobile.viewmodels.ProductSupplierDetailViewModel;

import java.math.BigDecimal;
import java.util.*;

import dagger.hilt.android.AndroidEntryPoint;

/**
 * Fragment for displaying and editing the relationship between products and suppliers.
 */
@AndroidEntryPoint
public class ProductSupplierDetailFragment extends Fragment {

    private FragmentProductSupplierDetailBinding binding;
    private ProductSupplierDetailViewModel viewModel;

    private long preselectedProductId = -1;
    private long preselectedSupplierId = -1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        viewModel = new ViewModelProvider(this).get(ProductSupplierDetailViewModel.class);
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        binding = FragmentProductSupplierDetailBinding.inflate(inflater, container, false);
        return binding.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        observeViewModel();
        loadSpinnersData();
        handleArguments();

        binding.btnPSBack.setOnClickListener(v -> navigateBack());
        binding.btnSavePS.setOnClickListener(v -> save());
        binding.btnDeletePS.setOnClickListener(v -> confirmDelete());
    }

    private void observeViewModel() {
        viewModel.getProductList().observe(getViewLifecycleOwner(), list -> refreshProductSpinner());
        viewModel.getSupplierList().observe(getViewLifecycleOwner(), list -> refreshSupplierSpinner());
    }

    private void setLoading(boolean loading) {
        if (binding != null && binding.progressBar != null) {
            binding.progressBar.setVisibility(loading ? View.VISIBLE : View.GONE);
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }

    private void loadSpinnersData() {
        viewModel.loadProducts().observe(getViewLifecycleOwner(), resource -> {
            if (resource == null) return;
            setLoading(resource.status == Resource.Status.LOADING);
            if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
                viewModel.setProductList(resource.data.getContent());
            }
        });
        viewModel.loadSuppliers().observe(getViewLifecycleOwner(), resource -> {
            if (resource == null) return;
            setLoading(resource.status == Resource.Status.LOADING);
            if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
                viewModel.setSupplierList(resource.data.getContent());
            }
        });
    }

    private void refreshProductSpinner() {
        SpinnerUtils.populateSpinner(requireContext(), binding.spinnerPSProduct, viewModel.getProductList().getValue(),
                ProductDTO::getProdName, "-- Select Product --",
                preselectedProductId, ProductDTO::getProdId);
    }

    private void refreshSupplierSpinner() {
        SpinnerUtils.populateSpinner(requireContext(), binding.spinnerPSSupplier, viewModel.getSupplierList().getValue(),
                SupplierDTO::getSupCompany, "-- Select Supplier --",
                preselectedSupplierId, SupplierDTO::getSupId);
    }

    private void handleArguments() {
        Bundle a = getArguments();
        if (a != null && a.containsKey("productId") && a.containsKey("supplierId")) {
            long productId = a.getLong("productId");
            long supplierId = a.getLong("supplierId");
            viewModel.setEditMode(productId, supplierId);
            preselectedProductId = productId;
            preselectedSupplierId = supplierId;

            binding.tvPSMode.setText("Edit Product Supplier");
            binding.btnDeletePS.setVisibility(View.VISIBLE);

            viewModel.loadProductSupplier().observe(getViewLifecycleOwner(), resource -> {
                if (resource == null) return;
                if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
                    if (resource.data.getCost() != null) {
                        binding.etPSCost.setText(resource.data.getCost().toPlainString());
                    }
                }
            });
        } else {
            binding.tvPSMode.setText("Add Product Supplier");
            binding.btnDeletePS.setVisibility(View.GONE);
        }
    }

    private void save() {
        if (!InputValidator.isSpinnerSelected(binding.spinnerPSProduct, "Product")) return;
        if (!InputValidator.isSpinnerSelected(binding.spinnerPSSupplier, "Supplier")) return;
        if (!InputValidator.isPositiveDecimal(binding.etPSCost, "Cost")) return;

        ProductDTO product   = viewModel.getProductList().getValue().get(binding.spinnerPSProduct.getSelectedItemPosition() - 1);
        SupplierDTO supplier = viewModel.getSupplierList().getValue().get(binding.spinnerPSSupplier.getSelectedItemPosition() - 1);
        BigDecimal cost = new BigDecimal(binding.etPSCost.getText().toString().trim());

        ProductSupplierDTO dto = new ProductSupplierDTO(product.getProdId(), supplier.getSupId(), cost);

        viewModel.saveProductSupplier(dto).observe(getViewLifecycleOwner(), resource -> {
            if (resource == null) return;
            setLoading(resource.status == Resource.Status.LOADING);
            if (resource.status == Resource.Status.SUCCESS) {
                Toast.makeText(getContext(), viewModel.isEditing() ? "Updated" : "Saved", Toast.LENGTH_SHORT).show();
                navigateBack();
            } else if (resource.status == Resource.Status.ERROR) {
                Toast.makeText(getContext(), "Error: " + resource.message, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void confirmDelete() {
        DialogUtils.showDeleteConfirmDialog(requireContext(), "Product Supplier Relationship", () ->
                viewModel.deleteProductSupplier().observe(getViewLifecycleOwner(), resource -> {
                    if (resource == null) return;
                    setLoading(resource.status == Resource.Status.LOADING);
                    if (resource.status == Resource.Status.SUCCESS) {
                        Toast.makeText(getContext(), "Deleted", Toast.LENGTH_SHORT).show();
                        navigateBack();
                    } else if (resource.status == Resource.Status.ERROR) {
                        Toast.makeText(getContext(), "Delete failed: " + resource.message, Toast.LENGTH_SHORT).show();
                    }
                }));
    }

    private void navigateBack() {
        NavHostFragment.findNavController(this).popBackStack();
    }
}
