package com.unibuy.smartdevice.ui.devs.electric;

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

import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;

import com.unibuy.smartdevice.FragmentAbstract;
import com.unibuy.smartdevice.MyApp;
import com.unibuy.smartdevice.controller.DevDigitalDisplayController;
import com.unibuy.smartdevice.controller.DevElectricController;
import com.unibuy.smartdevice.databinding.FragmentElectricBinding;
import com.unibuy.smartdevice.devices.SlotField;
import com.unibuy.smartdevice.exception.ErrorCode;
import com.unibuy.smartdevice.exception.LogsIOException;
import com.unibuy.smartdevice.exception.LogsParseException;
import com.unibuy.smartdevice.exception.LogsSecurityException;
import com.unibuy.smartdevice.exception.LogsSettingEmptyException;
import com.unibuy.smartdevice.exception.LogsUnsupportedOperationException;
import com.unibuy.smartdevice.external.HttpAPI;
import com.unibuy.smartdevice.structure.SlotStructure;
import com.unibuy.smartdevice.tools.HandlerMain;
import com.unibuy.smartdevice.tools.HandlerMainScheduler;
import com.unibuy.smartdevice.tools.ToastHandlerMain;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class ElectricFragment extends FragmentAbstract {
    public enum Option {
        TOAST(0),
        SHIPPED_PRODUCT(1),
        BUY_ON_THREAD_TIMER_TASK(2),
        ADD_PRODUCT_OPEN(3),
        ADD_PRODUCT_CLOSE(4),
        CLOSE_SLOT(5)
        ;

        private int option;

        public int getOption() {
            return option;
        }

        Option(int option) {
            this.option = option;
        }
    }

    public static final Map<Integer, Option> optionMap = new HashMap<>();
    static {
        for (Option option : Option.values()) {
            optionMap.put(option.getOption(), option);
        }
    }

    private FragmentElectricBinding binding;
    private List<SlotStructure> slotList;
    private static BuyOnScheduler buyOnScheduler;
    private RecyclerElectricBuyListAdpter recyclerElectricBuyListAdpter;
    private HttpAPI httpAPI;
    private boolean isChangeUI = false;

    @Override
    protected String setName() {
        return "桌遊空間出租";
    }

    @Override
    protected Context setCtx() {
        return getContext();
    }

    @Override
    protected Class<?> setCls() {
        return getClass();
    }

    @Override
    protected HandlerMain setHandlerMain() {
        return new ToastHandlerMain(getCtx(), getLogs()) {

            @Override
            protected void execute(Context context, int commandCode, String message) {
                Option option = optionMap.get(commandCode);

                switch (option) {
                    case TOAST:
                        super.execute(context, commandCode, message);
                        break;
                    case SHIPPED_PRODUCT:
                        if (!isChangeUI) {
                            isChangeUI = true;
                            recyclerElectricBuyListAdpter.notifyItemRangeChanged(0, slotList.size());
                            isChangeUI = false;
                        }
                        break;
                    case BUY_ON_THREAD_TIMER_TASK:
                        try {
                            DevDigitalDisplayController devDigitalDisplayController = new DevDigitalDisplayController(this);
                            DevElectricController devElectricController = new DevElectricController(this);

                            JSONArray electricInfoByJsonArray = new JSONArray();

                            for (int index=0; index<slotList.size(); index++) {
                                JSONObject electricData = new JSONObject();

                                SlotStructure slotStructure = slotList.get(index);
                                int slot = slotStructure.getSlot();
                                electricData.put("cid", String.valueOf(slot));
                                electricData.put("pid", String.valueOf(slotStructure.getProduct().getProductID()));

                                if (slotStructure.getOtherData().has("timeExpired")) {
                                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                                    Date now = new Date();
                                    Date timeEpiredDate = new Date();

                                    if (slotStructure.getOtherData().has("timeExpired")) {
                                        try {
                                            timeEpiredDate = sdf.parse(slotStructure.getOtherData().getString("timeExpired"));
                                        } catch (JSONException | ParseException e) {
//                                            exception(context, ErrorCode.JSON_FORMAT_ERROR, e.getLocalizedMessage());
                                            getLogs().warning(e);
                                        }
                                    }
                                    long diffInMillis = timeEpiredDate.getTime() - now.getTime();
                                    electricData.put("status", diffInMillis>0?"1":"0");

                                    long diffInSeconds = diffInMillis / 1000; // 總秒數

                                    electricData.put("num", String.valueOf(diffInSeconds));
                                    int day = (int) (diffInSeconds / 3600 / 24);        //天
                                    int hours = (int) (diffInSeconds / 3600 % 24);        // 小時
                                    int minutes = (int) ((diffInSeconds % 3600) / 60); // 剩下的分鐘
                                    int seconds = (int) (diffInSeconds % 60);          // 剩下的秒數
                                    int hours2 = (int) (diffInSeconds / 3600);        // 小時

                                    if (diffInMillis > 0) {
                                        devDigitalDisplayController.devPut(slot, hours2, minutes, seconds);
                                        devElectricController.devSwitch(slot - 1, hours2, minutes+2, seconds);
                                    } else {
                                        devDigitalDisplayController.devPut(slot, 0, 0, 0);
                                        devElectricController.devSwitch(slot - 1, 0, 0, 0);

                                        //關閉資料
                                        slotStructure.getOtherData().remove("timeExpired");
                                    }
                                } else {
                                    devDigitalDisplayController.devPut(slot, 0, 0, 0);
                                    devElectricController.devSwitch(slot - 1, 0, 0, 0);
                                    electricData.put("status", "0");
                                    electricData.put("num", "0");
                                }

                                if (slotStructure.isLock()) {
                                    electricData.put("status", "4");
                                }

                                electricInfoByJsonArray.put(electricData);
                            }

                            getHandler().postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    devDigitalDisplayController.start();

                                    try {
                                        Thread.sleep(300);
                                    } catch (InterruptedException e) {
                                        throw new RuntimeException(e);
                                    }

                                    devElectricController.start();

                                    try {
                                        Thread.sleep(300);
                                    } catch (InterruptedException e) {
                                        throw new RuntimeException(e);
                                    }

                                    if (!MyApp.getInstance().isMachineBusy()) {
                                        try {
                                            httpAPI.reportElectricInfo(electricInfoByJsonArray);
                                        } catch (LogsParseException | LogsSettingEmptyException e) {
                                            getLogs().warning(e);
                                        }
                                    }
                                }
                            }, 200);
                        } catch (LogsIOException | LogsSecurityException | LogsUnsupportedOperationException e) {
                            if (buyOnScheduler != null && !buyOnScheduler.isShutdown()) {
                                buyOnScheduler.shutdown();
                            }
                            getLogs().warning(e);
                        } catch (JSONException e) {
                            getLogs().warning(e);
                        }

                        break;
                    case ADD_PRODUCT_OPEN:
                        break;
                    case ADD_PRODUCT_CLOSE:
                        break;
                    case CLOSE_SLOT:
                        getLogs().info("close slot:" + MyApp.getInstance().getCloseSlot());
                        SlotStructure slot = slotList.get(MyApp.getInstance().getCloseSlot()-1);
                        slot.getOtherData().remove("timeExpired");
                        this.start("ElectricFragment", Option.BUY_ON_THREAD_TIMER_TASK.getOption(), "change");

                        break;
                }
            }
        };
    }

    public ElectricFragment() {
        super(null);  // 確保有無參數構造函數
    }

    public ElectricFragment(HandlerMain srcHandlerMain) {
        super(srcHandlerMain);
    }

    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        ElectricViewModel electricViewModel = new ViewModelProvider(this).get(ElectricViewModel.class);
        binding = FragmentElectricBinding.inflate(inflater, container, false);
        View root = binding.getRoot();
        httpAPI = new HttpAPI(getHandlerMain());
        isChangeUI = false;

        slotList = new ArrayList<>();

        recyclerElectricBuyListAdpter = new RecyclerElectricBuyListAdpter(this, slotList, getHandlerMain());
        binding.recyclerBuy.setAdapter(recyclerElectricBuyListAdpter);
        binding.recyclerBuy.setLayoutManager(new GridLayoutManager(getContext(), 3));

        if (buyOnScheduler != null) {
            buyOnScheduler.shutdown();
        }

