package com.example.submanager

import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import android.content.Context
import android.database.ContentObserver
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.provider.Telephony
import org.json.JSONObject
import java.text.SimpleDateFormat
import java.util.*

class MainActivity: FlutterActivity() {
    private val CHANNEL = "com.submanager/sms"

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when (call.method) {
                "scanSubscriptions" -> {
                    scanSubscriptions(result)
                }
                else -> {
                    result.notImplemented()
                }
            }
        }
    }

    private fun scanSubscriptions(result: MethodChannel.Result) {
        try {
            // 메시지를 임시 저장할 맵
            val messageGroups = mutableMapOf<String, MutableList<Map<String, Any>>>()
            
            val cursor = contentResolver.query(
                Telephony.Sms.CONTENT_URI,
                arrayOf(
                    Telephony.Sms.ADDRESS,
                    Telephony.Sms.BODY,
                    Telephony.Sms.DATE
                ),
                null,
                null,
                "${Telephony.Sms.DATE} DESC"
            )

            cursor?.use {
                while (it.moveToNext()) {
                    val address = it.getString(0)
                    val body = it.getString(1)
                    val date = it.getLong(2)

                    // 구독 관련 키워드로 필터링
                    if (isSubscriptionMessage(body)) {
                        val parsedMessage = parseSubscriptionMessage(body, address, date)
                        if (parsedMessage != null) {
                            val key = "${address}_${parsedMessage["monthlyCost"]}"
                            if (!messageGroups.containsKey(key)) {
                                messageGroups[key] = mutableListOf()
                            }
                            messageGroups[key]?.add(parsedMessage)
                        }
                    }
                }
            }
            
            // 최종 구독 목록
            val subscriptions = mutableListOf<Map<String, Any>>()
            
            // 동일한 발신자와 유사한 금액으로 2회 이상 메시지가 있는 경우만 구독으로 판단
            for ((key, messages) in messageGroups) {
                if (messages.size >= 2) {
                    // 가장 최근 메시지 정보를 사용
                    val latestMessage = messages.first()
                    
                    // 주기성 추가
                    val enhancedMessage = latestMessage.toMutableMap()
                    enhancedMessage["repeatCount"] = messages.size
                    enhancedMessage["isRecurring"] = true
                    
                    // 이전 결제일도 추가
                    if (messages.size > 1) {
                        enhancedMessage["previousPaymentDate"] = messages[1]["nextBillingDate"] ?: ""
                    }
                    
                    subscriptions.add(enhancedMessage)
                }
            }

            result.success(subscriptions)
        } catch (e: Exception) {
            result.error("SMS_SCAN_ERROR", e.message, null)
        }
    }

    private fun isSubscriptionMessage(body: String?): Boolean {
        if (body == null) return false
        val keywords = listOf(
            "구독", "결제", "청구", "요금", "월정액", "정기결제",
            "subscription", "payment", "bill", "fee", "monthly", "recurring"
        )
        return keywords.any { body.contains(it) }
    }

    private fun parseSubscriptionMessage(
        body: String,
        address: String,
        date: Long
    ): Map<String, Any>? {
        try {
            // 서비스명 추출 (예: "넷플릭스", "스포티파이" 등)
            val serviceName = extractServiceName(address, body)

            // 금액 추출 (예: "9,900원", "₩9,900" 등)
            val amount = extractAmount(body)

            // 결제 주기 추출 (예: "월간", "연간" 등)
            val billingCycle = extractBillingCycle(body)

            // 다음 결제일 추출
            val nextBillingDate = extractNextBillingDate(body, date)

            return mapOf(
                "serviceName" to serviceName,
                "monthlyCost" to amount,
                "billingCycle" to billingCycle,
                "nextBillingDate" to nextBillingDate,
                "isRecurring" to false,
                "repeatCount" to 1,
                "sender" to address,
                "messageDate" to formatDate(date)
            )
        } catch (e: Exception) {
            return null
        }
    }

    private fun formatDate(timestamp: Long): String {
        val date = Date(timestamp)
        val formatter = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
        return formatter.format(date)
    }

    private fun extractServiceName(address: String, body: String): String {
        // 주소에서 서비스명 추출 시도
        val addressPattern = Regex("""([가-힣a-zA-Z]+)""")
        val addressMatch = addressPattern.find(address)
        if (addressMatch != null) {
            return addressMatch.value
        }

        // 본문에서 서비스명 추출 시도
        val bodyPattern = Regex("""([가-힣a-zA-Z]+)\s*(구독|결제|청구)""")
        val bodyMatch = bodyPattern.find(body)
        if (bodyMatch != null) {
            return bodyMatch.groupValues[1]
        }

        return "알 수 없는 서비스"
    }

    private fun extractAmount(body: String): Double {
        val pattern = Regex("""(\d{1,3}(?:,\d{3})*)(?:\s*원|\s*₩)""")
        val match = pattern.find(body)
        return if (match != null) {
            match.groupValues[1].replace(",", "").toDouble()
        } else {
            0.0
        }
    }

    private fun extractBillingCycle(body: String): String {
        return when {
            body.contains("월간") || body.contains("월정액") -> "월간"
            body.contains("연간") || body.contains("연정액") -> "연간"
            body.contains("주간") || body.contains("주정액") -> "주간"
            else -> "월간"
        }
    }

    private fun extractNextBillingDate(body: String, messageDate: Long): String {
        val datePattern = Regex("""(\d{4})[년/.-](\d{1,2})[월/.-](\d{1,2})일?""")
        val match = datePattern.find(body)
        if (match != null) {
            val (year, month, day) = match.destructured
            return "$year-${month.padStart(2, '0')}-${day.padStart(2, '0')}"
        }

        // 날짜를 찾을 수 없는 경우, 메시지 날짜로부터 1개월 후를 반환
        val calendar = Calendar.getInstance()
        calendar.timeInMillis = messageDate
        calendar.add(Calendar.MONTH, 1)
        return SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(calendar.time)
    }
}
