package com.example.petstoremobile.utils;

import android.app.DatePickerDialog;
import android.content.Context;
import android.telephony.PhoneNumberFormattingTextWatcher;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextWatcher;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.Toast;

import androidx.fragment.app.Fragment;
import com.example.petstoremobile.fragments.ListFragment;

import java.util.Calendar;
import java.util.Locale;

/**
 * Utility class for shared UI component logic and formatting.
 */
public class UIUtils {
    /**
     * Formats an EditText to phone format.
     */
    public static void formatPhoneInput(EditText editText) {
        editText.addTextChangedListener(new PhoneNumberFormattingTextWatcher("CA"));
        editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(14)});
    }

    /**
     * Sets up a toggle for a filter layout, including icon changes.
     */
    public static void setupFilterToggle(ImageButton btnToggle, View layoutFilter, EditText etSearch, Spinner... spinners) {
        btnToggle.setOnClickListener(v -> {
            boolean isVisible = layoutFilter.getVisibility() == View.VISIBLE;
            layoutFilter.setVisibility(isVisible ? View.GONE : View.VISIBLE);
            
            btnToggle.setImageResource(isVisible ? 
                    android.R.drawable.ic_menu_search : 
                    android.R.drawable.ic_menu_close_clear_cancel);
        });
    }

    /**
     * Simplifies setting up the hamburger menu to open the navigation drawer.
     */
    public static void setupHamburgerMenu(ImageButton btnHamburger, Fragment fragment) {
        btnHamburger.setOnClickListener(v -> {
            Fragment parent = fragment.getParentFragment();
            if (parent != null) {
                Fragment grandParent = parent.getParentFragment();
                if (grandParent instanceof ListFragment) {
                    ((ListFragment) grandParent).openDrawer();
                }
            }
        });
    }

    /**
     * Attaches a simplified TextWatcher to an EditText for search functionality.
     */
    public static void attachSearch(EditText etSearch, Runnable onQueryChanged) {
        etSearch.addTextChangedListener(new TextWatcher() {
            @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
            @Override public void onTextChanged(CharSequence s, int start, int before, int count) {
                onQueryChanged.run();
            }
            @Override public void afterTextChanged(Editable s) {}
        });
    }

    /**
     * Sets the enabled state and alpha for multiple views, only if changed.
     */
    public static void setViewsEnabled(boolean enabled, View... views) {
        for (View v : views) {
            if (v != null) {
                if (v.isEnabled() != enabled) {
                    v.setEnabled(enabled);
                }
                float targetAlpha = enabled ? 1.0f : 0.5f;
                if (Math.abs(v.getAlpha() - targetAlpha) > 0.01f) {
                    v.setAlpha(targetAlpha);
                }
            }
        }
    }

    /**
     * Sets enabled state for a field and updates alpha for both the field and its label, only if changed.
     */
    public static void setFieldEnabled(boolean enabled, View field, View label) {
        if (field != null) {
            if (field.isEnabled() != enabled) {
                field.setEnabled(enabled);
            }
            float targetAlpha = enabled ? 1.0f : 0.5f;
            if (Math.abs(field.getAlpha() - targetAlpha) > 0.01f) {
                field.setAlpha(targetAlpha);
            }
        }
        if (label != null) {
            float targetAlpha = enabled ? 1.0f : 0.5f;
            if (Math.abs(label.getAlpha() - targetAlpha) > 0.01f) {
                label.setAlpha(targetAlpha);
            }
        }
    }

    /**
     * Sets the alpha for multiple views, only if changed.
     */
    public static void setViewsAlpha(float alpha, View... views) {
        for (View v : views) {
            if (v != null && Math.abs(v.getAlpha() - alpha) > 0.01f) {
                v.setAlpha(alpha);
            }
        }
    }

    /**
     * Displays a DatePickerDialog and sets the result to an EditText.
     */
    public static void showDatePicker(Context context, EditText editText, Runnable onDateSet) {
        Calendar c = Calendar.getInstance();
        DatePickerDialog d = new DatePickerDialog(context,
                (dp, y, m, d1) -> {
                    String selectedDate = String.format(Locale.getDefault(), "%04d-%02d-%02d", y, m + 1, d1);
                    editText.setText(selectedDate);
                    if (onDateSet != null) onDateSet.run();
                },
                c.get(Calendar.YEAR), c.get(Calendar.MONTH),
                c.get(Calendar.DAY_OF_MONTH));
        d.setButton(DatePickerDialog.BUTTON_NEUTRAL, "Clear", (dialog, which) -> {
            editText.setText("");
            if (onDateSet != null) onDateSet.run();
        });
        d.getDatePicker().setMinDate(System.currentTimeMillis() - 1000);
        d.show();
    }

    /**
     * Displays a toast and returns false. Useful for validation chains.
     */
    public static boolean showToast(Context context, String msg) {
        if (context != null) {
            Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
        }
        return false;
    }
}
