package tw.local.botrates

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.net.HttpURLConnection
import java.net.URL
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

private const val URL_CSV = "https://rate.bot.com.tw/xrt/flcsv/0/day"
private val TARGETS = listOf("USD" to "美元", "JPY" to "日幣", "EUR" to "歐元")

data class Rate(val code: String, val name: String, val rate: Double)

private fun fetchRates(): List<Rate> {
    val conn = (URL(URL_CSV).openConnection() as HttpURLConnection).apply {
        connectTimeout = 10_000
        readTimeout = 10_000
        setRequestProperty("User-Agent", "Mozilla/5.0 bot_rates")
    }
    val body = conn.inputStream.bufferedReader().use { it.readText() }
        .trimStart('\uFEFF')

    val out = mutableListOf<Rate>()
    body.lines().drop(1).forEach { line ->
        val cols = line.split(",")
        if (cols.size < 14) return@forEach
        val code = cols[0].trim()
        val pair = TARGETS.firstOrNull { it.first == code } ?: return@forEach
        val v = cols[13].trim().toDoubleOrNull() ?: return@forEach
        out.add(Rate(code, pair.second, v))
    }
    return out.sortedBy { r -> TARGETS.indexOfFirst { it.first == r.code } }
}

private fun parseAmount(s: String): Double? =
    s.filter { it != ',' && !it.isWhitespace() }.takeIf { it.isNotEmpty() }?.toDoubleOrNull()

private fun formatTwd(v: Double): String {
    val rounded = kotlin.math.round(v * 100.0) / 100.0
    return "%,.2f".format(rounded)
}

private fun formatTwdRaw(v: Double): String =
    "%.2f".format(kotlin.math.round(v * 100.0) / 100.0)

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MaterialTheme {
                App()
            }
        }
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun App() {
    val scope = rememberCoroutineScope()
    val context = LocalContext.current

    var rates by remember { mutableStateOf<List<Rate>>(emptyList()) }
    val amounts = remember {
        mutableStateMapOf<String, String>().apply {
            TARGETS.forEach { put(it.first, "100") }
        }
    }
    var loading by remember { mutableStateOf(false) }
    var error by remember { mutableStateOf<String?>(null) }
    var fetchedAt by remember { mutableStateOf<String?>(null) }

    fun load() {
        if (loading) return
        loading = true
        error = null
        scope.launch {
            try {
                val r = withContext(Dispatchers.IO) { fetchRates() }
                if (r.isEmpty()) {
                    error = "解析結果為空"
                } else {
                    rates = r
                    fetchedAt = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US)
                        .format(Date())
                }
            } catch (e: Exception) {
                error = e.message ?: "載入失敗"
            } finally {
                loading = false
            }
        }
    }

    LaunchedEffect(Unit) { load() }

    Scaffold(
        topBar = { TopAppBar(title = { Text("台銀 即期賣出") }) }
    ) { padding ->
        Column(
            modifier = Modifier
                .padding(padding)
                .padding(16.dp)
                .fillMaxSize()
        ) {
            Text(
                "輸入外幣金額，下方顯示台幣換算",
                fontSize = 12.sp,
                color = Color.Gray
            )
            Spacer(Modifier.height(12.dp))

            val display = rates.ifEmpty {
                TARGETS.map { Rate(it.first, it.second, Double.NaN) }
            }

            display.forEachIndexed { idx, r ->
                if (idx > 0) {
                    HorizontalDivider(Modifier.padding(vertical = 8.dp))
                }
                RateRow(
                    rate = r,
                    amount = amounts[r.code] ?: "",
                    onAmountChange = { amounts[r.code] = it },
                    onCopy = { raw ->
                        val cm = context.getSystemService(Context.CLIPBOARD_SERVICE)
                            as ClipboardManager
                        cm.setPrimaryClip(ClipData.newPlainText("TWD", raw))
                        Toast.makeText(context, "已複製 $raw", Toast.LENGTH_SHORT).show()
                    }
                )
            }

            Spacer(Modifier.height(16.dp))
            Row(verticalAlignment = Alignment.CenterVertically) {
                val status = when {
                    error != null -> "載入失敗：$error"
                    loading -> "載入中…"
                    fetchedAt != null -> "更新時間：$fetchedAt"
                    else -> ""
                }
                Text(
                    status,
                    fontSize = 11.sp,
                    color = if (error != null) Color(0xFFB91C1C) else Color.Gray,
                    modifier = Modifier.weight(1f)
                )
                Button(onClick = { load() }, enabled = !loading) {
                    Text("重新整理")
                }
            }
        }
    }
}

@Composable
private fun RateRow(
    rate: Rate,
    amount: String,
    onAmountChange: (String) -> Unit,
    onCopy: (String) -> Unit
) {
    val rateText = if (rate.rate.isNaN()) "--" else "%.4f".format(rate.rate)
    val parsed = parseAmount(amount)
    val twd = if (parsed != null && !rate.rate.isNaN()) parsed * rate.rate else null
    val twdText = twd?.let { "NT$ ${formatTwd(it)}" } ?: "NT$ --"

    Column(modifier = Modifier.fillMaxWidth()) {
        Row(verticalAlignment = Alignment.CenterVertically) {
            Column(Modifier.width(110.dp)) {
                Text(
                    "${rate.name} ${rate.code}",
                    fontWeight = FontWeight.Bold,
                    fontSize = 14.sp
                )
                Text(
                    rateText,
                    fontSize = 12.sp,
                    fontFamily = FontFamily.Monospace,
                    color = Color(0xFF0F766E)
                )
            }
            Spacer(Modifier.width(8.dp))
            OutlinedTextField(
                value = amount,
                onValueChange = onAmountChange,
                keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
                singleLine = true,
                modifier = Modifier.fillMaxWidth(),
                textStyle = TextStyle(fontFamily = FontFamily.Monospace)
            )
        }
        Spacer(Modifier.height(6.dp))
        Row(
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.End,
            modifier = Modifier.fillMaxWidth()
        ) {
            Text(
                twdText,
                modifier = Modifier.weight(1f),
                fontWeight = FontWeight.Bold,
                fontSize = 16.sp,
                color = Color(0xFFB45309),
                fontFamily = FontFamily.Monospace
            )
            Button(
                onClick = { twd?.let { onCopy(formatTwdRaw(it)) } },
                enabled = twd != null,
                contentPadding = PaddingValues(horizontal = 14.dp, vertical = 4.dp)
            ) {
                Text("複製", fontSize = 12.sp)
            }
        }
    }
}
