package com.hdrdevs.turnosxpress;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.ConsoleMessage;
import android.webkit.JavascriptInterface;
import android.webkit.PermissionRequest;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import android.os.Environment;
import android.util.Base64;
import android.content.ContentValues;
import android.provider.MediaStore;
import android.content.ContentResolver;

public class MainActivity extends AppCompatActivity {

    private static final int LOGIN_REQUEST_CODE = 1;
    private WebView webView;
    private ValueCallback<Uri[]> fileChooserCallback;

    private String tokenResult;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        tokenResult = "";

        // For Android Emulator, use 10.0.2.2 to access localhost on your development machine.
        // If testing on a physical device, replace 10.0.2.2 with your development machine's actual local IP address.
        //Uri home = Uri.parse("http://10.0.2.2:3021");
        Uri home = Uri.parse("https://turnosxpress.com.ar");

        webView = new WebView(this);
        webView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT));

        WebSettings settings = webView.getSettings();
        settings.setAllowContentAccess(true);
        settings.setAllowFileAccess(true);
        settings.setDatabaseEnabled(true);
        settings.setDomStorageEnabled(true);
        settings.setGeolocationEnabled(true);
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setJavaScriptEnabled(true);
        settings.setLoadsImagesAutomatically(true);
        settings.setMediaPlaybackRequiresUserGesture(false);
        settings.setSupportMultipleWindows(true);

        webView.setWebContentsDebuggingEnabled(true);

        webView.addJavascriptInterface(new WebAppInterface(), "Android");

        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView vw, WebResourceRequest request) {
                if (request.getUrl().toString().contains(home.getHost())) {
                    vw.loadUrl(request.getUrl().toString());
                } else {
                    Intent intent = new Intent(Intent.ACTION_VIEW, request.getUrl());
                    vw.getContext().startActivity(intent);
                }

                return true;
            }
        });
        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onPermissionRequest(final PermissionRequest request) {
                request.grant(request.getResources());
            }

            @Override
            public boolean onConsoleMessage(ConsoleMessage cm) {
                Log.d("WEBVIEW", cm.message() + " (line "
                        + cm.lineNumber() + " of " + cm.sourceId() + ")");
                return true;
            }

            @Override
            public boolean onShowFileChooser(WebView vw, ValueCallback<Uri[]> filePathCallback,
                                             FileChooserParams fileChooserParams) {
                if (fileChooserCallback != null) {
                    fileChooserCallback.onReceiveValue(null);
                }
                fileChooserCallback = filePathCallback;

                Intent selectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
                selectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
                selectionIntent.setType("*/*");

                Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
                chooserIntent.putExtra(Intent.EXTRA_INTENT, selectionIntent);
                startActivityForResult(chooserIntent, 0);

                return true;
            }


        });
        webView.setOnKeyListener((v, keyCode, event) ->
        {
            WebView vw = (WebView) v;
            if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK && vw.canGoBack()) {
                vw.goBack();

                return true;
            }

            return false;
        });
        webView.setDownloadListener((uri, userAgent, contentDisposition, mimetype, contentLength) -> handleURI(uri));
        webView.setOnLongClickListener(v -> {
            handleURI(((WebView) v).getHitTestResult().getExtra());

            return true;
        });

        webView.loadUrl(home.toString());

        setContentView(webView);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);

        if (requestCode == LOGIN_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                tokenResult = intent.getStringExtra("token");
                //Log.w("MainActivity", "Received token: " + token);
                webView.evaluateJavascript("javascript:window.dispatchEvent(new CustomEvent('androidTokenReceived', { detail: '" + tokenResult + "' }));", null);
            } else {
                tokenResult = "";
                // Google login was cancelled or failed. Do nothing or log a message.
                // The 'intent' might be null here, so avoid accessing it.
                //android.util.Log.w("MainActivity", "Google login cancelled or failed.");
            }
        } else if (requestCode == 0) { // This is for the file chooser
            if (fileChooserCallback != null) {
                Uri result = (intent == null || resultCode != RESULT_OK) ? null : intent.getData();
                fileChooserCallback.onReceiveValue(result != null ? new Uri[]{result} : null);
                fileChooserCallback = null;
            }
        }
    }

    private void handleURI(String uri) {
        if (uri != null) {
            Intent i = new Intent(Intent.ACTION_VIEW);
            i.setData(Uri.parse(uri.replaceFirst("^blob:", "")));

            startActivity(i);
        }
    }

    public class WebAppInterface {
        @JavascriptInterface
        public void startGoogleLogin() {
            Intent intent = new Intent(MainActivity.this, LoginActivity.class);
            startActivityForResult(intent, LOGIN_REQUEST_CODE);
        }

        @JavascriptInterface
        public String getLoginToken() {
            //Log.w("getLoginToken", "getLoginToken token: " + tokenResult);
            return tokenResult;
        }

        @JavascriptInterface
        public void savePdf(String base64Data, String filename) {
            try {
                byte[] pdfAsBytes = Base64.decode(base64Data, 0);
                boolean isSaved = false;

                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
                    ContentResolver resolver = getContentResolver();
                    ContentValues contentValues = new ContentValues();
                    contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, filename);
                    contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "application/pdf");
                    contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS);

                    Uri uri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues);

                    if (uri != null) {
                        try (OutputStream outputStream = resolver.openOutputStream(uri)) {
                            outputStream.write(pdfAsBytes);
                            isSaved = true;
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                } else {
                    File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
                    File file = new File(path, filename);

                    try (FileOutputStream os = new FileOutputStream(file)) {
                        os.write(pdfAsBytes);
                        isSaved = true;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                if (isSaved) {
                    runOnUiThread(() -> Toast.makeText(MainActivity.this, "PDF guardado en Descargas", Toast.LENGTH_LONG).show());
                } else {
                    runOnUiThread(() -> Toast.makeText(MainActivity.this, "Error al guardar el PDF", Toast.LENGTH_LONG).show());
                }

            } catch (Exception e) {
                e.printStackTrace();
                runOnUiThread(() -> Toast.makeText(MainActivity.this, "Error: " + e.getMessage(), Toast.LENGTH_LONG).show());
            }
        }
    }
}
