package com.example.p3

import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import androidx.activity.result.ActivityResult
import com.example.core.model.PaymentResultEntity
import com.example.core.model.PaymentResultStatus
import com.example.p3.models.IapAccountSplit
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class IapPosService @Inject constructor(
    private val context: Context
) {
    private val gson = Gson()

    fun isPosAppInstalled(packageName: String = "ir.co.pna.pos"): Boolean {
        return try {
            context.packageManager.getPackageInfo(packageName, 0)
            true
        } catch (e: PackageManager.NameNotFoundException) {
            false
        }
    }

    fun startPurchase(
        amount: Long,
        billNo: String? = null,
        additionalData: String? = null,
        swipeCardTimeoutMs: Int = 30000,
        receiptType: String = "1",
        packageName: String = "ir.co.pna.pos"
    ): Intent {
        val payload = mutableMapOf<String, Any>(
            "AndroidPosMessageHeader" to "@@PNA@@",
            "ECRType" to "1",
            "Amount" to amount.toString(),
            "TransactionType" to "00",
            "SwipeCardTimeout" to swipeCardTimeoutMs.toString(),
            "ReceiptType" to receiptType,
            "OriginalAmount" to amount.toString()
        )

        if (!billNo.isNullOrEmpty()) {
            payload["BillNo"] = billNo
        }
        if (!additionalData.isNullOrEmpty()) {
            payload["AdditionalData"] = additionalData
        }

        return createIntent(payload, packageName)
    }

    fun startBillPayment(
        billId: String,
        paymentId: String,
        billNo: String? = null,
        additionalData: String? = null,
        swipeCardTimeoutMs: Int = 30000,
        receiptType: String = "1",
        packageName: String = "ir.co.pna.pos"
    ): Intent {
        val payload = mutableMapOf<String, Any>(
            "AndroidPosMessageHeader" to "@@PNA@@",
            "ECRType" to "1",
            "TransactionType" to "01",
            "BillId" to billId,
            "PaymentId" to paymentId,
            "SwipeCardTimeout" to swipeCardTimeoutMs.toString(),
            "ReceiptType" to receiptType
        )

        if (!billNo.isNullOrEmpty()) {
            payload["BillNo"] = billNo
        }
        if (!additionalData.isNullOrEmpty()) {
            payload["AdditionalData"] = additionalData
        }

        return createIntent(payload, packageName)
    }

    fun startMultiAccountPurchase(
        amount: Long,
        splits: List<IapAccountSplit>,
        billNo: String? = null,
        swipeCardTimeoutMs: Int = 30000,
        receiptType: String = "1",
        packageName: String = "ir.co.pna.pos"
    ): Intent {
        require(splits.isNotEmpty()) { "splits must not be empty." }
        val totalPercent = splits.sumOf { it.percent }
        require(totalPercent == 100) { "splits percent total must be 100." }

        val additionalDataList = mutableListOf<Map<String, Any>>()
        var totalProcessedAmount = 0L
        for (i in splits.indices) {
            val split = splits[i]
            val isLast = i == splits.size - 1
            val accountAmount = if (isLast) {
                amount - totalProcessedAmount
            } else {
                (amount * split.percent / 100)
            }
            totalProcessedAmount += accountAmount
            additionalDataList.add(
                mapOf(
                    "Index" to split.index,
                    "AccountAmount" to accountAmount
                )
            )
        }

        val payload = mutableMapOf<String, Any>(
            "AndroidPosMessageHeader" to "@@PNA@@",
            "ECRType" to "1",
            "Amount" to amount.toString(),
            "TransactionType" to "04",
            "AdditionalData" to additionalDataList,
            "SwipeCardTimeout" to swipeCardTimeoutMs.toString(),
            "ReceiptType" to receiptType,
            "OriginalAmount" to amount.toString()
        )

        if (!billNo.isNullOrEmpty()) {
            payload["BillNo"] = billNo
        }

        return createIntent(payload, packageName)
    }

    fun getSettlementAccounts(packageName: String = "ir.co.pna.pos"): Intent {
        val payload = mapOf(
            "AndroidPosMessageHeader" to "@@PNA@@",
            "TransactionType" to "10"
        )
        return createIntent(payload, packageName)
    }

    private fun createIntent(payload: Map<String, Any>, packageName: String): Intent {
        val data = gson.toJson(payload)

        return Intent("ir.co.pna.pos.view.cart.IAPCActivity").apply {
//            setPackage(packageName)
            putExtra("Data", data)
        }
    }


    fun decodeResponse(
        id: String?,
        activityResult: ActivityResult
    ): PaymentResultEntity {
        val result = activityResult.data?.getStringExtra("Result")


        if (result.isNullOrEmpty()) {
            throw Exception("پرداخت کنسل شد")
        }
        return try {
            val type = object : TypeToken<Map<String, Any>>() {}.type
            val data = gson.fromJson<Map<String, Any>>(result, type)
            PaymentResultEntity(
                id = id,
                status = if (data["Status"] == "OK") PaymentResultStatus.OK else PaymentResultStatus.ERROR,
                terminalId = data["TerminalId"].toString(),
                stan = data["STAN"].toString(),
                rrn = data["RRN"].toString(),
                responseCode = data["ResponseCode"].toString(),
                customerCardNO = data["CustomerCardNO"].toString(),
                transactionDateTime = data["TransactionDateTime"].toString(),
                description = data["Description"].toString()
            )
        } catch (e: Exception) {
            throw Exception("POS response is not a JSON object.")
        }
    }
}
