package com.mvrent.carrental.controller;

import com.mvrent.carrental.model.Booking;
import com.mvrent.carrental.model.BookingStatus;
import com.mvrent.carrental.model.Driver;
import com.mvrent.carrental.model.DriverStatus;
import com.mvrent.carrental.model.User;
import com.mvrent.carrental.service.DriverService;
import com.mvrent.carrental.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.time.LocalDate;
import java.util.List;

/** Self-service portal scoped to the logged-in driver's own record and trips. */
@Controller
@RequestMapping("/driver")
@RequiredArgsConstructor
public class DriverPortalController {

    private final UserService userService;
    private final DriverService driverService;

    private Driver currentDriver(UserDetails principal) {
        User user = userService.findByUsername(principal.getUsername());
        Driver driver = user.getDriver();
        if (driver == null) {
            throw new ResponseStatusException(HttpStatus.FORBIDDEN, "No driver linked to this account");
        }
        return driver;
    }

    @GetMapping
    public String dashboard(@AuthenticationPrincipal UserDetails principal, Model model) {
        Driver driver = currentDriver(principal);
        List<Booking> trips = driverService.tripHistory(driver);
        LocalDate today = LocalDate.now();
        List<Booking> upcoming = trips.stream()
                .filter(b -> b.getReturnDate() != null && !b.getReturnDate().isBefore(today)
                        && (b.getStatus() == BookingStatus.PENDING || b.getStatus() == BookingStatus.CONFIRMED))
                .toList();
        model.addAttribute("driver", driver);
        model.addAttribute("initials", initials(driver.getName()));
        model.addAttribute("totalTrips", driverService.totalTrips(driver));
        model.addAttribute("upcoming", upcoming);
        model.addAttribute("recentTrips", trips.stream().limit(6).toList());
        return "driver/dashboard";
    }

    @GetMapping("/trips")
    public String trips(@AuthenticationPrincipal UserDetails principal, Model model) {
        Driver driver = currentDriver(principal);
        model.addAttribute("driver", driver);
        model.addAttribute("initials", initials(driver.getName()));
        model.addAttribute("trips", driverService.tripHistory(driver));
        return "driver/trips";
    }

    @GetMapping("/profile")
    public String profile(@AuthenticationPrincipal UserDetails principal, Model model) {
        Driver driver = currentDriver(principal);
        model.addAttribute("driver", driver);
        model.addAttribute("initials", initials(driver.getName()));
        return "driver/profile";
    }

    /** Driver toggles their own availability (AVAILABLE ↔ OFF). */
    @PostMapping("/availability")
    public String availability(@AuthenticationPrincipal UserDetails principal,
                               @RequestParam DriverStatus status,
                               RedirectAttributes ra) {
        Driver driver = currentDriver(principal);
        // A driver may only mark themselves available or off (not ON_TRIP).
        DriverStatus target = (status == DriverStatus.OFF) ? DriverStatus.OFF : DriverStatus.AVAILABLE;
        driverService.updateStatus(driver.getId(), target);
        ra.addFlashAttribute("success", "You are now " + (target == DriverStatus.OFF ? "off duty" : "available"));
        return "redirect:/driver";
    }

    @PostMapping("/password")
    public String changePassword(@AuthenticationPrincipal UserDetails principal,
                                 @RequestParam String currentPassword,
                                 @RequestParam String newPassword,
                                 RedirectAttributes ra) {
        try {
            userService.changePassword(principal.getUsername(), currentPassword, newPassword);
            ra.addFlashAttribute("success", "Password updated");
        } catch (IllegalArgumentException ex) {
            ra.addFlashAttribute("error", ex.getMessage());
        }
        return "redirect:/driver/profile";
    }

    private static String initials(String name) {
        if (name == null || name.isBlank()) return "?";
        String[] p = name.trim().split("\\s+");
        if (p.length >= 2 && !p[0].isEmpty() && !p[1].isEmpty()) {
            return ("" + p[0].charAt(0) + p[1].charAt(0)).toUpperCase();
        }
        return name.substring(0, Math.min(2, name.length())).toUpperCase();
    }
}
