package kr.co.compcarecompany.Util.CustomView;

import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.DatePicker;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

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.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.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.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;

import kr.co.compcarecompany.Data.ArrayItem;
import kr.co.compcarecompany.Data.Product.MachineItem;
import kr.co.compcarecompany.MyApplication;
import kr.co.compcarecompany.R;
import kr.co.compcarecompany.Util.Adapter.AirLeakAdapter;
import kr.co.compcarecompany.Util.Api.ApiClient;
import kr.co.compcarecompany.Util.Common;
import kr.co.compcarecompany.Util.ConvertTimeZone;

public class AirLeakDialog extends Dialog {

    private Context context;
    private RecyclerView air_leakRV;
    private LineChart air_leakLC;
    private TextView air_leak_dayTV, air_leak_weekTV, air_leak_monthTV, select_dayTV, air_leak_rangeTV;
    private LinearLayout select_dayLL;
    //    private Spinner select_weekSN, select_monthSN, select_yearSN;
    private ProgressBar air_leakPB;
    private String cp_idx, mc_idx, date_type = "day", start_date, end_date;
    private int this_year, this_week, this_month, total_week, today;
    private Handler hdr;
    private AirLeakAdapter adapter;
    private DatePickerDialog.OnDateSetListener callbackMethod;
    private ArrayItem<MachineItem> machine_array;
    private ArrayAdapter<String> year_adapter;

    private LinearLayout select_weekLL, select_monthLL;
    private Spinner week_select_yearSN, week_select_monthSN, week_select_weekSN, month_select_yearSN, month_select_monthSN;

    public AirLeakDialog(@NonNull Context context, String cp_idx, String mc_idx) {
        super(context);
        this.context = context;
        this.cp_idx = cp_idx;
        this.mc_idx = mc_idx;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.dlg_air_leak);

        MyApplication.stop_ui_change = true;

        air_leakLC = findViewById(R.id.air_leakLC);
        air_leak_dayTV = findViewById(R.id.air_leak_dayTV);
        air_leak_weekTV = findViewById(R.id.air_leak_weekTV);
        air_leak_monthTV = findViewById(R.id.air_leak_monthTV);
        select_dayLL = findViewById(R.id.select_dayLL);
        select_dayTV = findViewById(R.id.select_dayTV);
//        select_weekSN = findViewById(R.id.select_weekSN);
//        select_monthSN = findViewById(R.id.select_monthSN);
        air_leakRV = findViewById(R.id.air_leakRV);
        air_leakPB = findViewById(R.id.air_leakPB);
        air_leak_rangeTV = findViewById(R.id.air_leak_rangeTV);
//        select_yearSN = findViewById(R.id.select_yearSN);


        select_weekLL = findViewById(R.id.select_weekLL);
        week_select_yearSN = findViewById(R.id.week_select_yearSN);
        week_select_monthSN = findViewById(R.id.week_select_monthSN);
        week_select_weekSN = findViewById(R.id.week_select_weekSN);
        select_monthLL = findViewById(R.id.select_monthLL);
        month_select_yearSN = findViewById(R.id.month_select_yearSN);
        month_select_monthSN = findViewById(R.id.month_select_monthSN);

        //스피너 초기화
        Calendar calendar = Calendar.getInstance();
        this_year = calendar.get(Calendar.YEAR);
        this_month = calendar.get(Calendar.MONTH) + 1;
        this_week = calendar.get(Calendar.WEEK_OF_MONTH);
        today = calendar.get(Calendar.DATE);

        start_date = this_year + "-" + Common.getInstance().fill_zero(this_month) + "-" + Common.getInstance().fill_zero(today);
        end_date = this_year + "-" + Common.getInstance().fill_zero(this_month) + "-" + Common.getInstance().fill_zero(today);
        select_dayTV.setText(start_date);

        int day = calendar.getActualMaximum(Calendar.DATE);
        calendar.set(calendar.get(Calendar.YEAR), this_month - 1, day);
        total_week = calendar.get(Calendar.WEEK_OF_MONTH);

        ArrayAdapter<CharSequence> week_adapter;
        if (total_week < 5) {
            week_adapter = ArrayAdapter.createFromResource(getContext(), R.array.select_week_4, R.layout.custom_spinner_item_purple);
        } else if (total_week == 5) {
            week_adapter = ArrayAdapter.createFromResource(getContext(), R.array.select_week_5, R.layout.custom_spinner_item_purple);
        } else {
            week_adapter = ArrayAdapter.createFromResource(getContext(), R.array.select_week_6, R.layout.custom_spinner_item_purple);
        }
        week_select_weekSN.setAdapter(week_adapter);
        week_select_weekSN.setSelection(this_week - 1);

