package com.app.simplitend.welcome.welcomepatient.mvvm;

import android.content.Context;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModel;

import com.app.simplitend.R;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.welcome.welcomepatient.mvvm.models.PatientData;

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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import okhttp3.MediaType;
import okhttp3.RequestBody;

public class WelcomeViewModel extends ViewModel {

    private final WelcomeRepository welcomeRepository;

    // Patient data watcher
    private PatientData patientData;

    public WelcomeViewModel(){
        this.welcomeRepository = WelcomeRepository.getWelcomeRepository();
    }

    public void registerPatient(@NonNull WelcomeContracts.RegisterPatientContract registerPatientContract){
        Map<String, RequestBody> body = new HashMap<>();

        PatientData patientData = getPatientData();

        RequestBody first_name_body = RequestBody.create(patientData.first_name, MediaType.parse("text/plain;charset=utf-8") );
        body.put("full_name", first_name_body);

        RequestBody dob_body = RequestBody.create(patientData.date_of_birth, MediaType.parse("text/plain;charset=utf-8") );
        body.put("date_of_birth", dob_body);

        RequestBody phone_number_body = RequestBody.create(patientData.phone_number, MediaType.parse("text/plain;charset=utf-8") );
        body.put("contact_number", phone_number_body);

        RequestBody email_body = RequestBody.create(patientData.email, MediaType.parse("text/plain;charset=utf-8") );
        body.put("email", email_body);

        RequestBody street_body = RequestBody.create(patientData.address_line1, MediaType.parse("text/plain;charset=utf-8") );
        body.put("street", street_body);

        RequestBody town_body = RequestBody.create(patientData.city, MediaType.parse("text/plain;charset=utf-8") );
        body.put("town", town_body);

        RequestBody state_body = RequestBody.create(patientData.state, MediaType.parse("text/plain;charset=utf-8") );
        body.put("state", state_body);

        RequestBody country_body = RequestBody.create(patientData.country, MediaType.parse("text/plain;charset=utf-8") );
        body.put("country", country_body);

        RequestBody zip_code_body = RequestBody.create(patientData.post_code, MediaType.parse("text/plain;charset=utf-8") );
        body.put("zip_code", zip_code_body);

        RequestBody pin_body = RequestBody.create(patientData.pin_code, MediaType.parse("text/plain;charset=utf-8") );
        body.put("pin_code", pin_body);

        RequestBody cpin_body = RequestBody.create(patientData.c_pin_code, MediaType.parse("text/plain;charset=utf-8") );
        body.put("cpin_code", cpin_body);

        RequestBody lat_body = RequestBody.create(patientData.lat, MediaType.parse("text/plain;charset=utf-8") );
        body.put("lat", lat_body);

        RequestBody lng_body = RequestBody.create(patientData.lng, MediaType.parse("text/plain;charset=utf-8") );
        body.put("lng", lng_body);

        RequestBody one_signal_player_id_body = RequestBody.create(patientData.one_signal_player_id, MediaType.parse("text/plain;charset=utf-8") );
        body.put("one_signal_player_id", one_signal_player_id_body);

        RequestBody timezone_body = RequestBody.create(AppUtil.getTimeZone(), MediaType.parse("text/plain;charset=utf-8"));
        body.put("timezone", timezone_body);

        welcomeRepository.registerPatient(body, registerPatientContract);

    }

    public void sendOTPToEmail(String emailAddress,
                               @NonNull WelcomeContracts.SendOTPToEmailCallback otpToEmailCallback){
        welcomeRepository.sendOTPToEmail(emailAddress, otpToEmailCallback);
    }

    public void loginPatient(@NonNull Map<String, RequestBody> credentials,
                             @NonNull WelcomeContracts.RegisterPatientContract loginCallback){

        welcomeRepository.loginPatient(credentials, loginCallback);

    }

    public void verifyOTP(Map<String, RequestBody> body,
                          @NonNull WelcomeContracts.VerifyOTPCallback verifyOTPCallback){
        welcomeRepository.verifyOTP(body, verifyOTPCallback);
    }

    public void updatePin(Map<String, RequestBody> body,
                          @NonNull WelcomeContracts.UpdatePinCallback updatePinCallback){
        welcomeRepository.updatePin(body, updatePinCallback);
    }

    public void verifyEmail(String email_address, WelcomeContracts.VerifyEmailCallBack emailCallBack){
        Map<String, String> body = new HashMap<>();
        body.put("email", email_address);
        welcomeRepository.verifyEmail(body, emailCallBack);
    }

    public synchronized PatientData getPatientData(){

        if (patientData == null){
            patientData = new PatientData();
        }

        return patientData;
    }

    private static final String TAG = "WelcomeViewModel";

    public ArrayList<String> loadCountryCodeDropDown(Context context) {

        ArrayList<String> countryCodeList = new ArrayList<>();

        try {

            String countryCodeStr = readCountryCodes(context);
            JSONArray jsonArray = new JSONArray(countryCodeStr);

            for (int i = 0; i < jsonArray.length(); i++) {

                JSONObject code = jsonArray.getJSONObject(i);

                countryCodeList.add(code.getString("dial_code"));

            }

        } catch (Exception e) {

            // if cannot load all country codes showing only india's dial code
            countryCodeList.add("+91");
            countryCodeList.add("+1");

            Log.e(TAG, "loadCountryCodeDropDown: ", e);
        }

        return countryCodeList;
    }

    public String readCountryCodes(Context context) throws IOException {
        StringBuilder returnString = new StringBuilder();

        InputStream fIn = context.getResources().openRawResource(R.raw.country_code);
        InputStreamReader isr = new InputStreamReader(fIn);
        BufferedReader input = new BufferedReader(isr);

        String line = "";

        while ((line = input.readLine()) != null) {
            returnString.append(line);
        }

        try {
            isr.close();

            if (fIn != null) fIn.close();

            input.close();

        } catch (Exception e) {
            Log.e(TAG, "readCountryCodes: ", e);
        }

        return returnString.toString();
    }

}
