package com.example.quiz;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;

import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import com.anggastudio.printama.Printama;
import com.example.quiz.data.model.dtos.paris.SoldeResponse;
import com.example.quiz.databinding.FragmentSoldBinding;
import com.example.quiz.utils.BitMapUtils;
import com.example.quiz.utils.LoaderDialog;
import com.example.quiz.utils.MessageDialog;
import com.example.quiz.utils.MobiIotPrinterManager;
import com.example.quiz.utils.Result;
import com.example.quiz.utils.SharedPrefsHelper;
import com.example.quiz.utils.SunmiPrinterManager;
import com.example.quiz.viewModel.LogsViewModel;
import com.example.quiz.viewModel.PariViewModel;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.zxing.WriterException;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;

import dagger.hilt.android.AndroidEntryPoint;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link Sold#newInstance} factory method to
 * create an instance of this fragment.
 */
@AndroidEntryPoint
public class Sold extends Fragment {

    FragmentSoldBinding binding;

    SunmiPrinterManager sunmiPrinterManager;

    MutableLiveData<Boolean> isPrinterReady = new MutableLiveData<>(false);
    String mobileName;

    LoaderDialog dialog;

    PariViewModel pariViewModel;
    SharedPrefsHelper prefsHelper;
    LogsViewModel logsViewModel;

    public Sold() {
        // Required empty public constructor
    }

        // TODO: Rename and change types and number of parameters
    public static Sold newInstance() {
        Sold fragment = new Sold();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        prefsHelper = SharedPrefsHelper.getInstance(getContext());
        mobileName = Build.MANUFACTURER;
        sunmiPrinterManager = SunmiPrinterManager.getInstance(requireContext());
        if(mobileName.toLowerCase().contains("sunmi")){
            sunmiPrinterManager.connectPrinter(status ->{
                isPrinterReady.setValue(status);
                sunmiPrinterManager.disableSystemMessages();
            });
        }else{
            MobiIotPrinterManager.getInstance().init(requireContext());
        }
        AppCompatActivity activity = (AppCompatActivity) getActivity();
        if(activity != null){
            MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
            activity.setSupportActionBar(toolbar);
            if(activity.getSupportActionBar() != null){
                activity.getSupportActionBar().setTitle("Soldes");
            }
        }
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        binding = FragmentSoldBinding.inflate(inflater, container, false);
        dialog = new LoaderDialog(getContext());
        logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
        return binding.getRoot();

    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        pariViewModel = new ViewModelProvider(this).get(PariViewModel.class);
        binding.btnByCourse.setOnClickListener(v -> {
            FragmentManager fragmentManager = getParentFragmentManager();
            SoldByCourse soldByCourse = SoldByCourse.newInstance();
            fragmentManager.beginTransaction()
                    .replace(R.id.nav_host_fragment_content_main, soldByCourse)
                    .addToBackStack(null)
                    .commit();
        });

        binding.btnByDay.setOnClickListener(v->{
            _showCalendar();
        });
    }


    String _reformatDateForDate(int num){
        if(num<10){
            return "0"+num;
        }
        return String.valueOf(num);
    }
    void _showCalendar(){
        Calendar calendar = Calendar.getInstance();
        DatePickerDialog datePickerDialog = new DatePickerDialog(
                getContext(),
                (view, year, month, dayOfMonth) -> {
                    String date = year + "-" + _reformatDateForDate(month + 1) + "-" + _reformatDateForDate(dayOfMonth);
                    pariViewModel.getSoldeByDay(prefsHelper.get("id"), date).observe(getViewLifecycleOwner(), new Observer<Result<SoldeResponse>>() {
                        @Override
                        public void onChanged(Result<SoldeResponse> doubleResult) {
                          switch (doubleResult.status){
                              case LOADING:{
                                  dialog.show("Solde du jour");
                                  break;
                              }
                              case ERROR:{
                                  dialog.dismiss();
                                  MessageDialog.showError(getContext(), doubleResult.message);
                                  break;
                              }
                              case SUCCESS:{
                                  dialog.dismiss();

                                  try {
                                      _showSold(doubleResult.data, date);
                                  } catch (WriterException e) {
                                      throw new RuntimeException(e);
                                  }
                                  logsViewModel.insertLog(prefsHelper.get("id"), "SOLDE JOUR", "Solde du "+date, System.currentTimeMillis());
                                  break;
                              }
                          }
                        }
                    });
                },
                calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH)
        );

