package com.nisum.myteam.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.nisum.myteam.exception.handler.MyTeamException;
import com.nisum.myteam.exception.handler.ResponseDetails;
import com.nisum.myteam.model.Account;
import com.nisum.myteam.service.IAccountService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@RestController
public class AccountController {

	@Autowired
	private IAccountService accountService;

	@RequestMapping(value = "/accounts", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
	public ResponseEntity<?> createAccount(@Valid @RequestBody Account account, HttpServletRequest request)
			throws MyTeamException {

		log.info("Serving the Account Creation action");
		boolean isAccountExists = accountService.isAccountExists(account);
		log.info("is Account exists with the name " + account.getAccountName() + ":::" + isAccountExists);
		if (!isAccountExists) {
			Account accountPersisted = accountService.createAccount(account);

			ResponseDetails createResponseDetails = new ResponseDetails(new Date(), 601, "Account has been created",
					"status description",null, request.getContextPath(), "details", accountPersisted);
			return new ResponseEntity<ResponseDetails>(createResponseDetails, HttpStatus.OK);

		}
		ResponseDetails responseDetails = new ResponseDetails(new Date(), 602, "An Account is already existed",
				"Choose the different account name",null, request.getRequestURI(), "details", account);

		return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);
	}

	@RequestMapping(value = "/accounts/{accountId}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	public ResponseEntity<?> updateAccount(@RequestBody Account account, @PathVariable String accountId,
			HttpServletRequest request) throws MyTeamException {
		log.info("Updating the account with details::"+account);
		boolean isAccountExists = accountService.isAccountExists(account);
		if (isAccountExists == true) {
			Account accountPersisted = accountService.updateAccount(account);

			ResponseDetails updateRespDetails = new ResponseDetails(new Date(), 604, "Account has been updated",
					"status description",null, request.getContextPath(), "details", accountPersisted);

			return new ResponseEntity<ResponseDetails>(updateRespDetails, HttpStatus.OK);

		}
		ResponseDetails responseDetails = new ResponseDetails(new Date(), 605, "Account is Not found",
				"Choose the correct updating account name",null, request.getRequestURI(), "details", account);

		return new ResponseEntity<ResponseDetails>(responseDetails, HttpStatus.OK);

	}


	@RequestMapping(value = "/accounts/{accountId}", method = RequestMethod.DELETE, produces = MediaType.APPLICATION_JSON_VALUE)
	public ResponseEntity<?> deleteAccount(@PathVariable String accountId, HttpServletRequest request)
			throws MyTeamException {
		log.info("Deleting account with accountId:" + accountId);
		Account accountDeleted = accountService.deleteAccount(accountId);
		ResponseDetails deleteRespDetails = new ResponseDetails(new Date(), 604,
				"Account has been deleted successfully", "status description", null,request.getRequestURI(), "details",
				accountDeleted);

		return new ResponseEntity<ResponseDetails>(deleteRespDetails, HttpStatus.OK);

	}



	@RequestMapping(value = "/accounts", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	public ResponseEntity<?> getAccounts(HttpServletRequest request) throws MyTeamException {
		List<Map<Object, Object>> accountsList = accountService.getAccountsList();
		log.info("The accounts list::" + accountsList);

		ResponseDetails getRespDetails = new ResponseDetails(new Date(), 604, "Retrieved the accounts successfully",
				"Accounts list", accountsList, request.getRequestURI(), "details", null);

		return new ResponseEntity<ResponseDetails>(getRespDetails, HttpStatus.OK);

	}

	
	@RequestMapping(value = "/accounts/names", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	public ResponseEntity<?> getAccountNames(HttpServletRequest request) throws MyTeamException {
		List<Account> acountsList = accountService.getAccounts();
		List<String> accountNamesList = new ArrayList<>();

		for (Account account : acountsList) {
			accountNamesList.add(account.getAccountName());
		}
		log.info("The account names list::" + accountNamesList);

		ResponseDetails getRespDetails = new ResponseDetails(new Date(), 604,
				"Retrieved the account names successfully", "Account names list", accountNamesList,
				request.getRequestURI(), "details", null);

		return new ResponseEntity<ResponseDetails>(getRespDetails, HttpStatus.OK);

	}

	
	//get the accounts based on status(Active or inactive)
	@RequestMapping(value = "/accounts/status", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	public ResponseEntity<List<Account>> getAccounts(@RequestParam("status")String status) throws MyTeamException {
		List<Account> accountsList = accountService.getAccountsAll().stream()
				.filter(e -> "Active".equalsIgnoreCase(e.getStatus())).collect(Collectors.toList());
		return new ResponseEntity<>(accountsList, HttpStatus.OK);
	}
	
}