package kr.co.compcareworker.Util.Adapter;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.github.mikephil.charting.charts.BarLineChartBase;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.charts.PieChart;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.data.PieData;
import com.github.mikephil.charting.data.PieDataSet;
import com.github.mikephil.charting.data.PieEntry;
import com.github.mikephil.charting.formatter.PercentFormatter;
import com.github.mikephil.charting.formatter.ValueFormatter;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;

import java.net.URLEncoder;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

import kr.co.compcareworker.Activity.WebviewAct;
import kr.co.compcareworker.Data.ArrayItem;
import kr.co.compcareworker.Data.Company.Machine.MachineItem;
import kr.co.compcareworker.Data.Company.Machine.Product.MonitoringData;
import kr.co.compcareworker.MyApplication;
import kr.co.compcareworker.R;
import kr.co.compcareworker.Util.Api.ApiClient;
import kr.co.compcareworker.Util.Common;
import kr.co.compcareworker.Util.ConvertTimeZone;
import kr.co.compcareworker.Util.CustomView.MonitoringDialog;

public class EnterpriseProdRecyclerAdapter extends RecyclerView.Adapter<EnterpriseProdRecyclerAdapter.ItemViewHolder> {
    private Context context;
    private Handler handler, hdr;

    private String agency_id, user_id, pt_idx, cp_idx, mc_idx;
    private TextView lastDt;
    private ArrayList<Entry> entries = new ArrayList<>();
    private ArrayList<Float> value_list = new ArrayList<>();
    private ArrayList<String> time_list = new ArrayList<>();

    private Handler chart_handler = new Handler();
    private String temperature_time;
    private Float temperature;

    // adapter에 들어갈 list 입니다.
    private ArrayList<MachineItem> items = new ArrayList<>();

    EnterpriseProdRecyclerAdapter(Context context, String agency_id, String user_id) {
        this.context = context;
        this.agency_id = agency_id;
        this.user_id = user_id;

        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);

