package br.com.detetivesprofissionais.localizacao;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import org.json.JSONObject;

import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {

    private static final int REQ_LOCATION = 1001;
    private static final int REQ_NOTIFICATIONS = 1002;

    private TextView txtDispositivo;
    private TextView txtStatus;
    private TextView txtUltima;
    private Button btnIniciar;
    private Button btnParar;

    private SharedPreferences prefs;
    private String token;
    private String nomeDispositivo;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txtDispositivo = findViewById(R.id.txtDispositivo);
        txtStatus = findViewById(R.id.txtStatus);
        txtUltima = findViewById(R.id.txtUltima);
        btnIniciar = findViewById(R.id.btnIniciar);
        btnParar = findViewById(R.id.btnParar);

        prefs = getSharedPreferences("localizacao", Context.MODE_PRIVATE);

        nomeDispositivo = buildDeviceName();
        token = prefs.getString("token", "");

        if (token == null || token.trim().isEmpty()) {
            token = generateToken();
            prefs.edit().putString("token", token).apply();
        }

        txtDispositivo.setText("Dispositivo: " + nomeDispositivo);

        cadastrarAutomaticamente();

        btnIniciar.setOnClickListener(v -> iniciarFluxoPermissao());
        btnParar.setOnClickListener(v -> pararServico());

        atualizarEstadoBotoes();
    }

    private String buildDeviceName() {
        String fabricante = Build.MANUFACTURER == null ? "" : Build.MANUFACTURER.trim();
        String modelo = Build.MODEL == null ? "" : Build.MODEL.trim();

        if (fabricante.equalsIgnoreCase(modelo)) {
            return modelo;
        }

        return (fabricante + " " + modelo).trim();
    }

    private String generateToken() {
        try {
            String base = UUID.randomUUID().toString() + "-" +
                    System.currentTimeMillis() + "-" +
                    Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);

            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hash = md.digest(base.getBytes("UTF-8"));

            StringBuilder sb = new StringBuilder();

            for (byte b : hash) {
                sb.append(String.format(Locale.US, "%02x", b));
            }

            return sb.toString();

        } catch (Exception e) {
            return UUID.randomUUID().toString().replace("-", "") +
                    UUID.randomUUID().toString().replace("-", "");
        }
    }

    private void cadastrarAutomaticamente() {
        txtStatus.setText("Status: cadastrando aparelho...");

        Map<String, String> dados = new HashMap<>();
        dados.put("token", token);
        dados.put("nome", nomeDispositivo);

        HttpHelper.postForm(
                BuildConfig.BASE_URL + "api/cadastrar_dispositivo.php",
                dados,
                (okHttp, body) -> {
                    boolean okApi = HttpHelper.jsonOk(body);

                    if (okHttp && okApi) {
                        txtStatus.setText("Status: aparelho cadastrado");
                        prefs.edit().putBoolean("cadastrado", true).apply();
                    } else {
                        txtStatus.setText("Status: não foi possível cadastrar");
                    }
                }
        );
    }

    private void iniciarFluxoPermissao() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(
                    this,
                    new String[] {
                            Manifest.permission.ACCESS_FINE_LOCATION,
                            Manifest.permission.ACCESS_COARSE_LOCATION
                    },
                    REQ_LOCATION
            );

            return;
        }

        pedirNotificacaoSeNecessario();
        iniciarServico();
    }

    private void pedirNotificacaoSeNecessario() {
        if (Build.VERSION.SDK_INT >= 33 &&
                ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS)
                        != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(
                    this,
                    new String[] { Manifest.permission.POST_NOTIFICATIONS },
                    REQ_NOTIFICATIONS
            );
        }
    }

    private void iniciarServico() {
        Intent intent = new Intent(this, LocationService.class);
        intent.putExtra("token", token);

        ContextCompat.startForegroundService(this, intent);

        txtStatus.setText("Status: compartilhamento ativo");
        btnIniciar.setEnabled(false);
        btnParar.setEnabled(true);
    }

    private void pararServico() {
        Intent intent = new Intent(this, LocationService.class);
        stopService(intent);

        txtStatus.setText("Status: compartilhamento parado");
        btnIniciar.setEnabled(true);
        btnParar.setEnabled(false);
    }

    private void atualizarEstadoBotoes() {
        boolean ativo = prefs.getBoolean("servico_ativo", false);

        btnIniciar.setEnabled(!ativo);
        btnParar.setEnabled(ativo);

        if (ativo) {
            txtStatus.setText("Status: compartilhamento ativo");
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        String ultima = prefs.getString("ultima_localizacao", "");

        if (ultima != null && !ultima.isEmpty()) {
            txtUltima.setText(ultima);
        }

        atualizarEstadoBotoes();
    }

    @Override
    public void onRequestPermissionsResult(
            int requestCode,
            @NonNull String[] permissions,
            @NonNull int[] grantResults
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        if (requestCode == REQ_LOCATION) {
            if (grantResults.length > 0 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                pedirNotificacaoSeNecessario();
                iniciarServico();

            } else {
                Toast.makeText(
                        this,
                        "A localização precisa ser autorizada para iniciar o compartilhamento.",
                        Toast.LENGTH_LONG
                ).show();
            }
        }
    }
}
