package com.izipay.tradeizipay.ui

import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.Spinner
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import com.izipay.tradeizipay.utils.initCyberSource
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.izipay.izipay_pw_sdk.data.model.AppearenceControlsPaymentIzipay
import com.izipay.izipay_pw_sdk.data.model.AppearencePaymentIzipay
import com.izipay.izipay_pw_sdk.data.model.AppearenceVisualSettingsPaymentIzipay
import com.izipay.izipay_pw_sdk.data.model.BillingPaymentIzipay
import com.izipay.izipay_pw_sdk.data.model.ConfigRequest
import com.izipay.izipay_pw_sdk.data.model.CustomThemePaymentIzipay
import com.izipay.izipay_pw_sdk.data.model.CyberSource
import com.izipay.izipay_pw_sdk.data.model.OrderPaymentIzipay
import com.izipay.izipay_pw_sdk.data.model.PayOption
import com.izipay.izipay_pw_sdk.data.model.ShippingPaymentIzipay
import com.izipay.izipay_pw_sdk.data.model.TokenPaymentIzipay
import com.izipay.izipay_pw_sdk.domain.model.PaymentResponse
import com.izipay.izipay_pw_sdk.eventbus.EventBus
import com.izipay.izipay_pw_sdk.ui.embedded.callback.PayCallback
import com.izipay.izipay_pw_sdk.ui.embedded.callback.PayManager
import com.izipay.izipay_pw_sdk.ui.embedded.container.PaymentsFragment
import com.izipay.izipay_pw_sdk.ui.embedded.container.PaymentsObject
import com.izipay.izipay_pw_sdk.ui.fullscreend.ContainerActivity
import com.izipay.tradeizipay.R
import com.izipay.tradeizipay.databinding.FragmentHomeBinding
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import org.json.JSONObject
import kotlin.toString

/**
 * Fragment desde el cual se llamará al SDK Móvil de Izipay
 * Información basada en https://developers.izipay.pe/android-core/integration-with-android/recommended-integration/
 * Actualizado al 27-08-2025
 */
@AndroidEntryPoint

/**
 * Integración con Android - Paso 6.2
 * https://developers.izipay.pe/android-core/integration-with-android/recommended-integration/#62-modo-embebido
 * Actualizado al 27-08-2025
 */
class HomeFragment : Fragment(), PayCallback {