                if (msg.what == -1) {
                    Toast.makeText(context, msg.obj.toString().replace("\"", ""), Toast.LENGTH_SHORT).show();

                } else if (msg.what == 1) {
                    String url = msg.getData().getString("url");
                    if (url.equals("proc_machine_onoff")) {
                        JsonElement element = new JsonParser().parse(msg.obj.toString());
                        JsonObject result_item = element.getAsJsonObject();
                        Log.d("1234", result_item.toString());
                        if (result_item.get("resultItem").getAsJsonObject().get("result").getAsString().equals("Y")) {
                            String status;
                            if (result_item.get("arrayItem").getAsString().equals("MM")) {
                                status = "Staring(" + result_item.get("arrayItem").getAsString() + ")";
                            } else {
                                status = "Stop(" + result_item.get("arrayItem").getAsString() + ")";
                            }
                            //Toast.makeText(context, status, Toast.LENGTH_LONG).show();
                        } else {
                            //Toast.makeText(context, result_item.get("resultItem").getAsJsonObject().get("message").getAsString(), Toast.LENGTH_LONG).show();
                        }
                    }
                }
            }
        };
    }

    @NonNull
    @Override
    public EnterpriseProdRecyclerAdapter.ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        // LayoutInflater를 이용하여 전 단계에서 만들었던 item.xml을 inflate 시킵니다.
        // return 인자는 ViewHolder 입니다.
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_enterprise_prod, parent, false);
        return new EnterpriseProdRecyclerAdapter.ItemViewHolder(view);
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public void onBindViewHolder(@NonNull EnterpriseProdRecyclerAdapter.ItemViewHolder holder, final int position) {
        // Item을 하나, 하나 보여주는(bind 되는) 함수입니다.
        holder.onBind(items.get(position));
        holder.seq.setText(position + 1 + ".");

        init_Handler(holder);

        chart_handler.postDelayed(new Runnable() {
            @Override
            public void run() {

                Get_ChartData();

                if (!MyApplication.finishMonitoring) {
                    chart_handler.postDelayed(this, 3000);

                } else {
                    chart_handler.removeMessages(0);
                }

                if (temperature != null) {

                    setLineChart(holder.currentLC, holder.currentTV, value_list);
                    setPieChart(Float.parseFloat(Common.getInstance().valueConvert("" + temperature)), 120, holder.temperaturePC);
                    setPieChart(Float.parseFloat(Common.getInstance().valueConvert("" + temperature)), 100, holder.pressurePC);
                }

            }

        }, 0);

        holder.currentLC.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MonitoringDialog dialog = new MonitoringDialog(context, agency_id, pt_idx, cp_idx, mc_idx, "current", items.get(position).getMcIotMac(), items.get(position));
                dialog.show();
            }
        });

        holder.temperaturePC.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    MonitoringDialog dialog = new MonitoringDialog(context, agency_id, pt_idx, cp_idx, mc_idx, "temperature", items.get(position).getMcIotMac(), items.get(position));
                    dialog.show();
                }

                return true;
            }
        });

        holder.pressurePC.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    MonitoringDialog dialog = new MonitoringDialog(context, agency_id, pt_idx, cp_idx, mc_idx, "pressure", items.get(position).getMcIotMac(), items.get(position));
                    dialog.show();
                }

                return true;
            }
        });

        holder.max_settingTV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
    }

    @Override
    public int getItemCount() {
        // RecyclerView의 총 개수 입니다.
        return items.size();
    }

    public void addItem(ArrayList<MachineItem> data) {
        // 외부에서 item을 추가시킬 함수입니다.
        items.clear();
        items.addAll(data);
        notifyDataSetChanged();
    }

    public void clearItem() {
        items.clear();
        notifyDataSetChanged();
    }


    // RecyclerView의 핵심인 ViewHolder 입니다.
    // 여기서 subView를 setting 해줍니다.
    class ItemViewHolder extends RecyclerView.ViewHolder {

        TextView seq, name, spec;
        //Switch sw;
        ToggleButton sw;
        LinearLayout progressFrame;
        RelativeLayout time;
        ProgressBar progress;
        TextView min, max, qr;

//        String pt_idx, cp_idx, mc_idx;

        int viewWidth;
        String temp_time;

        LinearLayout graphLL;
        LineChart currentLC;
        PieChart temperaturePC, pressurePC;
        TextView temperature_maxTV, pressure_maxTV, currentTV;
        RelativeLayout temperatureRL, pressureRL;
        TextView max_settingTV;

        ItemViewHolder(View itemView) {
            super(itemView);
            seq = itemView.findViewById(R.id.seq);
            name = itemView.findViewById(R.id.name);
            spec = itemView.findViewById(R.id.spec);
            qr = itemView.findViewById(R.id.qr);
            time = itemView.findViewById(R.id.time);
            sw = itemView.findViewById(R.id.sw);
            progressFrame = itemView.findViewById(R.id.progressFrame);
            progress = itemView.findViewById(R.id.progress);
            min = itemView.findViewById(R.id.min);
            max = itemView.findViewById(R.id.max);
            lastDt = itemView.findViewById(R.id.lastDt);

            graphLL = itemView.findViewById(R.id.graphLL);
            currentLC = itemView.findViewById(R.id.currentLC);
            temperaturePC = itemView.findViewById(R.id.temperaturePC);
            pressurePC = itemView.findViewById(R.id.pressurePC);
            temperature_maxTV = itemView.findViewById(R.id.temperature_maxTV);
            pressure_maxTV = itemView.findViewById(R.id.pressure_maxTV);
            currentTV = itemView.findViewById(R.id.currentTV);
            temperatureRL = itemView.findViewById(R.id.temperatureRL);
            pressureRL = itemView.findViewById(R.id.pressureRL);
            max_settingTV = itemView.findViewById(R.id.max_settingTV);

            time.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String incodeUrl = URLEncoder.encode("https://" + agency_id + ".compcare.co.kr/setting/serial/write_machine/" + mc_idx + "?cp_idx=" + cp_idx + "&pt_idx=" + pt_idx);
                    Intent intent = new Intent(context, WebviewAct.class);
                    intent.putExtra("title", "보유기종 관리");
                    intent.putExtra("url", "https://" + agency_id + ".compcare.co.kr/api/web/" + user_id + "/?url=" + incodeUrl);
                    context.startActivity(intent);
                }
            });

            sw.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String del_flag;
                    if (sw.isChecked()) {

                        del_flag = "MM";
                        graphLL.setVisibility(View.VISIBLE);

                    } else {

                        del_flag = "STOP";
                        graphLL.setVisibility(View.GONE);
                    }

                    HashMap<String, String> data = new HashMap<>();
                    data.put("mc_idx", mc_idx);
                    data.put("del_flag", del_flag);
                    new ApiClient(data, "proc_machine_onoff", handler);
                }
            });
        }

        void onBind(MachineItem data) {
            name.setText(data.getProductData().getPdTtypeStr());
            spec.setText(data.getProductData().getPdName());

            lastDt.setText("교환정보 없음");

//            if (data.getMcExchangedt().toString().equals("")){
//                lastDt.setText("교환정보 없음");
//            }else{
//                lastDt.setText(data.getMcExchangedt().toString());
//            }


            if (data.getQrCode() == null) {
                qr.setText("[QR 없음]");
            } else {
                qr.setText("[" + data.getQrCode().toString() + "]");
            }

            sw.setOnCheckedChangeListener(null);

            if (data.getDelFlag().equals("MM")) {
                data.setSelected(true);
                progressFrame.setVisibility(View.VISIBLE);
                graphLL.setVisibility(View.VISIBLE);
                //sw.setChecked(true);
            } else {
                data.setSelected(false);
                progressFrame.setVisibility(View.GONE);
                graphLL.setVisibility(View.GONE);
            }

            sw.setChecked(data.isSelected());

            sw.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    data.setSelected(isChecked);
                    if (isChecked) {
                        data.setDelFlag("MM");
                        graphLL.setVisibility(View.VISIBLE);
                        progressFrame.setVisibility(View.VISIBLE);

                    } else {
                        data.setDelFlag("STOP");
                        graphLL.setVisibility(View.GONE);
                        progressFrame.setVisibility(View.GONE);
                    }
                }
            });

            int runningTime = Integer.parseInt(Common.getInstance().isNullToZero(data.getMcRunningtime()));
            int cycle = Integer.parseInt(Common.getInstance().isNullToZero(data.getMcCycle()));
            double per;
            if (cycle == 0 && runningTime != 0) {
                per = 100;
            } else {
                per = ((double) runningTime / (double) cycle) * 100;
            }
            //Log.d("1234", "per = " + per + "/runningTime = " + runningTime + "/cycle = " + cycle);
            //progress.setMin(runningTime);
            progress.setMax(100);
            progress.setProgress((int) per);

            min.setText(runningTime + "");
            max.setText(cycle + "");
            //Log.d("1234", progress.getMax() + "");

            /*if (data.getSubIdx1() == null){
                progressFrame.setVisibility(View.GONE);
            } else *//*if (data.getMcCycle().equals("0")){
                progressFrame.setVisibility(View.GONE);
            } else{

            }*/

            pt_idx = data.getPtIdx();
            cp_idx = data.getCpIdx();
            mc_idx = data.getMcIdx();

        }
    }

    private void init_Handler(ItemViewHolder holder) {
        hdr = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);

                if (msg.what == -1) {
                    Toast.makeText(context, msg.obj.toString().replace("\"", ""), Toast.LENGTH_SHORT).show();

                } else if (msg.what == 1) {
                    String url = msg.getData().getString("url");
                    Log.e("init_Handler", url.toString());

                    ArrayItem<MonitoringData> monitoringArray;
                    MonitoringData monitoringData;

                    if (url.equals("proc_monitoring")) {
                        JsonElement element = new JsonParser().parse(msg.obj.toString());
                        JsonObject result_item = element.getAsJsonObject();
                        monitoringArray = new Gson().fromJson(result_item, new TypeToken<ArrayItem<MonitoringData>>() {
                        }.getType());

                        if (monitoringArray.isSuccess()) {

                            int size = monitoringArray.size();

                            value_list.clear();
                            time_list.clear();
                            holder.temp_time = "";

                            for (int i = 0; i < size; i++) {

                                monitoringData = monitoringArray.getArrayitem().get(i);

                                if (monitoringData.getTempPt100() != null && monitoringData.getTime() != null) {

                                    ConvertTimeZone timeZone = new ConvertTimeZone();
                                    String str = "";

                                    try {
                                        str = timeZone.convertKoreaTimeS(monitoringData.getTime());
                                    } catch (ParseException e) {
                                        e.printStackTrace();
                                    }

                                    temperature_time = str.substring(11);
                                    temperature = Float.parseFloat(monitoringData.getTempPt100());
                                    String temp_value = Common.getInstance().valueConvert(monitoringData.getTempPt100());

                                    value_list.add(Float.parseFloat(temp_value));
                                    time_list.add(temperature_time);
                                }
                            }
                        }
                    }
                }
            }
        };
    }

    private void setLineChart(LineChart lineChart, TextView currentTV, ArrayList<Float> number) {

        lineChart.clear();
        entries.clear();

        Float[] number_sort = new Float[number.size()];

        for (int i = 0; i < number.size(); i++) {

            entries.add(new Entry(i, number.get(i)));
            number_sort[i] = number.get(i);
        }

        currentTV.setText(number.get(number.size() - 1) + "A");

        String line_color = "#455579";

        LineDataSet lineDataSet = new LineDataSet(entries, null);
        lineDataSet.setLineWidth(1);
        lineDataSet.setCircleRadius(1);

        lineDataSet.setCircleColor(Color.parseColor("#368dd2"));
        lineDataSet.setColor(Color.parseColor(line_color));
        lineDataSet.setDrawCircleHole(false);
        lineDataSet.setDrawCircles(false);
        lineDataSet.setDrawHorizontalHighlightIndicator(false);
        lineDataSet.setDrawHighlightIndicators(false);
        lineDataSet.setDrawValues(false);

        LineData lineData = new LineData(lineDataSet);
        lineChart.setData(lineData);

        XAxis xAxis = lineChart.getXAxis();
        ValueFormatter xAxisFormatter = new TimeAxisValueFormatter(lineChart);

        xAxis.setGranularityEnabled(true);
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setTextColor(Color.BLACK);
        xAxis.setGridDashedLine(new DashPathEffect(new float[]{3, 3}, 0));
        xAxis.setLabelCount(3, true);
        xAxis.setValueFormatter(xAxisFormatter);
        xAxis.setAxisLineColor(Color.BLACK);
        xAxis.setGranularity(0f);

        Arrays.sort(number_sort);

        YAxis yLAxis = lineChart.getAxisLeft();
        yLAxis.setTextColor(Color.BLACK);
        yLAxis.setAxisMaximum(number_sort[number_sort.length - 1] + 0.1f);
        yLAxis.setAxisMinimum(number_sort[0] - 0.1f);
        yLAxis.setDrawAxisLine(false);
        yLAxis.setDrawGridLines(false);
        yLAxis.setAxisLineColor(Color.BLACK);
        yLAxis.setLabelCount(5, true);

        YAxis yRAxis = lineChart.getAxisRight();
        yRAxis.setDrawLabels(false);
        yRAxis.setDrawAxisLine(false);
        yRAxis.setDrawGridLines(false);

        lineChart.setVisibleXRange(305, 305);
        lineChart.getAxisRight().setEnabled(false);
        lineChart.getLegend().setEnabled(false);
        lineChart.setDoubleTapToZoomEnabled(false);
        lineChart.setDrawGridBackground(false);
        lineChart.setScaleXEnabled(false);
        lineChart.setScaleYEnabled(false);

        lineChart.setDescription(null);
        lineChart.getAxisRight().setEnabled(false);
        lineChart.setTouchEnabled(true);
        lineChart.invalidate();

    }

    public class TimeAxisValueFormatter extends ValueFormatter {

        TimeAxisValueFormatter(BarLineChartBase<?> chart) {
        }

        @Override
        public String getFormattedValue(float value) {

            String set_time;
            int half = time_list.size() / 2;
            int last = time_list.size() - 1;
            int match = (int) value;
            if (match == 0) {

                set_time = time_list.get(0);

            } else if (match == half - 1 || match == half || match == half + 1) {

                set_time = time_list.get(half);

            } else if (match == last) {

                set_time = time_list.get(last);

            } else {
                set_time = "";
            }

            return set_time;
        }
    }

    private void setPieChart(float count, float range, PieChart pieChart) {

        pieChart.setMaxAngle(180f); // HALF CHART
        pieChart.setRotationAngle(180f);

        ArrayList<PieEntry> values = new ArrayList<>();

        values.add(new PieEntry(count, (Drawable) null));
        values.add(new PieEntry(range - count, (Drawable) null));

        PieDataSet dataSet = new PieDataSet(values, "");
        dataSet.setSliceSpace(1);
        dataSet.setSelectionShift(0f);

        if (pieChart.getId() == R.id.temperaturePC) {

            if (count > 100) {
                dataSet.setColors(Color.parseColor("#CC2828"), Color.parseColor("#e2ded3"));
            } else {
                dataSet.setColors(Color.parseColor("#368dd2"), Color.parseColor("#e2ded3"));
            }
            pieChart.setCenterText(count + " ℃");

        } else {

            if (count > 70) {
                dataSet.setColors(Color.parseColor("#CC2828"), Color.parseColor("#e2ded3"));
            } else {
                dataSet.setColors(Color.parseColor("#49a6a6"), Color.parseColor("#e2ded3"));
            }
            String pressure = String.format("%.1f", count / 10);
            pieChart.setCenterText(pressure + " Bar");
        }

        pieChart.setDrawHoleEnabled(true);
        pieChart.setHoleColor(Color.WHITE);
        pieChart.setExtraOffsets(10f, -30f, 10f, -95f);
        pieChart.setHoleRadius(60f);
        pieChart.setTransparentCircleRadius(65f);
        pieChart.setUsePercentValues(true);
        pieChart.getDescription().setEnabled(false);
        pieChart.setRotationEnabled(false);
        pieChart.setDrawCenterText(true);
        pieChart.setCenterTextSize(20);
        pieChart.setCenterTextOffset(0, -10f);
        pieChart.setCenterTextColor(Color.BLACK);
        pieChart.setEntryLabelColor(Color.WHITE);
        pieChart.getLegend().setEnabled(false);

        PieData data = new PieData(dataSet);
        data.setValueFormatter(new PercentFormatter());
        data.setDrawValues(false);

        pieChart.setData(data);
        pieChart.invalidate();
    }

    private void Get_ChartData() {
        HashMap<String, String> data = new HashMap<>();
        new ApiClient(data, "proc_monitoring", hdr);
    }
}
