package inn.ocsf.bee.freigeld.serve.rest

import inn.ocsf.bee.freigeld.core.model.CentralBank
import inn.ocsf.bee.freigeld.core.model.GlobalWorld
import inn.ocsf.bee.freigeld.core.model.PersonIdentityPrivateMember
import inn.ocsf.bee.freigeld.core.model.PersonMemberPosition
import inn.ocsf.bee.freigeld.core.model.data.PersonData
import inn.ocsf.bee.freigeld.core.service.WorldService
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import java.util.*
import javax.inject.Inject

@RestController
class OrgController {

    @Inject
    private lateinit var world: GlobalWorld

    @Inject
    private lateinit var worldService: WorldService

    @Inject
    private lateinit var bank: CentralBank

    @RequestMapping("api/new/private", method = [RequestMethod.POST])
    fun new(@RequestBody newReq: NewPrivatePersonReq): ResponseEntity<Map<String, Any?>> {
        val orgId = world.addPerson(PersonData.PrivatePersonImpl(newReq.ownerId))
        val org = world.getPerson(orgId) ?: throw RuntimeException("org not created")
        world.setPersonIdentity(org, PersonIdentityPrivateMember(newReq.ownerId, PersonMemberPosition.owner))
        val orgAccount = bank.addAccount(orgId)
        return ResponseEntity.ok(mapOf("id" to orgId, "accountId" to orgAccount.id))
    }

    @RequestMapping("api/old/private/{ownerId}/list", method = [RequestMethod.GET])
    fun list(@PathVariable("ownerId") ownerId: UUID): ResponseEntity<List<PrivatePersonInfo>> {
        val ret = (worldService.findAllByOwnerId(ownerId).map {
            //val org = world.getPerson(it)
            PrivatePersonInfo(it, ownerId, PersonMemberPosition.owner)
        } + worldService.findAllByMemberId(ownerId).map {
            PrivatePersonInfo(it._1, ownerId, it._2)
        }).distinctBy { it.privateId }
        return ResponseEntity.ok(ret)
    }

    @RequestMapping("api/old/private/{privateId}", method = [RequestMethod.GET])
    fun old(@PathVariable("privateId") privateId: UUID, @RequestParam("memberId") memberId: UUID): ResponseEntity<PrivatePersonInfo> {
        val org = world.getPerson(privateId)
        return if (org != null) {
            val accessors = world.getPersonIdentitySet(org) ?: setOf()
            val ret = accessors.filter { it is PersonIdentityPrivateMember }.map { it as PersonIdentityPrivateMember }.filter { it.personId == memberId }.map { PrivatePersonInfo(org.id, it.personId, it.position) }.firstOrNull()
            if (ret != null) {
                ResponseEntity.ok(ret)
            } else {
                ResponseEntity(HttpStatus.FORBIDDEN)
            }
        } else {
            ResponseEntity(HttpStatus.NOT_FOUND)
        }
    }
}

data class PrivatePersonInfo(val privateId: UUID, val personId: UUID, val position: PersonMemberPosition)

data class NewPrivatePersonReq(val ownerId: UUID)