        ArrayAdapter<CharSequence> month_adapter = ArrayAdapter.createFromResource(getContext(), R.array.month, R.layout.custom_spinner_item_purple);
        week_select_monthSN.setAdapter(month_adapter);
        week_select_monthSN.setSelection(this_month - 1);

        month_select_monthSN.setAdapter(month_adapter);
        month_select_monthSN.setSelection(this_month - 1);

        year_adapter = new ArrayAdapter<>(getContext(), R.layout.custom_spinner_item_purple);

        for (int i = 2020; i <= calendar.get(Calendar.YEAR); i++) {
            year_adapter.add(i + "년");
        }

        week_select_yearSN.setAdapter(year_adapter);
        week_select_yearSN.setSelection(year_adapter.getCount() - 1);

        month_select_yearSN.setAdapter(year_adapter);
        month_select_yearSN.setSelection(year_adapter.getCount() - 1);

        Display display = getWindow().getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);

        Window thisWindow = this.getWindow();

        int x = (int) (size.x * 0.95f);
        int y = (int) (size.y * 0.95f);

        thisWindow.setLayout(x, y);

        init_Handler();
        init_Listener();
        Get_LeakData();
    }

    @Override
    protected void onStop() {
        super.onStop();
        MyApplication.stop_ui_change = false;
    }

    void Get_LeakData() {
        //차트데이터
        air_leakPB.setVisibility(View.VISIBLE);
        HashMap<String, String> data = new HashMap<>();
        data.put("cp_idx", cp_idx);
        data.put("mc_idx", mc_idx);
        data.put("type", date_type);

        if (!TextUtils.isEmpty(start_date))
            data.put("start_date", start_date);

        if (!TextUtils.isEmpty(end_date))
            data.put("end_date", end_date);

        Log.d("데이터 확인~~~@@@@", data.toString());

        new ApiClient(data, "proc_get_air_leak", hdr);
    }

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

                String url = msg.getData().getString("url");
                Log.e("init_Handler", url.toString());

                if (url.equals("proc_get_air_leak")) {
                    JsonElement element = new JsonParser().parse(msg.obj.toString());
                    JsonObject result_item = element.getAsJsonObject();

                    Log.d("가져왔닝@@@@", result_item.toString());
                    machine_array = new Gson().fromJson(result_item, new TypeToken<ArrayItem<MachineItem>>() {
                    }.getType());

                    if (machine_array.isSuccess()) {

                        float std_value = Float.parseFloat(machine_array.get(0).getMcAirLeakStd());
                        float range = Float.parseFloat(machine_array.get(0).getMcAirLeakRange());
                        float min_value = std_value - range;
                        air_leak_rangeTV.setVisibility(View.VISIBLE);
                        air_leak_rangeTV.setText("정상범위 : " + std_value + "Bar ~ " + min_value + "Bar");
                        adapter = new AirLeakAdapter(getContext(), date_type);
                        air_leakRV.setAdapter(adapter);
                        setLineChart();
                        adapter.addItems(machine_array.getArrayitem());

                    } else {
                        Toast.makeText(getContext(), "해당시간에 저장된 데이터가 없습니다\n시간을 조정하여 데이터를 조회해보세요", Toast.LENGTH_SHORT).show();
                        air_leak_rangeTV.setVisibility(View.GONE);
                        air_leakLC.clear();
                        if (adapter != null) adapter.clearItems();
                    }
                    air_leakPB.setVisibility(View.GONE);
                }
            }
        };
    }

    private void init_Listener() {

        if (air_leakPB.getVisibility() == View.VISIBLE) {
            Toast.makeText(context, "데이터를 가져오는 중입니다...", Toast.LENGTH_SHORT).show();
            return;
        }

        air_leak_dayTV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //일간 차트
                date_type = "day";
                air_leak_dayTV.setBackgroundResource(R.drawable.bg_round_purple_except_right);
                air_leak_dayTV.setTextColor(Color.WHITE);
                air_leak_monthTV.setBackgroundResource(R.drawable.bg_round_white_except_left);
                air_leak_monthTV.setTextColor(Color.parseColor("#9134A1"));
                air_leak_weekTV.setBackgroundResource(R.color.white);
                air_leak_weekTV.setTextColor(getContext().getResources().getColor(R.color.color_bg_purple));

                Calendar calendar = Calendar.getInstance();
                this_year = calendar.get(Calendar.YEAR);
                this_month = calendar.get(Calendar.MONTH) + 1;
                this_week = calendar.get(Calendar.WEEK_OF_MONTH);
                today = calendar.get(Calendar.DATE);

                start_date = this_year + "-" + Common.getInstance().fill_zero(this_month) + "-" + Common.getInstance().fill_zero(today);
                end_date = this_year + "-" + Common.getInstance().fill_zero(this_month) + "-" + Common.getInstance().fill_zero(today);
                select_dayTV.setText(start_date);

                select_dayLL.setVisibility(View.VISIBLE);
                select_monthLL.setVisibility(View.GONE);
                select_weekLL.setVisibility(View.GONE);

                Get_LeakData();
            }
        });

        air_leak_weekTV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //주간 차트
                date_type = "week";
                air_leak_dayTV.setBackgroundResource(R.drawable.bg_round_white_except_right);
                air_leak_dayTV.setTextColor(Color.parseColor("#9134A1"));
                air_leak_monthTV.setBackgroundResource(R.drawable.bg_round_white_except_left);
                air_leak_monthTV.setTextColor(Color.parseColor("#9134A1"));
                air_leak_weekTV.setBackgroundResource(R.color.color_bg_purple);
                air_leak_weekTV.setTextColor(getContext().getResources().getColor(R.color.white));

                select_dayLL.setVisibility(View.GONE);
                select_monthLL.setVisibility(View.GONE);
                select_weekLL.setVisibility(View.VISIBLE);

                week_select_monthSN.setOnItemSelectedListener(null);
                week_select_weekSN.setOnItemSelectedListener(null);
                week_select_yearSN.setOnItemSelectedListener(year_listener);

                week_select_yearSN.setSelection(year_adapter.getCount() - 1);
                week_select_monthSN.setSelection(this_month - 1);
                week_select_weekSN.setSelection(this_week - 1);

                getWeekData();

                week_select_monthSN.setOnItemSelectedListener(month_listener);
                week_select_weekSN.setOnItemSelectedListener(week_listener);
            }
        });

        air_leak_monthTV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //월간 차트
                date_type = "month";
                air_leak_dayTV.setBackgroundResource(R.drawable.bg_round_white_except_right);
                air_leak_dayTV.setTextColor(Color.parseColor("#9134A1"));
                air_leak_weekTV.setBackgroundResource(R.color.white);
                air_leak_weekTV.setTextColor(getContext().getResources().getColor(R.color.color_bg_purple));
                air_leak_monthTV.setBackgroundResource(R.drawable.bg_round_purple_except_left);
                air_leak_monthTV.setTextColor(Color.WHITE);

                select_dayLL.setVisibility(View.GONE);
                select_weekLL.setVisibility(View.GONE);
                select_monthLL.setVisibility(View.VISIBLE);

                month_select_monthSN.setOnItemSelectedListener(null);
                month_select_yearSN.setOnItemSelectedListener(year_listener);

                month_select_yearSN.setSelection(year_adapter.getCount() - 1);
                month_select_monthSN.setSelection(this_month - 1);

                getMonthData(this_month);

                month_select_monthSN.setOnItemSelectedListener(month_listener);
            }
        });

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

                DatePickerDialog dialog = new DatePickerDialog(getContext(), callbackMethod, this_year, this_month - 1, today);
                dialog.getDatePicker().setMaxDate(Calendar.getInstance().getTimeInMillis());
                dialog.show();
            }
        });

        callbackMethod = new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {

                int month = monthOfYear + 1;

                this_year = year;
                this_month = month;
                today = dayOfMonth;

                start_date = this_year + "-" + Common.getInstance().fill_zero(this_month) + "-" + Common.getInstance().fill_zero(today);
                end_date = this_year + "-" + Common.getInstance().fill_zero(this_month) + "-" + Common.getInstance().fill_zero(today);
                select_dayTV.setText(start_date);
                Get_LeakData();
            }
        };
    }

    AdapterView.OnItemSelectedListener year_listener = new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            if (date_type.equals("week"))
                this_year = Integer.parseInt(week_select_yearSN.getSelectedItem().toString().substring(0, 4));
            else
                this_year = Integer.parseInt(month_select_yearSN.getSelectedItem().toString().substring(0, 4));
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    };

    AdapterView.OnItemSelectedListener month_listener = new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            Calendar calendar = Calendar.getInstance();
            if (this_year == calendar.get(Calendar.YEAR) && position + 1 > this_month) {
                Common.getInstance().toastShow(context, "현재보다 미래의 일자는 선택할 수 없습니다.");
                if (date_type.equals("week"))
                    week_select_monthSN.setSelection(this_month - 1);
                else
                    month_select_monthSN.setSelection(this_month - 1);
                return;
            }
            if (date_type.equals("month"))
                getMonthData(position);
            else getWeekData();
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    };

    AdapterView.OnItemSelectedListener week_listener = new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            Calendar calendar = Calendar.getInstance();
            if (this_year == calendar.get(Calendar.YEAR) && this_month == calendar.get(Calendar.MONTH) && position + 1 > this_week) {
                Common.getInstance().toastShow(context, "현재보다 미래의 일자는 선택할 수 없습니다.");
                week_select_weekSN.setSelection(this_week - 1);
                return;
            }
            getWeekData();
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    };

    void getWeekData() {
        try {
            String first = Common.getInstance().getDateOfWeek2(this_year, week_select_monthSN.getSelectedItemPosition() + 1, week_select_weekSN.getSelectedItemPosition() + 1, "first");
            String last = Common.getInstance().getDateOfWeek2(this_year, week_select_monthSN.getSelectedItemPosition() + 1, week_select_weekSN.getSelectedItemPosition() + 1, "last");

            start_date = first;
            end_date = last;
            Get_LeakData();

        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    void getMonthData(int position) {
        try {
            String first = Common.getInstance().getDateOfMonth2(this_year, position + 1, "first");
            String last = Common.getInstance().getDateOfMonth2(this_year, position + 1, "last");

            start_date = first;
            end_date = last;
            Get_LeakData();

        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    private void setLineChart() {

        ArrayList<Entry> entries = new ArrayList<>();

        for (int i = 0; i < machine_array.size(); i++) {
            entries.add(new Entry(i, Float.parseFloat(machine_array.get(i).getMcAirLeakValue())));
        }

        String line_color = "#82bb6b";

        LineDataSet lineDataSet = new LineDataSet(entries, null);
        lineDataSet.setLineWidth(1);
        lineDataSet.setDrawFilled(false);
        lineDataSet.setCircleColor(Color.parseColor("#F7A400"));
        lineDataSet.setColor(Color.parseColor(line_color));
        lineDataSet.setDrawCircleHole(false);
        lineDataSet.setCircleRadius(2f);
        lineDataSet.setDrawCircles(true);
        lineDataSet.setDrawHorizontalHighlightIndicator(false);
        lineDataSet.setDrawHighlightIndicators(false);
        lineDataSet.setDrawValues(false);

        LineData lineData = new LineData(lineDataSet);
        air_leakLC.setData(lineData);
        air_leakLC.invalidate();

        XAxis xAxis = air_leakLC.getXAxis();
        xAxis.setAxisLineColor(Color.WHITE);
        xAxis.setAxisLineWidth(1f);
        xAxis.setYOffset(5f);
        xAxis.setGranularityEnabled(true);
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setTextColor(Color.WHITE);
        xAxis.setTextSize(8f);

        air_leakLC.setScaleXEnabled(false);
        air_leakLC.setScaleYEnabled(false);

        xAxis.setLabelCount(machine_array.size(), true);
        xAxis.setAxisMinimum(0);
        xAxis.setAxisMaximum(machine_array.size() - 1);

        xAxis.setGridDashedLine(new DashPathEffect(new float[]{3, 3}, 0));
        ValueFormatter xAxisFormatter = new AirLeakDialog.TimeAxisValueFormatter(air_leakLC);
        xAxis.setValueFormatter(xAxisFormatter);

        YAxis yLAxis = air_leakLC.getAxisLeft();
        yLAxis.setTextColor(Color.WHITE);
        yLAxis.setAxisLineColor(Color.WHITE);
        yLAxis.setTextSize(11f);
        yLAxis.setDrawGridLines(true);
        yLAxis.setAxisMinimum(0f);
        yLAxis.setAxisMaximum(10f);

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

        CustomMarkerView marker = new CustomMarkerView(context, R.layout.custom_marker, machine_array.getArrayitem(), "pressure1", date_type);
        marker.setChartView(air_leakLC);
        air_leakLC.setMarker(marker);

        air_leakLC.getAxisRight().setEnabled(false);
        air_leakLC.getLegend().setEnabled(false);
        air_leakLC.setDoubleTapToZoomEnabled(false);
        air_leakLC.setDrawGridBackground(false);

        air_leakLC.setDescription(null);
        air_leakLC.getAxisRight().setEnabled(false);
        air_leakLC.notifyDataSetChanged();
        air_leakLC.fitScreen();

        air_leakLC.invalidate();
    }

    public class TimeAxisValueFormatter extends ValueFormatter {

        BarLineChartBase<?> chart;

        TimeAxisValueFormatter(BarLineChartBase<?> chart) {
            this.chart = chart;
        }

        @Override
        public String getFormattedValue(float value) {

            ConvertTimeZone timeZone = new ConvertTimeZone();
            String time = "";
            int match = (int) value;

            if (match > -1 && match < machine_array.size()) {
                try {
                    if (TextUtils.isEmpty(date_type) || (date_type.equals("day"))) {
                        time = timeZone.convertKoreaTimeS(machine_array.get(match).getTime());
                        time = time.substring(11, 16);

                    } else if (date_type.equals("week") || date_type.equals("month")) {
                        time = timeZone.convertKoreaTimeD(machine_array.get(match).getTime());
                        time = time.substring(8);
                    }

                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
            return time;
        }
    }
}
