package com.example.web;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.sql.Date;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.example.domain.Items;
import com.example.domain.SalesLog;
import com.example.domain.Shoes;
import com.example.domain.User;
import com.example.domain.Wallets;
import com.example.service.LoginUser;
import com.example.service.SalesLogService;
import com.example.service.ShoesService;
import com.example.service.WalletsService;

@Controller
@RequestMapping("limited")
public class EcsiteController {
	@Autowired
	ShoesService shoesService;
	@Autowired
	WalletsService walletsService;
	@Autowired
	SalesLogService salesLogService;
	@Autowired
	HttpSession session;
	
	@ModelAttribute
	WalletsForm setUpForm() {
		return new WalletsForm();
	}
	
	@ModelAttribute
	DateSearchForm setForm() {
		return new DateSearchForm();
	}
	
	@ModelAttribute
	PriceSearchForm setPriceForm() {
		return new PriceSearchForm();
	}
	
	int totalPrice = 0;
	//写真の表示用メソッド
	public String photoView(String Photo) {
		// 画像を検索してbyteとしてViewへ受け渡す
		String uploadPath = "src/main/resources/static/upload/" + Photo;
		// 画像データストリームを取得する
		try (FileInputStream fis = new FileInputStream(uploadPath);) {
		StringBuffer data = new StringBuffer();
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		// バイト配列に変換
		while (true) {
		int len = fis.read(buffer);
		if (len < 0) {
		        break;
		        }
		        os.write(buffer, 0, len);
		}
		// 画像データをbaseにエンコード
		String base64 = new String(
		org.apache.tomcat.util.codec.binary.Base64.encodeBase64(os.toByteArray()),"ASCII");
		// 画像タイプはJPEG
		// Viewへの受け渡し。
		            data.append("data:image/jpeg;base64,");
		            data.append(base64);
		 
		return data.toString();
		 
		} catch (Exception e) {     e.printStackTrace();
		return null;
		}
	}
	
	
	//トップ画面遷移(現在のログインユーザーデータもmodelに格納済み)
	@GetMapping("top")
	public String top(Model model, @AuthenticationPrincipal LoginUser userDetails) {
		User user = userDetails.getUser();
		model.addAttribute("user", user);
		Wallets wallets = walletsService.findOne(user.getId());
		model.addAttribute("wallets", wallets);
		if(session.getAttribute("cartValue") ==  null) {
			model.addAttribute("cartValue", 0);
		}else {
			model.addAttribute("cartValue",session.getAttribute("cartValue"));
		}
		//遷移先 設定済み
		return "index";
	}
	
	
	//一覧画面遷移(靴の情報と画像を一緒にmodelにあげることが出来ない為、分けてある)
	@GetMapping("list")
	public String list(Model model,  @AuthenticationPrincipal LoginUser userDetails) {
		//靴の情報をすべて取得
//		List<Shoes> shoes = shoesService.findAll();
//		System.out.println(shoes);
		//靴の情報を一括で取得するmodel(Idでの降順表示設定済み)
//		model.addAttribute("shoes", shoes);
		
		//一般商品取得
		List<Shoes> generalShoes = shoesService.findAllGeneralShoes();
		model.addAttribute("generalShoes", generalShoes);
		
		//限定商品取得
		List<Shoes> limitedShoes = shoesService.findAllLimitedShoes();
		model.addAttribute("limitedShoes", limitedShoes);
		
		//user情報取得、格納
		User user = userDetails.getUser();
		model.addAttribute("user", user);
		Wallets wallets = walletsService.findOne(user.getId());
		model.addAttribute("wallets", wallets);
		//カート個数取得、格納
		if(session.getAttribute("cartValue") ==  null) {
			model.addAttribute("cartValue", 0);
		}else {
			model.addAttribute("cartValue",session.getAttribute("cartValue"));
		}
		//遷移先 未設定
		return "list";
	}
	
	//名前検索用
	@PostMapping("/search")
	public String search(@RequestParam String shoesName, Model model, @AuthenticationPrincipal LoginUser userDetails){
		//user情報取得、格納
		User user = userDetails.getUser();
		model.addAttribute("user", user);
		
		//検索に当てはまる靴取得
		List<Shoes> searchShoes = shoesService.findAllForSearch(shoesName);
		model.addAttribute("searchShoes", searchShoes);
		return "list";
	}
	
	//サイズ検索用
	public String searchBySize(@RequestParam Integer shoesSize, Model model, @AuthenticationPrincipal LoginUser userDetails){
		//user情報取得、格納
		User user = userDetails.getUser();
		model.addAttribute("user", user);

		//検索に当てはまる靴取得
		List<Shoes> searchShoes = shoesService.findAllBySize(shoesSize);
		model.addAttribute("searchShoes", searchShoes);
		return "list";
	}
	
	
	//購入履歴画面
	@GetMapping("log/{id}")
	public String history (@PathVariable Integer id, Model model, SalesLog salesLog, @AuthenticationPrincipal LoginUser userDetails) {
		User user = userDetails.getUser();
		model.addAttribute("user", user);
		Wallets wallets = walletsService.findOne(user.getId());
		model.addAttribute("wallets", wallets);
		if(session.getAttribute("cartValue") ==  null) {
			model.addAttribute("cartValue", 0);
		}else {
			model.addAttribute("cartValue",session.getAttribute("cartValue"));
		}
		List<SalesLog> list = salesLogService.history(id);
		ArrayList<SalesLog> newList = new ArrayList<SalesLog>(); 
		for(int i = (list.size() - 1); i >= 0; i--){
			newList.add(list.get(i));
		}
		model.addAttribute("log", newList);
		return "log";
	}
	
