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

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

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.Navigation;

import com.example.petstoremobile.R;
import com.example.petstoremobile.databinding.FragmentCouponDetailBinding;
import com.example.petstoremobile.dtos.CouponDTO;
import com.example.petstoremobile.utils.DateTimeUtils;
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.CouponDetailViewModel;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

import dagger.hilt.android.AndroidEntryPoint;

@AndroidEntryPoint
public class CouponDetailFragment extends Fragment {
    private FragmentCouponDetailBinding binding;
    private CouponDetailViewModel viewModel;
    private long couponId = -1;

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        binding = FragmentCouponDetailBinding.inflate(inflater, container, false);
        viewModel = new ViewModelProvider(this).get(CouponDetailViewModel.class);

        if (getArguments() != null) {
            couponId = getArguments().getLong("couponId", -1);
            viewModel.setCouponId(couponId, couponId > 0);
        }

        setupDiscountTypeSpinner();
        setupDatePicker(binding.etStartsAtDetail, null, () -> {
            String selectedDate = binding.etStartsAtDetail.getText().toString();
            if (selectedDate.isEmpty()) {
                binding.etEndsAtDetail.setText("");
            } else {
                String today = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());
                if (selectedDate.equals(today)) {
                    binding.cbActiveDetail.setChecked(true);
                }
            }
        });
        setupDatePicker(binding.etEndsAtDetail, binding.etStartsAtDetail, null);

        if (couponId > 0) {
            loadCouponDetails();
            binding.btnDeleteCouponDetail.setVisibility(View.VISIBLE);
        } else {
            binding.tvTitleCouponDetail.setText("Add Coupon");
        }

        binding.btnBackCouponDetail.setOnClickListener(v -> Navigation.findNavController(v).popBackStack());
        binding.btnSaveCouponDetail.setOnClickListener(v -> saveCoupon());
        binding.btnDeleteCouponDetail.setOnClickListener(v -> confirmDelete());

        return binding.getRoot();
    }

    private void setupDiscountTypeSpinner() {
        SpinnerUtils.setupStringSpinner(requireContext(), binding.spinnerDiscountTypeDetail, new String[]{"FIXED", "PERCENT"});
    }

    private void setupDatePicker(android.widget.EditText editText, android.widget.EditText dependOn, Runnable onDateSet) {
        editText.setFocusable(false);
        editText.setClickable(true);
        editText.setCursorVisible(false);
        editText.setOnClickListener(v -> {
            if (dependOn != null && dependOn.getText().toString().trim().isEmpty()) {
                UIUtils.showToast(requireContext(), "Please select a start date first");
                return;
            }
            UIUtils.showDatePicker(requireContext(), editText, onDateSet);
        });
    }

    private void loadCouponDetails() {
        binding.tvCouponId.setText(DateTimeUtils.formatId(couponId));
        binding.tvCouponId.setVisibility(View.VISIBLE);

        viewModel.loadCoupon(couponId).observe(getViewLifecycleOwner(), resource -> {
            if (resource.status == Resource.Status.SUCCESS && resource.data != null) {
                CouponDTO coupon = resource.data;
                binding.etCouponCodeDetail.setText(coupon.getCouponCode());
                binding.spinnerDiscountTypeDetail.setSelection(coupon.getDiscountType().equals("FIXED") ? 0 : 1);
                binding.etDiscountValueDetail.setText(coupon.getDiscountValue().stripTrailingZeros().toPlainString());
                binding.etMinOrderAmountDetail.setText(coupon.getMinOrderAmount().stripTrailingZeros().toPlainString());
                binding.etUsageLimitDetail.setText(coupon.getUsageLimit() != null ? String.valueOf(coupon.getUsageLimit()) : "");
                binding.cbActiveDetail.setChecked(Boolean.TRUE.equals(coupon.getActive()));
                
                if (coupon.getStartsAt() != null) binding.etStartsAtDetail.setText(DateTimeUtils.extractDate(coupon.getStartsAt()));
                if (coupon.getEndsAt() != null) binding.etEndsAtDetail.setText(DateTimeUtils.extractDate(coupon.getEndsAt()));
            }
        });
    }

    private void saveCoupon() {
        if (!InputValidator.isNotEmpty(binding.etCouponCodeDetail, "Coupon Code")) return;
        if (!InputValidator.isGreaterThanZero(binding.etDiscountValueDetail, "Discount Value")) return;
        if (!InputValidator.isPositiveDecimal(binding.etMinOrderAmountDetail, "Min Order Amount")) return;

        String startsAt = binding.etStartsAtDetail.getText().toString().trim();
        String endsAt = binding.etEndsAtDetail.getText().toString().trim();

        if (!startsAt.isEmpty() && !endsAt.isEmpty()) {
            if (startsAt.compareTo(endsAt) > 0) {
                binding.etEndsAtDetail.setError("End date must be after start date");
                UIUtils.showToast(requireContext(), "End date must be after start date");
                return;
            }
        }
        
        String usageLimitStr = binding.etUsageLimitDetail.getText().toString().trim();
        if (!usageLimitStr.isEmpty()) {
            if (!InputValidator.isPositiveInteger(binding.etUsageLimitDetail, "Usage Limit")) return;
        }

        CouponDTO dto = new CouponDTO();
        dto.setCouponCode(binding.etCouponCodeDetail.getText().toString().trim().toUpperCase());
        dto.setDiscountType(binding.spinnerDiscountTypeDetail.getSelectedItem().toString());
        dto.setDiscountValue(new BigDecimal(binding.etDiscountValueDetail.getText().toString().trim()));
        dto.setMinOrderAmount(new BigDecimal(binding.etMinOrderAmountDetail.getText().toString().trim()));
        
        String usageLimit = binding.etUsageLimitDetail.getText().toString().trim();
        dto.setUsageLimit(usageLimit.isEmpty() ? null : Integer.parseInt(usageLimit));
        
        dto.setActive(binding.cbActiveDetail.isChecked());
        
        dto.setStartsAt(startsAt.isEmpty() ? null : startsAt + "T00:00:00");
        
        dto.setEndsAt(endsAt.isEmpty() ? null : endsAt + "T23:59:59");

        viewModel.saveCoupon(dto).observe(getViewLifecycleOwner(), resource -> {
            if (resource.status == Resource.Status.SUCCESS) {
                Navigation.findNavController(requireView()).popBackStack();
            } else if (resource.status == Resource.Status.ERROR) {
                UIUtils.showToast(requireContext(), resource.message);
            }
        });
    }

    private void confirmDelete() {
        new AlertDialog.Builder(requireContext())
                .setTitle("Delete Coupon")
                .setMessage("Are you sure you want to delete this coupon?")
                .setPositiveButton("Delete", (dialog, which) -> {
                    viewModel.deleteCoupon().observe(getViewLifecycleOwner(), resource -> {
                        if (resource.status == Resource.Status.SUCCESS) {
                            Navigation.findNavController(requireView()).popBackStack();
                        } else if (resource.status == Resource.Status.ERROR) {
                            UIUtils.showToast(requireContext(), resource.message);
                        }
                    });
                })
                .setNegativeButton("Cancel", null)
                .show();
    }
}
