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

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

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.FragmentInventoryDetailBinding;
import com.example.petstoremobile.dtos.DropdownDTO;
import com.example.petstoremobile.dtos.InventoryDTO;
import com.example.petstoremobile.dtos.ProductDTO;
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.InventoryDetailViewModel;

import dagger.hilt.android.AndroidEntryPoint;

/**
 * Fragment for displaying and editing inventory item details.
 */
@AndroidEntryPoint
public class InventoryDetailFragment extends Fragment {

    private FragmentInventoryDetailBinding binding;
    private InventoryDetailViewModel viewModel;

    private long preselectedStoreId = -1;
    private long preselectedProductId = -1;

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

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        binding = FragmentInventoryDetailBinding.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.btnInventoryBack.setOnClickListener(v -> navigateBack());
        binding.btnSaveInventory.setOnClickListener(v -> saveInventory());
        binding.btnDeleteInventory.setOnClickListener(v -> confirmDelete());
    }

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

    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.loadStores().observe(getViewLifecycleOwner(), resource -> {
            if (resource == null) return;
            setLoading(resource.status == Resource.Status.LOADING);
            if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
                viewModel.setStoreList(resource.data);
            }
        });
        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);
            }
        });
    }

    private void refreshStoreSpinner() {
        SpinnerUtils.populateSpinner(requireContext(), binding.spinnerInventoryStore, viewModel.getStoreList().getValue(),
                DropdownDTO::getLabel, "-- Select Store --",
                preselectedStoreId, DropdownDTO::getId);
    }

    private void refreshProductSpinner() {
        SpinnerUtils.populateSpinner(requireContext(), binding.spinnerInventoryProduct, viewModel.getProductList().getValue(),
                DropdownDTO::getLabel, "-- Select Product --",
                preselectedProductId, DropdownDTO::getId);
    }

    private void handleArguments() {
        Bundle args = getArguments();
        if (args != null && args.containsKey("inventoryId")) {
            long inventoryId = args.getLong("inventoryId");
            viewModel.setInventoryId(inventoryId);

            binding.tvInventoryMode.setText("Edit Inventory");
            binding.tvInventoryId.setText("Inventory ID: " + inventoryId);
            binding.tvInventoryId.setVisibility(View.VISIBLE);
            binding.btnDeleteInventory.setVisibility(View.VISIBLE);
            binding.btnSaveInventory.setText("Save");

            loadInventoryData();
        } else {
            viewModel.setInventoryId(-1);
            binding.tvInventoryMode.setText("Add Inventory");
            binding.tvInventoryId.setVisibility(View.GONE);
            binding.btnDeleteInventory.setVisibility(View.GONE);
            binding.btnSaveInventory.setText("Add");
        }
    }

    private void loadInventoryData() {
        viewModel.loadInventory().observe(getViewLifecycleOwner(), resource -> {
            if (resource == null) return;
            setLoading(resource.status == Resource.Status.LOADING);
            if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
                InventoryDTO inv = resource.data;
                binding.etQuantity.setText(String.valueOf(inv.getQuantity()));
                preselectedStoreId = inv.getStoreId() != null ? inv.getStoreId() : -1;
                preselectedProductId = inv.getProdId() != null ? inv.getProdId() : -1;
                
                refreshStoreSpinner();
                refreshProductSpinner();
            } else if (resource.status == Resource.Status.ERROR) {
                Toast.makeText(getContext(), "Failed to load inventory: " + resource.message, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void saveInventory() {
        if (!InputValidator.isSpinnerSelected(binding.spinnerInventoryStore, "Store")) return;
        if (!InputValidator.isSpinnerSelected(binding.spinnerInventoryProduct, "Product")) return;
        if (!InputValidator.isPositiveInteger(binding.etQuantity, "Quantity")) return;

        int quantity = Integer.parseInt(binding.etQuantity.getText().toString().trim());
        DropdownDTO store = viewModel.getStoreList().getValue().get(binding.spinnerInventoryStore.getSelectedItemPosition() - 1);
        DropdownDTO product = viewModel.getProductList().getValue().get(binding.spinnerInventoryProduct.getSelectedItemPosition() - 1);

        InventoryDTO request = new InventoryDTO(product.getId(), store.getId(), quantity);
        setButtonsEnabled(false);

        viewModel.saveInventory(request).observe(getViewLifecycleOwner(), resource -> {
            if (resource == null) return;
            setLoading(resource.status == Resource.Status.LOADING);
            if (resource.status != Resource.Status.LOADING) {
                setButtonsEnabled(true);
                if (resource.status == Resource.Status.SUCCESS) {
                    Toast.makeText(getContext(), viewModel.isEditing() ? "Inventory updated" : "Inventory created", 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(), "Inventory Item", this::deleteInventory);
    }

    private void deleteInventory() {
        setButtonsEnabled(false);
        viewModel.deleteInventory().observe(getViewLifecycleOwner(), resource -> {
            if (resource == null) return;
            setLoading(resource.status == Resource.Status.LOADING);
            if (resource.status != Resource.Status.LOADING) {
                setButtonsEnabled(true);
                if (resource.status == Resource.Status.SUCCESS) {
                    Toast.makeText(getContext(), "Inventory 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();
    }

    private void setButtonsEnabled(boolean enabled) {
        UIUtils.setViewsEnabled(enabled, binding.btnSaveInventory, binding.btnDeleteInventory, binding.btnInventoryBack);
    }
}
