import Foundation
import Capacitor
import CallKit

@objc(MetoyouMobilePlugin)
public class MetoyouMobilePlugin: CAPPlugin, CAPBridgedPlugin {
    public let identifier = "MetoyouMobilePlugin"
    public let jsName = "MetoyouMobile"
    public let pluginMethods: [CAPPluginMethod] = [
        CAPPluginMethod(name: "startCallKitSession", returnType: CAPPluginReturnPromise),
        CAPPluginMethod(name: "endCallKitSession", returnType: CAPPluginReturnPromise),
        CAPPluginMethod(name: "isRemotePushConfigured", returnType: CAPPluginReturnPromise)
    ]

    private let provider: CXProvider
    private let callController = CXCallController()
    private var activeCallUuid: UUID?

    public override init() {
        let configuration = CXProviderConfiguration(localizedName: "Toju")
        configuration.supportsVideo = true
        configuration.maximumCallsPerCallGroup = 1
        configuration.supportedHandleTypes = [.generic]
        provider = CXProvider(configuration: configuration)
        super.init()
        provider.setDelegate(self, queue: nil)
    }

    @objc func startCallKitSession(_ call: CAPPluginCall) {
        guard let callId = call.getString("callId"),
              let displayName = call.getString("displayName") else {
            call.reject("Missing callId/displayName")
            return
        }

        let uuid = UUID(uuidString: callId) ?? UUID()
        activeCallUuid = uuid

        let handle = CXHandle(type: .generic, value: displayName)
        let startAction = CXStartCallAction(call: uuid, handle: handle)
        startAction.isVideo = false
        let transaction = CXTransaction(action: startAction)

        callController.request(transaction) { error in
            if let error = error {
                call.resolve(["supported": false, "error": error.localizedDescription])
                return
            }

            let update = CXCallUpdate()
            update.remoteHandle = handle
            update.localizedCallerName = displayName
            update.hasVideo = false
            self.provider.reportCall(with: uuid, updated: update)
            call.resolve(["supported": true])
        }
    }

    @objc func endCallKitSession(_ call: CAPPluginCall) {
        guard let uuid = activeCallUuid else {
            call.resolve()
            return
        }

        let endAction = CXEndCallAction(call: uuid)
        let transaction = CXTransaction(action: endAction)

        callController.request(transaction) { _ in
            self.activeCallUuid = nil
            call.resolve()
        }
    }

    @objc func isRemotePushConfigured(_ call: CAPPluginCall) {
        call.resolve(["configured": true])
    }
}

extension MetoyouMobilePlugin: CXProviderDelegate {
    public func providerDidReset(_ provider: CXProvider) {
        activeCallUuid = nil
    }

    public func provider(_ provider: CXProvider, perform action: CXAnswerCallAction) {
        action.fulfill()
    }

    public func provider(_ provider: CXProvider, perform action: CXEndCallAction) {
        activeCallUuid = nil
        action.fulfill()
    }
}
