package com.example.api;

import java.sql.Date;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.LinkedHashMap;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.SessionAttributes;

import com.example.domain.BadRequestException;
import com.example.domain.ItemData;
import com.example.domain.Items;
import com.example.domain.Shoes;
import com.example.domain.User;
import com.example.domain.Wallets;
import com.example.service.ItemsService;
import com.example.service.LoginUser;
import com.example.service.LoginUserDetailsService;
import com.example.service.SalesLogService;
import com.example.service.ShoesService;
import com.example.service.WalletsService;

@RestController
@RequestMapping("limited")
@SessionAttributes(names ="itemData")
public class EcsiteRestController {
	@Autowired
	LoginUserDetailsService loginUserDetailsService;
	@Autowired
	ItemsService itemsService;
	@Autowired
	HttpSession session;
	@Autowired
	SalesLogService salesLogService;
	@Autowired
	ShoesService shoesService;
	@Autowired
	WalletsService walletsService;	
	
	String sameId;
	int totalPrice;
	int count;
	
	//アカウント新規登録
	@PostMapping("signUp")
	public User createUser(@RequestBody User user) {
		user.setRoles("USER");
		LocalDate localDate =  LocalDate.now();
		Date nowDate = Date.valueOf(localDate);
		user.setCreatedAt(nowDate);
		user.setUpdatedAt(nowDate);
		user.setPassword(new Pbkdf2PasswordEncoder().encode(user.getPassword()));
		loginUserDetailsService.create(user);
		Wallets wallet = new Wallets();
		wallet.setUserId(user.getId());
		wallet.setAmount(0);
		walletsService.create(wallet);
		return user;
	}
	
	//カート追加処理
	@PostMapping("inputCart")
	public LinkedHashMap<String, Items> inputCart(@RequestBody ItemData data, Model model, Shoes shoes) {
		//靴の在庫数を購入予定数が超えていないか確認
		shoes = shoesService.findOne(data.getShoesId());
		if(shoes.getStock() < data.getQuantity()){
			throw new BadRequestException();
		}
		//セッションがnullの場合
		if(session.getAttribute("cart") == null){
			//HashMapを生成
			LinkedHashMap<String, Items> cart = new LinkedHashMap<String, Items>();
			String id = data.getShoesId().toString(); 
			//HashMapに靴のIdをKeyとして、Valueに靴の情報を入れる。
			cart.put(id , itemsService.findOne(data.getShoesId(),data.getQuantity()));
			System.out.println(cart);
			//HashMapをセッションに追加
			session.setAttribute("cart", cart);
			//カートのアイテム数をセッションに追加
			session.setAttribute("cartValue", data.getQuantity());
		//セッションがnull出ない場合	
			return cart;
		}else{
			//HashMapを生成
			LinkedHashMap<String, Items> cart = new LinkedHashMap<String, Items>();
			ArrayList <String> list = new ArrayList<String> ();
			String id = data.getShoesId().toString();
			//生成したHashMapにセッションにもともとある情報を照会させる。
			cart = (LinkedHashMap<String, Items>) session.getAttribute("cart");
			//HashMapに靴のIdをKeyとして、Valueに靴の情報を入れる。
			cart.forEach((key, value) ->{
				if(key.equals(id)){
					sameId = key;
					System.out.println(sameId);
				}
			});
			if(id.equals(sameId)){
				cart.put(id , itemsService.findOne(data.getShoesId(), data.getQuantity() + cart.get(id).getQuantity()));
			}else{
				cart.put(id , itemsService.findOne(data.getShoesId(),data.getQuantity()));
			}
			//HashMapをセッションに追加
			session.setAttribute("cart", cart);
			int nowQuantity =  (int) session.getAttribute("cartValue");
			//カートのアイテム数をセッションに追加
			session.setAttribute("cartValue", nowQuantity + data.getQuantity());
			return cart;
		}
	}
	
	@PostMapping("editCart")
	public LinkedHashMap<String, Items>  editCart(@RequestBody ItemData data, Shoes shoes) {
		LinkedHashMap<String, Items> cart = new LinkedHashMap<String, Items>();
		String id = data.getShoesId().toString();
		//生成したHashMapにセッションにもともとある情報を照会させる。
		shoes = shoesService.findOne(data.getShoesId());
		if(shoes.getStock() < data.getQuantity()){
			throw new BadRequestException();
		}
		cart = (LinkedHashMap<String, Items>) session.getAttribute("cart");
		if(data.getQuantity() == 0) {
			cart.remove(id);
		}else {
			cart.put(id , itemsService.findOne(data.getShoesId(),data.getQuantity()));
		}
		if(cart.size() == 0) {
			session.removeAttribute("cart");
			session.removeAttribute("cartValue");
			return cart;
		}
		cart.forEach((key, value)-> {
			this.count += value.getQuantity();
		});
		session.setAttribute("cart", cart);
		session.setAttribute("cartValue", count);
		this.count = 0;
		return cart;
	}
	
	@GetMapping("buy")
	public void buy(@AuthenticationPrincipal LoginUser userDetails, LinkedHashMap<String, Items> items, ArrayList <Items> cart, Wallets wallet){
		items = (LinkedHashMap<String, Items>) session.getAttribute("cart");
		items.forEach((key, value) -> {
			cart.add(value);
		});
		cart.forEach(item ->{
			totalPrice += item.getPrice();
		});
		Integer userId = (Integer) session.getAttribute("userId");
		if(walletsService.findOne(userId).getAmount() < totalPrice){
			throw new BadRequestException(); 
		}
		//支払い
		walletsService.pay(userId, totalPrice);
		salesLogService.update(userId, cart);
		session.removeAttribute("cart");
		session.removeAttribute("cartValue");
		totalPrice = 0;
	}
}