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

import android.os.Bundle;
import android.view.*;
import android.widget.*;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.fragment.NavHostFragment;
import com.example.petstoremobile.R;
import com.example.petstoremobile.databinding.FragmentStaffDetailBinding;
import com.example.petstoremobile.dtos.DropdownDTO;
import com.example.petstoremobile.dtos.EmployeeDTO;
import com.example.petstoremobile.utils.DialogUtils;
import com.example.petstoremobile.utils.InputValidator;
import com.example.petstoremobile.utils.SpinnerUtils;
import com.example.petstoremobile.utils.UIUtils;
import com.example.petstoremobile.viewmodels.StaffDetailViewModel;
import com.example.petstoremobile.utils.Resource;

import java.util.List;

import dagger.hilt.android.AndroidEntryPoint;

@AndroidEntryPoint
public class StaffDetailFragment extends Fragment {

    private FragmentStaffDetailBinding binding;
    private StaffDetailViewModel viewModel;

    private final String[] STATUSES = {"Active", "Inactive"};

    private long preselectedStoreId = -1;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        binding = FragmentStaffDetailBinding.inflate(inflater, container, false);
        viewModel = new ViewModelProvider(this).get(StaffDetailViewModel.class);
        
        setupSpinners();
        observeViewModel();
        loadStores();
        handleArguments();

        binding.btnStaffBack.setOnClickListener(v -> navigateBack());
        binding.btnSaveStaff.setOnClickListener(v -> save());
        binding.btnDeleteStaff.setOnClickListener(v -> confirmDelete());
        
        UIUtils.formatPhoneInput(binding.etStaffPhone);
        
        return binding.getRoot();
    }

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

    private void setupSpinners() {
        SpinnerUtils.setupStringSpinner(requireContext(), binding.spinnerStaffStatus, STATUSES);
    }

    private void loadStores() {
        viewModel.loadStores().observe(getViewLifecycleOwner(), resource -> {
            if (resource != null && resource.status == Resource.Status.SUCCESS && resource.data != null) {
                viewModel.setStoreList(resource.data);
            }
        });
    }

    private void refreshStoreSpinner() {
        List<DropdownDTO> list = viewModel.getStoreList().getValue();
        if (list == null) return;
        SpinnerUtils.populateSpinner(requireContext(), binding.spinnerStaffStore, list,
                DropdownDTO::getLabel, "-- Select Store --",
                preselectedStoreId, DropdownDTO::getId);
    }

    private void handleArguments() {
        Bundle a = getArguments();
        if (a != null && a.getBoolean("isEditing", false)) {
            long employeeId = a.getLong("employeeId", -1);
            viewModel.setEmployeeId(employeeId, true);

            binding.tvStaffMode.setText("Edit Staff Account");
            binding.tvStaffId.setText("ID: " + employeeId);
            binding.tvStaffId.setVisibility(View.VISIBLE);
            binding.btnDeleteStaff.setVisibility(View.VISIBLE);

            loadEmployeeData(employeeId);
        } else {
            viewModel.setEmployeeId(-1, false);
            binding.tvStaffMode.setText("Add Staff Account");
            binding.btnDeleteStaff.setVisibility(View.GONE);
            binding.tvStaffId.setVisibility(View.GONE);
        }
    }

    private void loadEmployeeData(long id) {
        viewModel.loadEmployee(id).observe(getViewLifecycleOwner(), resource -> {
            if (resource != null) {
                setLoading(resource.status == Resource.Status.LOADING);
                if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
                    EmployeeDTO e = resource.data;
                    binding.etStaffUsername.setText(e.getUsername());
                    binding.etStaffFirstName.setText(e.getFirstName());
                    binding.etStaffLastName.setText(e.getLastName());
                    binding.etStaffEmail.setText(e.getEmail());
                    binding.etStaffPhone.setText(e.getPhone());
                    
                    binding.spinnerStaffStatus.setSelection(Boolean.TRUE.equals(e.getActive()) ? 0 : 1);
                    
                    preselectedStoreId = e.getPrimaryStoreId() != null ? e.getPrimaryStoreId() : -1;
                    refreshStoreSpinner();
                }
            }
        });
    }

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

    private void save() {
        if (!InputValidator.isNotEmpty(binding.etStaffUsername, "Username")) return;

        String password = binding.etStaffPassword.getText().toString().trim();
        String confirmPassword = binding.etStaffConfirmPassword.getText().toString().trim();

        if (!viewModel.isEditing()) {
            if (!InputValidator.isNotEmpty(binding.etStaffPassword, "Password")) return;
            if (password.length() < 6) {
                binding.etStaffPassword.setError("At least 6 characters");
                binding.etStaffPassword.requestFocus();
                return;
            }
            if (!password.equals(confirmPassword)) {
                binding.etStaffConfirmPassword.setError("Passwords do not match");
                binding.etStaffConfirmPassword.requestFocus();
                return;
            }
        } else if (!password.isEmpty()) {
            if (password.length() < 6) {
                binding.etStaffPassword.setError("At least 6 characters");
                binding.etStaffPassword.requestFocus();
                return;
            }
            if (!password.equals(confirmPassword)) {
                binding.etStaffConfirmPassword.setError("Passwords do not match");
                binding.etStaffConfirmPassword.requestFocus();
                return;
            }
        }

        if (!InputValidator.isNotEmpty(binding.etStaffFirstName, "First Name")) return;
        if (!InputValidator.isNotEmpty(binding.etStaffLastName, "Last Name")) return;
        if (!InputValidator.isValidEmail(binding.etStaffEmail)) return;
        if (!InputValidator.isValidPhone(binding.etStaffPhone)) return;
        if (!InputValidator.isSpinnerSelected(binding.spinnerStaffStore, "Primary Store")) return;

        String username  = binding.etStaffUsername.getText().toString().trim();
        String firstName = binding.etStaffFirstName.getText().toString().trim();
        String lastName  = binding.etStaffLastName.getText().toString().trim();
        String email     = binding.etStaffEmail.getText().toString().trim();
        String phone     = binding.etStaffPhone.getText().toString().trim();
        String role      = "STAFF";
        String staffRole = null;
        boolean active   = binding.spinnerStaffStatus.getSelectedItemPosition() == 0;
        
        List<DropdownDTO> stores = viewModel.getStoreList().getValue();
        Long storeId = stores.get(binding.spinnerStaffStore.getSelectedItemPosition() - 1).getId();

        EmployeeDTO dto = viewModel.createEmployeeDto(
                username,
                password.isEmpty() ? null : password,
                firstName,
                lastName,
                email,
                phone,
                role,
                staffRole,
                active,
                storeId
        );

        viewModel.saveEmployee(dto).observe(getViewLifecycleOwner(), resource -> {
            if (resource != null) {
                setLoading(resource.status == Resource.Status.LOADING);
                if (resource.status == Resource.Status.SUCCESS) {
                    Toast.makeText(getContext(), viewModel.isEditing() ? "Updated successfully" : "Staff account created", Toast.LENGTH_SHORT).show();
                    navigateBack();
                } else if (resource.status == Resource.Status.ERROR) {
                    Toast.makeText(getContext(), "Error: " + resource.message, Toast.LENGTH_LONG).show();
                }
            }
        });
    }

    private void confirmDelete() {
        DialogUtils.showDeleteConfirmDialog(requireContext(), "Staff Account", () ->
                viewModel.deleteEmployee().observe(getViewLifecycleOwner(), resource -> {
                    if (resource != null) {
                        setLoading(resource.status == Resource.Status.LOADING);
                        if (resource.status == Resource.Status.SUCCESS) {
                            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();
    }

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