import Foundation

// MARK: Client class
final class XMPPClient {
    let jid: JID
    private let store: ClientStore

    init(jid: JID, updateCallback: @escaping (XMPPClientUpdateMsg) -> Void) {
        self.jid = jid
        let state = ClientState(jid: jid)

        // pre-init middlewares who requires callback
        let topObserverMiddleware = TopObserverMiddleware(jid: jid, callback: updateCallback)
        let connectionMiddleware = ConnectionMiddleware(jid: jid)
        let parserMiddleware = ParserMiddleware()
        let callMiddleware = CallMiddleware()

        // client store
        store = ClientStore(
            initialState: state,
            reducer: ClientState.reducer,
            middlewares: [
                LoggerMiddleware().middleware,
                topObserverMiddleware.middleware,
                ResolverMiddleware().middleware,
                connectionMiddleware.middleware,
                parserMiddleware.middleware,
                StreamMiddleware().middleware,
                AuthMiddleware().middleware,
                BindResourceMiddleware().middleware,
                ExternalServiceMiddleware().middleware,
                callMiddleware.middleware
            ]
        )

        // assign callback
        connectionMiddleware.setCallback(store.dispatch)
        parserMiddleware.setCallback(store.dispatch)
        callMiddleware.setCallback(store.dispatch)
    }
}

// MARK: Client functions
extension XMPPClient {
    func reconnect() {
        store.dispatch(.connectionAction(.reconnect))
    }

    func loginWith(_ pass: String) {
        store.dispatch(.authAction(.setAuthType(.authorization)))
        store.dispatch(.authAction(.setPassword(pass)))
        store.dispatch(.authAction(.startAuth))
    }
}
