/*
 * Copyright (C) 2026 SHX VPN
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 */

package org.strongswan.android.ui

import android.content.Intent
import android.content.pm.PackageManager
import android.os.Bundle
import android.widget.Toast
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.ViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.strongswan.android.R
import org.strongswan.android.data.LogContentProvider
import org.strongswan.android.logic.CharonVpnService
import org.strongswan.android.ui.compose.SecondaryScaffold
import org.strongswan.android.ui.compose.theme.ShxTheme
import java.io.BufferedReader
import java.io.File
import java.io.FileReader

class LogActivity : AppCompatActivity()
{
	override fun onCreate(savedInstanceState: Bundle?)
	{
		super.onCreate(savedInstanceState)
		enableEdgeToEdge()
		setContent {
			ShxTheme {
				LogScreen(onBack = { finish() }, onSend = { sendLog() })
			}
		}
	}

	private fun sendLog()
	{
		val logfile = File(filesDir, CharonVpnService.LOG_FILE)
		if (!logfile.exists() || logfile.length() == 0L)
		{
			Toast.makeText(this, R.string.empty_log, Toast.LENGTH_SHORT).show()
			return
		}
		var version = ""
		try
		{
			version = packageManager.getPackageInfo(packageName, 0).versionName ?: ""
		}
		catch (_: PackageManager.NameNotFoundException)
		{
		}
		val intent = Intent(Intent.ACTION_SEND)
		intent.putExtra(Intent.EXTRA_EMAIL, arrayOf(MainActivity.CONTACT_EMAIL))
		intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.log_mail_subject, version))
		intent.type = "text/plain"
		intent.putExtra(Intent.EXTRA_STREAM, LogContentProvider.createContentUri())
		startActivity(Intent.createChooser(intent, getString(R.string.send_log)))
	}
}

class LogViewModel : ViewModel()
{
	private val _lines = MutableStateFlow<List<String>>(emptyList())
	val lines: StateFlow<List<String>> = _lines

	private var started = false

	fun start(file: File)
	{
		if (started) return
		started = true
		viewModelScope.launch(Dispatchers.IO) {
			val buffer = ArrayList<String>()
			var reader: BufferedReader? = null
			try
			{
				reader = if (file.exists()) BufferedReader(FileReader(file)) else null
				while (isActive)
				{
					val line = reader?.readLine()
					if (line == null)
					{
						if (buffer.isNotEmpty())
						{
							val batch = buffer.toList()
							buffer.clear()
							withContext(Dispatchers.Main) {
								_lines.value = _lines.value + batch
							}
						}
						delay(800)
					}
					else
					{
						buffer.add(line)
						if (buffer.size >= 50)
						{
							val batch = buffer.toList()
							buffer.clear()
							withContext(Dispatchers.Main) {
								_lines.value = _lines.value + batch
							}
						}
					}
				}
			}
			catch (_: Exception)
			{
			}
			finally
			{
				try { reader?.close() } catch (_: Exception) {}
			}
		}
	}
}

@Composable
private fun LogScreen(onBack: () -> Unit, onSend: () -> Unit, viewModel: LogViewModel = viewModel())
{
	val context = LocalContext.current
	val lines by viewModel.lines.collectAsStateWithLifecycle()
	val listState = rememberLazyListState()

	LaunchedEffect(Unit) {
		viewModel.start(File(context.filesDir, CharonVpnService.LOG_FILE))
	}
	LaunchedEffect(lines.size) {
		if (lines.isNotEmpty())
		{
			listState.scrollToItem(lines.lastIndex)
		}
	}

	SecondaryScaffold(
		title = stringResource(R.string.log_title),
		onBack = onBack,
		actions = {
			IconButton(onClick = onSend) {
				Icon(Icons.Default.Share, contentDescription = stringResource(R.string.send_log))
			}
		},
	) { padding ->
		if (lines.isEmpty())
		{
			Text(
				stringResource(R.string.empty_log),
				modifier = Modifier.padding(padding).padding(24.dp),
				color = MaterialTheme.colorScheme.onSurfaceVariant,
			)
		}
		else
		{
			LazyColumn(
				state = listState,
				modifier = Modifier.fillMaxSize().padding(padding).padding(horizontal = 12.dp),
			) {
				items(lines.size) { index ->
					val line = lines[index]
					val isError = line.contains(" ERROR ", ignoreCase = false)
					Text(
						line,
						style = MaterialTheme.typography.bodySmall.copy(
							fontSize = 12.sp,
							fontFamily = FontFamily.Monospace,
						),
						color = if (isError) MaterialTheme.colorScheme.error
						else MaterialTheme.colorScheme.onSurface,
						modifier = Modifier.padding(vertical = 2.dp),
					)
				}
			}
		}
	}
}