    private lateinit var binding: FragmentHomeBinding
    private var timeStamp = ""
    private lateinit var libraryManager: PayManager
    private lateinit var lista_escenario:Array<String>
    private lateinit var listPayMethod:ArrayList<PayOption>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        lista_escenario = resources.getStringArray(R.array.escenario)
    }
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

        binding = FragmentHomeBinding.inflate(inflater, container, false)

        adapterSpinner(binding.spWindow, lista_escenario)

        var activity = requireActivity()
        if (activity is AppCompatActivity) {
            activity.supportActionBar?.title = "Cliente Demo Ktx"
        }

        /**
         * Integración con Android - Paso 5.2
         */
        libraryManager = PayManager()
        libraryManager.setCallback(this)

        binding.btnPagar.setOnClickListener {
            intentIntegration()
        }

        /**
         * Integración con Cybersource - Paso 3
         * https://developers.izipay.pe/android-core/integration-with-cybersource/
         * Actualizado al 27-08-2025
         */
        lifecycleScope.launch {
            EventBus.subscribe<CyberSource> { cyber ->
                initCyberSource(requireContext(), cyber.guid!!, cyber.url!!, cyber.userOrg!!, cyber.userScoring!!)
            }
        }

        return binding.root
    }

    /**
     * Integración con Android - Paso 6
     * https://developers.izipay.pe/android-core/integration-with-android/recommended-integration/#paso-6-agregar-archivo-hiltandroidapp
     * Actualizado al 27-08-2025
     */
    private fun buildConfigRequest(listPayMethod : ArrayList<PayOption>, timestamp: String) : ConfigRequest {
        /**
         * Revisar https://developers.izipay.pe/android-core/integration/parameters/
         * Para ver restricciones de formatos y longitudes en los campos
         */

        var orderNumber = System.currentTimeMillis().toString()

        val request  = ConfigRequest(
            "SBOX", //TEST, SBOX o PROD
            "pay_register", //pay, register
            binding.tvPublicKey.text.toString(),
            System.currentTimeMillis().toString(),
            binding.spComercio.text.toString(),
            "",
            OrderPaymentIzipay(
                orderNumber,
                "PEN",
                "3.00",
                listPayMethod,
                "mobile",
                "autorize",
                "Angel"+System.currentTimeMillis().toString(),
                System.currentTimeMillis().toString(),
            ),
            TokenPaymentIzipay(""),
            BillingPaymentIzipay(
                "Angel",
                "Quispe",
                "ejemplo01@gmail.com",
                "930292619",
                "Av. flores",
                "Lima",
                "Lima",
                "PE",
                "33065",
                "DNI",
                "55555555"
            ),
            ShippingPaymentIzipay(
                "Angel",
                "Quispe",
                "ejemplo01@gmail.com",
                "930292619",
                "Av. Alamo",
                "Lima",
                "Lima",
                "PE",
                "33065",
                "DNI",
                "55555555"
            ), // not required
            AppearencePaymentIzipay(
                "ESP",
                AppearenceControlsPaymentIzipay(
                    true,
                    true,
                ),
                AppearenceVisualSettingsPaymentIzipay(
                    true
                ),
                "red",
                CustomThemePaymentIzipay(
                    "#333399",
                    "#333399",
                    "#333399",
                ),
                ""
            ),
            "https://oalanya.com/izipay/ipn/"
        )
        return request
    }


    private fun intentIntegration() {

        listPayMethod = arrayListOf()
        /**
         * Métodos soportados al 20-11-2024 : Card y Yape
         */
        if(binding.checkTarjeta.isChecked)
            listPayMethod.add(PayOption.CARD)
        if(binding.checkYape.isChecked)
            listPayMethod.add(PayOption.YAPE)


        timeStamp = System.currentTimeMillis().toString()

        val request = buildConfigRequest(listPayMethod, timeStamp)

        if(lista_escenario[binding.spWindow.selectedItemPosition] == "FULLSCREEN"){
            val intent = Intent(activity, ContainerActivity::class.java)
            intent.putExtra(ContainerActivity.REQUEST, request)
            responseLauncher.launch(intent)
        }else{
            /**
             * Integración con Android - Paso 5.2
             */
            val bundle = Bundle().apply {
                putSerializable("data", request)
            }
            val transaction = parentFragmentManager.beginTransaction()
            var fragment = PaymentsObject.paymentsObject() as PaymentsFragment
            fragment.arguments = bundle
            fragment.payManager = libraryManager
            transaction
                .addToBackStack("HomeFragment")
                .add(R.id.navContainer, fragment)
                .commit()
        }
    }

    /**
     * Integración con Android - Paso 6.1
     * https://developers.izipay.pe/android-core/integration-with-android/recommended-integration/#61-modo-fullscreen-screen
     * Actualizado al 27-08-2025
     * Recepción de respuesta en modo fullscreen
     */
    private val responseLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result ->
        val dataSignature = result.data?.getStringExtra(ContainerActivity.RESPONSESIGNTURE).orEmpty()
        val dataPayLoad:PaymentResponse = Gson().fromJson(result.data?.getStringExtra(ContainerActivity.RESPONSEPAYLOAD).orEmpty(), object: TypeToken<PaymentResponse>(){}.type)

        if(result.resultCode == AppCompatActivity.RESULT_OK){
            val response = "Success: True \n\nTra.ID: $timeStamp \n\nSignature: $dataSignature \n\nDataPayLoad: $dataPayLoad"
            binding.etResponse.setText(response)
        }else{
            val response = "Success: False \n\nTra.ID: $timeStamp \n\nSignature: $dataSignature \n\nDataPayLoad: $dataPayLoad"
            binding.etResponse.setText(response)
        }


        var payloadHttp = dataPayLoad.payloadHttp
        var payMethod = "none"
        if(!payloadHttp.isNullOrEmpty()){
            val objPayloadHttp = JSONObject(payloadHttp)
            var responsePayloadHttp = objPayloadHttp.getJSONObject("response")
            payMethod = responsePayloadHttp.getString("payMethod")
        }

        var status = if(dataPayLoad.code == "00"){
            "OK"
        }else{
            "FAILED"
        }
    }

    /**
     * Integración con Android - Paso 5.2
     * Recepción de respuesta en modo embebido
     */
    override fun onDataFromPayments(success: Boolean, pdata: PaymentResponse?, psignature:String?) {
        binding.etResponse.setText("")
        if(success){
            val response = "Success: True \n\nTra.ID: $timeStamp \n\nData: $pdata \n\nSignature: $psignature"
            binding.etResponse.setText(response)
        }else{
            val response = "Success: False \n\nTra.ID: $timeStamp \n\nData: $pdata \n\nSignature: $psignature"
            binding.etResponse.setText(response)
        }

        if (parentFragmentManager.backStackEntryCount > 0)
            parentFragmentManager.popBackStack()
    }

    fun adapterSpinner(spinner:Spinner, opcionesArray:Array<String>){
        val adapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, opcionesArray)
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        spinner.adapter = adapter
    }

}