        datePickerDialog.show();
    }

    void _showSold(SoldeResponse soldeResponse, String date) throws WriterException {
        try {
            int solde = soldeResponse.getMontantParis() - soldeResponse.getMontantAnnulations() - soldeResponse.getMontantPaiements();
            new AlertDialog.Builder(getContext())
                    .setTitle("Solde")
                    .setMessage("Solde la course "+solde)
                    .setNeutralButton("Ok", (dialog, which)->{
                        dialog.dismiss();
                    })
                    .setPositiveButton("Imprimer", (dialog, which)->{
                        if(mobileName.toLowerCase().contains("sunmi")){
                            if(isPrinterReady.getValue() == null || !isPrinterReady.getValue()){
                                sunmiPrinterManager.connectPrinter(status ->{
                                    isPrinterReady.setValue(status);
                                });
                            }
                            if(sunmiPrinterManager.printerStatus() != 1){
                                MessageDialog.showError(getContext(), "Erreur lors de l'impréssion, Veuillez rééssayer S.V.P!");
                                return;
                            }
                        }else{
                            try {
                                int status = MobiIotPrinterManager.getInstance().getPrinterStatus();
                                if(status != 1){
                                    MessageDialog.showError(getContext(), "Erreur lors de l'impréssion, Veuillez rééssayer S.V.P!");
                                    return;
                                }
                            } catch (RemoteException e) {
                                throw new RuntimeException(e);
                            }
                        }
                        Bitmap logo = BitmapFactory.decodeResource(getResources(), R.drawable.pmu_logo);
                        String title = "SOLDE AU "+date;
                        StringBuilder text = new StringBuilder();
                        text.append("VENTES HIPPIQUES: ").append(BitMapUtils.formatMontant(soldeResponse.getMontantParis())).append(" XOF").append("\n");
                        text.append("NBR. PAIEMENTS: ").append(BitMapUtils.formatMontant(soldeResponse.getNombrePaiements())).append("\n");
                        text.append("PAIEMENTS: ").append(BitMapUtils.formatMontant(soldeResponse.getMontantPaiements())).append(" XOF").append("\n");
                        text.append("NBR. ANNULATIONS: ").append(BitMapUtils.formatMontant(soldeResponse.getNombreAnnulations())).append("\n");
                        text.append("ANNULATIONS: ").append(BitMapUtils.formatMontant(soldeResponse.getMontantAnnulations())).append(" XOF").append("\n");
                        text.append(sunmiPrinterManager.separationText()).append("\n");
                        text.append("SOLDE: ").append(BitMapUtils.formatMontant(solde)).append(" XOF").append("\n");
                        text.append(sunmiPrinterManager.separationText()).append("\n");
                        text.append("AGENT     :  ").append(prefsHelper.get("code")).append("\n");
                        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
                        String now = formatter.format(LocalDateTime.now());
                        text.append("DATE      :  ").append(now).append("\n");
                        if(mobileName.toLowerCase().contains("sunmi")){
                            sunmiPrinterManager.printSold(BitMapUtils.resizeToPrinterWidth(logo, 384), title, text, status -> {
                                if(!status){
                                    new Handler(Looper.getMainLooper()).post(new Runnable() {
                                        @Override
                                        public void run() {
                                            MessageDialog.showError(getContext(), "Erreur d'impression"+"\n"+"Veuillez rééssayer SVP.");
                                        }
                                    });
                                }
                            });
                        }else{
                            try {
                                MobiIotPrinterManager.getInstance().printSold(BitMapUtils.bitmapToBmp(BitMapUtils.resizeToPrinterWidth(logo, 384)), title, text, new MobiIotPrinterManager.MobiIotPrinterStatus() {
                                    @Override
                                    public void printStatusCode(int status) {
                                        if(status != 1){
                                            new Handler(Looper.getMainLooper()).post(new Runnable() {
                                                @Override
                                                public void run() {
                                                    MessageDialog.showError(getContext(), "Erreur d'impression"+"\n"+"Veuillez rééssayer SVP.");
                                                }
                                            });
                                        }
                                    }
                                });
                            } catch (RemoteException e) {
                                throw new RuntimeException(e);
                            }
                        }
                    })
                    .show();
        }catch (SecurityException e){
            MessageDialog.showError(getContext(), "Erreur lors de l'affichage du solde");
        }

    }
}