package com.foxx.androidcast.stats.ui;

/*********************************************************************
 * SessionStatsAnalyzerActivity.java
 * Created at: Tue 19 May 2026 19:43:06 +0200
 * Updated at: Wed 20 May 2026 15:17:13 +0200 by Anton Afanasyeu <a.afanasieff@gmail.com>
 * Commit: 5d8e82d2e60a21fff3138d2a394ee4e8b4c6dcb8
 * class SessionStatsAnalyzerActivity
 * Contributors:
 *    - Anton Afanasyeu <a.afanasieff@gmail.com> (2 commits, 189 lines)
 *    - Cursor Agent (project assistant)
 * Digest: SHA256	cd3ef931583d3213d5aaba08bbc5859ceaba1c5f0bc10c1fff11d4d65b65aed4
**********************************************************************/
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.foxx.androidcast.AppPreferences;
import com.foxx.androidcast.CastLocaleHelper;
import com.foxx.androidcast.CastThemeHelper;
import com.foxx.androidcast.R;
import com.foxx.androidcast.stats.SessionStatsStore;
import com.foxx.androidcast.util.CastBackgroundExecutor;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/** In-app viewer for saved session_send_* / session_recv_* cast statistics. */
public class SessionStatsAnalyzerActivity extends AppCompatActivity
        implements SessionStatsListAdapter.Listener {
    private SessionLineChartView lineChart;
    private SessionBarChartView barChart;
    private TextView summaryText;
    private TextView emptyText;
    private View detailPanel;
    private SessionRecord primarySelection;
    private SessionLineChartView.Metric chartMetric = SessionLineChartView.Metric.BITRATE;
    private List<SessionRecord> chartSessions = new ArrayList<>();

    @Override
    protected void attachBaseContext(android.content.Context newBase) {
        super.attachBaseContext(CastLocaleHelper.attach(newBase));
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        CastThemeHelper.applyTheme(this);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_session_stats_analyzer);
        setTitle(R.string.session_stats_title);

        if (getSupportActionBar() != null) {
            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        }

        emptyText = findViewById(R.id.text_session_stats_empty);
        detailPanel = findViewById(R.id.panel_session_detail);
        summaryText = findViewById(R.id.text_session_summary);
        lineChart = findViewById(R.id.chart_session_lines);
        barChart = findViewById(R.id.chart_session_bars);
        RecyclerView list = findViewById(R.id.list_sessions);

        SessionStatsListAdapter adapter = new SessionStatsListAdapter(this);
        list.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
        list.setAdapter(adapter);

        setupMetricRadios();
        findViewById(R.id.btn_share_session).setOnClickListener(v -> shareSelected());
        findViewById(R.id.btn_refresh_sessions).setOnClickListener(v -> reloadSessions(adapter));

        TextView hint = findViewById(R.id.text_chart_interaction_hint);
        if (hint != null) {
            hint.setText(R.string.session_stats_chart_hint);
        }

        if (!AppPreferences.isGrabSessionStats(this)) {
            Toast.makeText(this, R.string.session_stats_disabled_hint, Toast.LENGTH_LONG).show();
        }
        reloadSessions(adapter);
    }

    @Override
    public boolean onSupportNavigateUp() {
        finish();
        return true;
    }

    private void setupMetricRadios() {
        RadioGroup group = findViewById(R.id.radio_group_metric);
        if (group == null) {
            return;
        }
        group.setOnCheckedChangeListener((g, id) -> {
            if (id == R.id.radio_metric_loss) {
                chartMetric = SessionLineChartView.Metric.LOSS;
            } else if (id == R.id.radio_metric_fps) {
                chartMetric = SessionLineChartView.Metric.ENCODE_FPS;
            } else {
                chartMetric = SessionLineChartView.Metric.BITRATE;
            }
            refreshChart();
        });
    }

    private void reloadSessions(SessionStatsListAdapter adapter) {
        emptyText.setVisibility(View.VISIBLE);
        detailPanel.setVisibility(View.GONE);
        CastBackgroundExecutor.execute(() -> {
            List<SessionRecord> loaded = new ArrayList<>();
            List<File> files = SessionStatsStore.listSessionFiles(this);
            for (File f : files) {
                try {
                    loaded.add(SessionStatsParser.load(f));
                } catch (Exception ignored) {
                }
            }
            runOnUiThread(() -> {
                adapter.setItems(loaded);
                boolean has = !loaded.isEmpty();
                emptyText.setVisibility(has ? View.GONE : View.VISIBLE);
                emptyText.setText(has ? "" : getString(R.string.session_stats_empty));
                detailPanel.setVisibility(has ? View.VISIBLE : View.GONE);
            });
        });
    }

    @Override
    public void onSelectionChanged(List<SessionRecord> selected) {
        chartSessions = selected != null ? selected : new ArrayList<>();
        primarySelection = chartSessions.isEmpty() ? null : chartSessions.get(0);
        refreshChart();
        if (primarySelection != null) {
            summaryText.setText(buildSummary(primarySelection));
            barChart.setSession(primarySelection);
        }
    }

    private void refreshChart() {
        lineChart.setSessions(chartSessions, chartMetric);
    }

    private String buildSummary(SessionRecord r) {
        StringBuilder sb = new StringBuilder();
        sb.append(r.role).append(" · ").append(r.transport).append('\n');
        sb.append(String.format(Locale.US, "Duration: %d ms\n", r.durationMs));
        if (!r.videoCodec.isEmpty()) {
            sb.append("Video: ").append(r.videoCodec).append('\n');
        }
        if (!r.resolution.isEmpty()) {
            sb.append("Resolution: ").append(r.resolution).append('\n');
        }
        sb.append(String.format(Locale.US, "Disrupts: %d  idle timeouts: %d\n",
                r.disruptCount, r.idleTimeoutCount));
        if (r.networkSamples > 0) {
            sb.append(String.format(Locale.US, "Avg RTT: %d ms  loss: %.3f  bitrate: %d kbps  fps: %.1f\n",
                    r.avgRttMs, r.avgLossRatio, r.avgVideoBitrateKbps, r.avgEncodeFps));
        }
        SessionRecord.ProtectionStats p = r.protection;
        sb.append(String.format(Locale.US, "Protection: %s (FEC=%s NACK=%s)\n",
                p.mode, p.fecEnabled, p.nackEnabled));
        sb.append(String.format(Locale.US, "Samples in chart: %d", r.samples.size()));
        return sb.toString().trim();
    }

    private void shareSelected() {
        if (primarySelection == null) {
            return;
        }
        File dir = SessionStatsStore.statsDir(this);
        File file = new File(dir, primarySelection.fileName);
        if (!file.isFile()) {
            Toast.makeText(this, R.string.session_stats_share_failed, Toast.LENGTH_SHORT).show();
            return;
        }
        Uri uri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", file);
        Intent send = new Intent(Intent.ACTION_SEND);
        send.setType("application/json");
        send.putExtra(Intent.EXTRA_STREAM, uri);
        send.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        startActivity(Intent.createChooser(send, getString(R.string.session_stats_share)));
    }
}
