package be.seeseepuff.allowanceplanner.controller;

import be.seeseepuff.allowanceplanner.dto.CreateAllowanceRequest;
import be.seeseepuff.allowanceplanner.dto.CreateTaskRequest;
import be.seeseepuff.allowanceplanner.service.AllowanceService;
import be.seeseepuff.allowanceplanner.service.TaskService;
import be.seeseepuff.allowanceplanner.service.UserService;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
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.RequestParam;

import java.util.Arrays;

@Controller
public class WebController {
    private final UserService userService;
    private final AllowanceService allowanceService;
    private final TaskService taskService;

    public WebController(UserService userService, AllowanceService allowanceService, TaskService taskService) {
        this.userService = userService;
        this.allowanceService = allowanceService;
        this.taskService = taskService;
    }

    @GetMapping("/")
    public String index(HttpServletRequest request, HttpServletResponse response, Model model) {
        Integer currentUser = getCurrentUser(request, response);
        if (currentUser == null) {
            model.addAttribute("users", userService.getUsers());
            return "index";
        }
        return renderWithUser(model, currentUser);
    }

    @GetMapping("/login")
    public String login(@RequestParam(required = false) String user, HttpServletResponse response) {
        if (user != null && !user.isEmpty()) {
            Cookie cookie = new Cookie("user", user);
            cookie.setMaxAge(3600);
            cookie.setHttpOnly(true);
            response.addCookie(cookie);
        }
        return "redirect:/";
    }

    @PostMapping("/createTask")
    public String createTask(@RequestParam String name, @RequestParam double reward,
                             @RequestParam(required = false) String schedule,
                             HttpServletRequest request, HttpServletResponse response, Model model) {
        Integer currentUser = getCurrentUser(request, response);
        if (currentUser == null) {
            return "redirect:/";
        }

        if (name.isEmpty() || reward <= 0) {
            model.addAttribute("error", "Invalid input");
            return "index";
        }

        CreateTaskRequest taskRequest = new CreateTaskRequest(name, reward, null,
                (schedule != null && !schedule.isEmpty()) ? schedule : null);
        taskService.createTask(taskRequest);
        return "redirect:/";
    }

    @GetMapping("/completeTask")
    public String completeTask(@RequestParam("task") int taskId) {
        taskService.completeTask(taskId);
        return "redirect:/";
    }

    @PostMapping("/createAllowance")
    public String createAllowance(@RequestParam String name, @RequestParam double target,
                                  @RequestParam double weight,
                                  HttpServletRequest request, HttpServletResponse response, Model model) {
        Integer currentUser = getCurrentUser(request, response);
        if (currentUser == null) {
            return "redirect:/";
        }

        if (name.isEmpty() || target <= 0 || weight <= 0) {
            model.addAttribute("error", "Invalid input");
            return "index";
        }

        allowanceService.createAllowance(currentUser, new CreateAllowanceRequest(name, target, weight, ""));
        return "redirect:/";
    }

    @GetMapping("/completeAllowance")
    public String completeAllowance(@RequestParam("allowance") int allowanceId,
                                    HttpServletRequest request, HttpServletResponse response) {
        Integer currentUser = getCurrentUser(request, response);
        if (currentUser == null) {
            return "redirect:/";
        }
        allowanceService.completeAllowance(currentUser, allowanceId);
        return "redirect:/";
    }

    private Integer getCurrentUser(HttpServletRequest request, HttpServletResponse response) {
        Cookie[] cookies = request.getCookies();
        if (cookies == null) {
            return null;
        }
        String userStr = Arrays.stream(cookies)
                .filter(c -> "user".equals(c.getName()))
                .map(Cookie::getValue)
                .findFirst()
                .orElse(null);
        if (userStr == null) {
            return null;
        }
        try {
            int userId = Integer.parseInt(userStr);
            if (!userService.userExists(userId)) {
                unsetUserCookie(response);
                return null;
            }
            return userId;
        } catch (NumberFormatException e) {
            unsetUserCookie(response);
            return null;
        }
    }

    private void unsetUserCookie(HttpServletResponse response) {
        Cookie cookie = new Cookie("user", "");
        cookie.setMaxAge(0);
        cookie.setPath("/");
        cookie.setHttpOnly(true);
        response.addCookie(cookie);
    }

    private String renderWithUser(Model model, int currentUser) {
        model.addAttribute("users", userService.getUsers());
        model.addAttribute("currentUser", currentUser);
        model.addAttribute("allowances", allowanceService.getUserAllowances(currentUser));
        model.addAttribute("tasks", taskService.getTasks());
        model.addAttribute("history", allowanceService.getHistory(currentUser));
        return "index";
    }
}
