package org.hso.ecommerce.controller;

import org.hso.ecommerce.action.user.CreateDeliveryData;
import org.hso.ecommerce.action.user.UpdateUserSettingsAction;
import org.hso.ecommerce.api.RestServiceForDelivery;
import org.hso.ecommerce.app.config.AppSettings;
import org.hso.ecommerce.entities.shop.CustomerOrder;
import org.hso.ecommerce.entities.user.User;
import org.hso.ecommerce.repos.shop.CustomerOrderRepository;
import org.hso.ecommerce.repos.user.UserRepository;
import org.hso.ecommerce.uimodel.DeliveryData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.stream.Collectors;

@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private final UserRepository userRepository = null;

    @Autowired
    private final CustomerOrderRepository customerOrderRepository = null;

    @Autowired
    private final RestServiceForDelivery restServiceForDelivery = null;

    @Autowired
    private final AppSettings appSettings = null;

    @GetMapping("/")
    public String user() {
        return "redirect:/user/settings";
    }

    @GetMapping("/settings")
    public String userSettings(Model model,
                               @RequestAttribute("user") User user
    ) {
        model.addAttribute("user", user);

        return "user/settings";
    }

    @GetMapping("/orders/")
    public String userOrders(
            @RequestAttribute("user") User user,
            Model model
    ) {
        List<CustomerOrder> orders = customerOrderRepository.getOrdersByUserId(user.id);

        List<CustomerOrderDelivery> customerOrderDeliveryDataMap = orders
                .stream()
                .map(o -> new CustomerOrderDelivery(o, CreateDeliveryData.getDeliveryDataFromCustomerOrder(o, customerOrderRepository, restServiceForDelivery)))
                .collect(Collectors.toList());

        model.addAttribute("orderDeliveryDataMap", customerOrderDeliveryDataMap);
        model.addAttribute("deliveryService", appSettings.getParcelServiceName());

        return "user/orders/index";
    }

    static class CustomerOrderDelivery {
        private CustomerOrder customerOrder;
        private DeliveryData deliveryData;

        public CustomerOrderDelivery(CustomerOrder customerOrder, DeliveryData deliveryData) {
            this.customerOrder = customerOrder;
            this.deliveryData = deliveryData;
        }

        public CustomerOrder getCustomerOrder() {
            return customerOrder;
        }

        public DeliveryData getDeliveryData() {
            return deliveryData;
        }
    }

    @PostMapping("/settings/changeMail")
    public String changeMail(HttpSession session,
                             @RequestParam("email") String email,
                             HttpServletRequest request
    ) {
        User user = userRepository.findById((long) session.getAttribute("userId")).get();

        UpdateUserSettingsAction cusa = new UpdateUserSettingsAction(user, userRepository);
        UpdateUserSettingsAction.UpdateResult result = cusa.updateEmail(email);
        if (result.updated == false) {
            request.setAttribute("error", result.errorString);
            return "user/settings";
        }

        return "redirect:/user/settings";
    }

    @PostMapping("/settings/changePwd")
    public String changePwd(HttpSession session,
                            @RequestParam("old-password") String oldPassword,
                            @RequestParam("password1") String password1,
                            @RequestParam("password2") String password2,
                            HttpServletRequest request
    ) {
        User user = userRepository.findById((long) session.getAttribute("userId")).get();

        UpdateUserSettingsAction cusa = new UpdateUserSettingsAction(user, userRepository);
        UpdateUserSettingsAction.UpdateResult result = cusa.updatePassword(oldPassword, password1, password2);
        if (result.updated == false) {
            request.setAttribute("error", result.errorString);
            return "user/settings";
        }

        return "redirect:/user/settings";
    }

    @PostMapping("/settings/changeAddress")
    public String changeAddress(HttpSession session,
                                @RequestParam("salutation") String salutation,
                                @RequestParam("name") String name,
                                @RequestParam("address") String address,
                                HttpServletRequest request
    ) {
        User user = userRepository.findById((long) session.getAttribute("userId")).get();

        UpdateUserSettingsAction cusa = new UpdateUserSettingsAction(user, userRepository);
        UpdateUserSettingsAction.UpdateResult result = cusa.updateShippingInfo(salutation, name, address);
        if (result.updated == false) {
            request.setAttribute("error", result.errorString);
            return "user/settings";
        }

        return "redirect:/user/settings";
    }

    @PostMapping("/settings/changePaymentInfo")
    public String changePaymentInfo(HttpSession session,
                                    @RequestParam("creditCardNumber") String creditCardNumber,
                                    HttpServletRequest request
    ) {
        User user = userRepository.findById((long) session.getAttribute("userId")).get();

        UpdateUserSettingsAction cusa = new UpdateUserSettingsAction(user, userRepository);
        UpdateUserSettingsAction.UpdateResult result = cusa.updatePaymentInfo(creditCardNumber);
        if (result.updated == false) {
            request.setAttribute("error", result.errorString);
            return "user/settings";
        }

        return "redirect:/user/settings";
    }
}
