package org.apache.fineract.ui.online.groups.creategroup

import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.stepstone.stepper.StepperLayout
import com.stepstone.stepper.VerificationError
import kotlinx.android.synthetic.main.activity_create_group.*
import org.apache.fineract.R
import org.apache.fineract.data.Status
import org.apache.fineract.data.models.Group
import org.apache.fineract.data.models.customer.Address
import org.apache.fineract.ui.base.FineractBaseActivity
import org.apache.fineract.ui.base.Toaster
import org.apache.fineract.ui.online.groups.GroupAction
import org.apache.fineract.ui.online.groups.grouplist.GroupViewModel
import org.apache.fineract.ui.online.groups.grouplist.GroupViewModelFactory
import org.apache.fineract.utils.Constants
import org.apache.fineract.utils.DateUtils
import javax.inject.Inject

/*
 * Created by saksham on 02/July/2019
*/

class CreateGroupActivity : FineractBaseActivity(), StepperLayout.StepperListener {

    private var group = Group()
    private var groupAction = GroupAction.CREATE

    @Inject
    lateinit var groupViewModelFactory: GroupViewModelFactory

    lateinit var viewModel: GroupViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_create_group)
        activityComponent.inject(this)
        groupAction = intent.getSerializableExtra(Constants.GROUP_ACTION) as GroupAction
        when (groupAction) {
            GroupAction.CREATE -> {
                setToolbarTitle(getString(R.string.create_group))
            }
            GroupAction.EDIT -> {
                setToolbarTitle(getString(R.string.edit_group))
                intent?.extras?.getParcelable<Group>(Constants.GROUP)?.let {
                    group = it
                }
            }
        }
        viewModel = ViewModelProviders.of(this, groupViewModelFactory).get(GroupViewModel::class.java)
        subscribeUI()
        showBackButton()
        slCreateGroup.adapter = CreateGroupAdapter(supportFragmentManager, this, groupAction)
        slCreateGroup.setOffscreenPageLimit(slCreateGroup.adapter.count)
        slCreateGroup.setListener(this)
    }

    override fun onStepSelected(newStepPosition: Int) {}

    override fun onError(verificationError: VerificationError?) {}

    override fun onReturn() {}

    private fun subscribeUI() {
        viewModel.status.observe(this, Observer { status ->
            when (status) {
                Status.LOADING ->
                    if (groupAction == GroupAction.CREATE) {
                        showMifosProgressDialog(getString(R.string.create_group))
                    } else {
                        showMifosProgressDialog(getString(R.string.updating_group_please_wait))
                    }
                Status.ERROR -> {
                    hideMifosProgressDialog()
                    if (groupAction == GroupAction.CREATE) {
                        Toaster.show(findViewById(android.R.id.content), R.string.error_while_creating_group, Toast.LENGTH_SHORT)
                    } else {
                        Toaster.show(findViewById(android.R.id.content), R.string.error_while_updating_group_status, Toast.LENGTH_SHORT)
                    }
                }
                Status.DONE -> {
                    hideMifosProgressDialog()
                    if (groupAction == GroupAction.CREATE) {
                        Toast.makeText(this, getString(R.string.group_identifier_created_successfully, group.identifier), Toast.LENGTH_SHORT).show()
                    } else {
                        Toast.makeText(this, getString(R.string.group_identifier_updated_successfully, group.identifier), Toast.LENGTH_SHORT).show()
                    }
                    finish()
                }
            }
        })
    }

    override fun onCompleted(completeButton: View?) {
        when (groupAction) {
            GroupAction.EDIT -> group.identifier?.let {
                viewModel.updateGroup(group)
            }
            GroupAction.CREATE -> viewModel.createGroup(group)
        }
    }

    fun setGroupDetails(identifier: String, groupDefinitionIdentifier: String, name: String, office: String, assignedEmployee: String) {
        group.identifier = identifier
        group.groupDefinitionIdentifier = groupDefinitionIdentifier
        group.name = name
        group.office = office
        group.assignedEmployee = assignedEmployee
        group.weekday = DateUtils.getWeekDayIndex(DateUtils.getPresentDay())
    }

    fun setMembers(members: List<String>) {
        group.members = members
    }

    fun setLeaders(leaders: List<String>) {
        group.leaders = leaders
    }

    fun setGroupAddress(street: String, city: String, region: String, postalCode: String, country: String, countryCode: String?) {
        val address = Address()
        address.street = street
        address.city = city
        address.region = region
        address.postalCode = postalCode
        address.country = country
        address.countryCode = countryCode
        group.address = address
    }

    fun getGroup(): Group {
        return group
    }
}