	//購入履歴詳細画面
	@GetMapping("logDetails/{created}")
	public String historyDetails (@PathVariable Date created, Model model, @AuthenticationPrincipal LoginUser userDetails) {
		User user = userDetails.getUser();
		model.addAttribute("user", user);
		Wallets wallets = walletsService.findOne(user.getId());
		model.addAttribute("wallets", wallets);
		if(session.getAttribute("cartValue") ==  null) {
			model.addAttribute("cartValue", 0);
		}else {
			model.addAttribute("cartValue",session.getAttribute("cartValue"));
		}
		if(salesLogService.historyDetails(created, user.getId()) == null){
			return "logDetails";
		}
		List<SalesLog> list = salesLogService.historyDetails(created, user.getId());
		model.addAttribute("logDetails", list);
		return "logDetails";
	}
	
	//購入履歴検索
	@PostMapping("log/search/{id}")
	public String searchHistory(@PathVariable Integer id, DateSearchForm dateSerchform, PriceSearchForm priceSearchform, Model model, @AuthenticationPrincipal LoginUser userDetails){
		User user = userDetails.getUser();
		model.addAttribute("user", user);
		Wallets wallets = walletsService.findOne(user.getId());
		model.addAttribute("wallets", wallets);
		if(session.getAttribute("cartValue") ==  null) {
			model.addAttribute("cartValue", 0);
		}else {
			model.addAttribute("cartValue",session.getAttribute("cartValue"));
		}
		//金額の指定がなく日付での検索のみ
		if(priceSearchform.getHighPrice() == null && priceSearchform.getLowPrice() == null && dateSerchform.getDate() != null){
			List<SalesLog> list = salesLogService.historyDetails(dateSerchform.getDate(), user.getId());
			model.addAttribute("log", list);
			return "log";
		}
		//金額のみの検索
		if(dateSerchform.getDate() == null && priceSearchform.getLowPrice() != null && priceSearchform.getHighPrice() != null){
			if(priceSearchform.getLowPrice() == null){
				priceSearchform.setLowPrice(0);
			}
			if(priceSearchform.getHighPrice() == null){
				priceSearchform.setHighPrice(1000000000);
			}
			List<SalesLog> list = salesLogService.searchPrice(priceSearchform.getLowPrice(), priceSearchform.getHighPrice(), user.getId());
			model.addAttribute("log", list);
			return "log";
		}
		return "log";
	}
	
	//カート画面
	@GetMapping("cart")
	public String Cart(Model model, @AuthenticationPrincipal LoginUser userDetails, LinkedHashMap<String, Items> items, ArrayList <Items> cart){
		User user = userDetails.getUser();
		model.addAttribute("user", user);
		Wallets wallets = walletsService.findOne(user.getId());
		model.addAttribute("wallets", wallets);
		session.setAttribute("userId", user.getId());
		items = (LinkedHashMap<String, Items>) session.getAttribute("cart");
		if(items == null) {
			if(session.getAttribute("cartValue") ==  null) {
				model.addAttribute("cartValue", 0);
			}
			return "Cart";
		}
		items.forEach((key, value) -> {
			cart.add(value);
		});
		model.addAttribute("cart", cart);
		cart.forEach(item -> {
			totalPrice += item.getPrice();
		});
		model.addAttribute("totalPrice", totalPrice);
		session.setAttribute("totalprice", totalPrice);
		totalPrice = 0;
		if(session.getAttribute("cartValue") ==  null) {
			model.addAttribute("cartValue", 0);
		}else {
			model.addAttribute("cartValue",session.getAttribute("cartValue"));
		}
		return "Cart";
	}
	
	//財布画面
	@GetMapping("wallets/{id}")
	public String wallets(@PathVariable Integer id, Model model, @AuthenticationPrincipal LoginUser userDetails, Wallets wallet) {
		User user = userDetails.getUser();
		model.addAttribute("user", user);
		wallet = walletsService.findOne(id);
		model.addAttribute("wallet", wallet);
		if(session.getAttribute("cartValue") ==  null) {
			model.addAttribute("cartValue", 0);
		}else {
			model.addAttribute("cartValue",session.getAttribute("cartValue"));
		}
		return "wallets";
	}
	
	//財布チャージ処理
	@PostMapping("wallets/charge/{id}")
	public String walletsCharge(@PathVariable Integer id, @Validated WalletsForm form){
		walletsService.charge(id, form.getAmount());	
		return "redirect:/limited/wallets/{id}";
	}
}