//        buyOnScheduler = new BuyOnScheduler(getHandlerMain());
//        buyOnScheduler.start(1000L, 30000L, TimeUnit.MILLISECONDS);

        for (int i=0; i<MyApp.getInstance().getSlotList(SlotField.ELECTRIC.getField()).size(); i++) {
            SlotStructure slot = MyApp.getInstance().getSlotList(SlotField.ELECTRIC.getField()).get(i);
            if (!slot.getProduct().getProductID().isEmpty() && !slot.getProduct().getProductName().isEmpty() && slot.getProduct().getSellingPrice() > 0) {
                slotList.add(slot);
            }
        }

        if (!slotList.isEmpty()) recyclerElectricBuyListAdpter.notifyItemInserted(slotList.size() -1);

        if (isUseStartOnSwitchFragment()) {
            startOnSwitchFragment();
            setUseStartOnSwitchFragment(false);
        }

        return root;
    }

    @Override
    public void startOnSwitchFragment() {

    }

    @Override
    public void stopOnSwitchFragment() {
    }

    public class BuyOnScheduler extends HandlerMainScheduler {

        public BuyOnScheduler(HandlerMain handlerMain) {
            super(handlerMain);
        }

        @Override
        protected HandlerMain setHandlerMain() {
            return getSrcHandlerMain();
        }

        @Override
        protected void execute(HandlerMain handlerMain) {
            handlerMain.start(getClass().getSimpleName(), Option.BUY_ON_THREAD_TIMER_TASK.getOption(), "start");
        }

        @Override
        protected Class<?> setCls() {
            return getClass();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onStop() {
        super.onStop();
    }

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