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

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.fragment.NavHostFragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.Toast;

import com.example.petstoremobile.databinding.FragmentServiceDetailBinding;
import com.example.petstoremobile.dtos.ServiceDTO;
import com.example.petstoremobile.utils.ActivityLogger;
import com.example.petstoremobile.utils.DateTimeUtils;
import com.example.petstoremobile.utils.DialogUtils;
import com.example.petstoremobile.utils.InputValidator;
import com.example.petstoremobile.utils.Resource;
import com.example.petstoremobile.utils.UIUtils;
import com.example.petstoremobile.viewmodels.ServiceDetailViewModel;

import dagger.hilt.android.AndroidEntryPoint;

/**
 * Fragment for displaying and editing service details.
 */
@AndroidEntryPoint
public class ServiceDetailFragment extends Fragment {

    private FragmentServiceDetailBinding binding;
    private ServiceDetailViewModel viewModel;

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

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

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

        observeViewModel();
        handleArguments();

        binding.btnBack.setOnClickListener(v -> navigateBack());
        binding.btnSaveService.setOnClickListener(v -> saveService());
        binding.btnDeleteService.setOnClickListener(v -> deleteService());
    }

    private void observeViewModel() {
        viewModel.getViewState().observe(getViewLifecycleOwner(), this::applyViewState);
    }

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

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

    private void saveService() {
        if (!InputValidator.isNotEmpty(binding.etServiceName, "Service Name")) return;
        if (!InputValidator.isNotEmpty(binding.etServiceDesc, "Description")) return;
        if (!InputValidator.isPositiveInteger(binding.etServiceDuration, "Duration")) return;
        if (!InputValidator.isPositiveDecimal(binding.etServicePrice, "Price")) return;

        String name = binding.etServiceName.getText().toString().trim();
        String desc = binding.etServiceDesc.getText().toString().trim();
        int duration = Integer.parseInt(binding.etServiceDuration.getText().toString().trim());
        double price = Double.parseDouble(binding.etServicePrice.getText().toString().trim());

        ServiceDTO serviceDTO = new ServiceDTO();
        serviceDTO.setServiceName(name);
        serviceDTO.setServiceDesc(desc);
        serviceDTO.setServiceDuration(duration);
        serviceDTO.setServicePrice(price);

        viewModel.saveService(serviceDTO).observe(getViewLifecycleOwner(), resource -> {
            if (resource == null) return;
            setLoading(resource.status == Resource.Status.LOADING);
            if (resource.status == Resource.Status.SUCCESS) {
                if (viewModel.isEditing()) {
                    ActivityLogger.logChange(requireContext(), "Service", "UPDATED", (int) viewModel.getServiceId());
                    Toast.makeText(getContext(), "Service updated successfully!", Toast.LENGTH_SHORT).show();
                } else {
                    ActivityLogger.log(requireContext(), "Added new Service: " + name);
                    Toast.makeText(getContext(), "Service added successfully!", Toast.LENGTH_SHORT).show();
                }
                navigateBack();
            } else if (resource.status == Resource.Status.ERROR) {
                Toast.makeText(getContext(), "Error: " + resource.message, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void deleteService() {
        DialogUtils.showDeleteConfirmDialog(requireContext(), "Service", () -> 
                viewModel.deleteService().observe(getViewLifecycleOwner(), resource -> {
                    if (resource == null) return;
                    setLoading(resource.status == Resource.Status.LOADING);
                    if (resource.status == Resource.Status.SUCCESS) {
                        ActivityLogger.logChange(requireContext(), "Service", "DELETED", (int) viewModel.getServiceId());
                        Toast.makeText(getContext(), "Service deleted successfully!", 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 handleArguments() {
        if (getArguments() != null && getArguments().containsKey("serviceId")) {
            viewModel.setServiceId(getArguments().getLong("serviceId"));
            loadServiceData();
            return;
        }

        viewModel.setServiceId(-1);
    }

    private void loadServiceData() {
        viewModel.loadService().observe(getViewLifecycleOwner(), resource -> {
            if (resource == null) return;
            setLoading(resource.status == Resource.Status.LOADING);
            if (resource.status == Resource.Status.ERROR) {
                Toast.makeText(getContext(), "Failed to load service: " + resource.message, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void applyViewState(ServiceDetailViewModel.ViewState state) {
        binding.tvMode.setText(state.modeTitle);
        binding.tvServiceId.setText(DateTimeUtils.formatId(viewModel.getServiceId()));
        binding.tvServiceId.setVisibility(state.isServiceIdVisible ? View.VISIBLE : View.GONE);
        binding.btnDeleteService.setVisibility(state.isDeleteVisible ? View.VISIBLE : View.GONE);
        binding.btnSaveService.setText(state.saveButtonText);

        UIUtils.setViewsEnabled(state.isFieldsEnabled,
                binding.etServiceName,
                binding.etServiceDesc,
                binding.etServiceDuration,
                binding.etServicePrice);

        updateIfDifferent(binding.etServiceName, state.serviceName);
        updateIfDifferent(binding.etServiceDesc, state.serviceDesc);
        updateIfDifferent(binding.etServiceDuration, state.serviceDuration);
        updateIfDifferent(binding.etServicePrice, state.servicePrice);
    }

    private void updateIfDifferent(EditText field, String value) {
        String current = field.getText() != null ? field.getText().toString() : "";
        String next = value != null ? value : "";
        if (!current.equals(next)) {
            field.setText(next);
        }
    }
}
