package com.mvrent.carrental.controller;

import com.mvrent.carrental.model.CategoryType;
import com.mvrent.carrental.model.Driver;
import com.mvrent.carrental.model.DriverDocumentType;
import com.mvrent.carrental.service.ConfigService;
import com.mvrent.carrental.service.DriverService;
import com.mvrent.carrental.service.FileStorageService;
import com.mvrent.carrental.service.VendorService;
import jakarta.validation.Valid;
import org.springframework.web.multipart.MultipartFile;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.time.LocalDate;

@Controller
@RequestMapping("/admin/drivers")
@RequiredArgsConstructor
@PreAuthorize("hasRole('ADMIN') or hasAuthority('MANAGE_DRIVERS')")
public class AdminDriverController {

    private final DriverService driverService;
    private final ConfigService configService;
    private final VendorService vendorService;
    private final FileStorageService fileStorage;

    @GetMapping
    public String list(Model model) {
        model.addAttribute("drivers", driverService.findAll());
        model.addAttribute("categories", configService.categoriesOfType(CategoryType.DRIVER));
        model.addAttribute("vendors", vendorService.findActive());
        return "admin/drivers";
    }

    @GetMapping("/new")
    public String newDriver(Model model) {
        if (!model.containsAttribute("driver")) {
            model.addAttribute("driver", new Driver());
        }
        model.addAttribute("categories", configService.categoriesOfType(CategoryType.DRIVER));
        model.addAttribute("vendors", vendorService.findActive());
        return "admin/driver-form";
    }

    @PostMapping
    public String save(@Valid @ModelAttribute("driver") Driver driver,
                       BindingResult result,
                       @RequestParam(required = false) Long categoryId,
                       @RequestParam(required = false) Long vendorId,
                       Model model,
                       RedirectAttributes ra) {
        if (result.hasErrors()) {
            model.addAttribute("categories", configService.categoriesOfType(CategoryType.DRIVER));
            model.addAttribute("vendors", vendorService.findActive());
            return "admin/driver-form";
        }
        driverService.saveFromForm(driver, categoryId, vendorId);
        ra.addFlashAttribute("success", "Driver saved");
        return "redirect:/admin/drivers";
    }

    @GetMapping("/{id}")
    public String profile(@PathVariable Long id, Model model) {
        Driver driver = driverService.findById(id);
        model.addAttribute("driver", driver);
        model.addAttribute("trips", driverService.tripHistory(driver));
        model.addAttribute("totalTrips", driverService.totalTrips(driver));
        model.addAttribute("initials", initials(driver.getName()));
        return "admin/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();
    }

    @GetMapping("/{id}/edit")
    public String edit(@PathVariable Long id, Model model) {
        model.addAttribute("driver", driverService.findById(id));
        model.addAttribute("categories", configService.categoriesOfType(CategoryType.DRIVER));
        model.addAttribute("vendors", vendorService.findActive());
        return "admin/driver-form";
    }

    @PostMapping("/{id}/delete")
    public String delete(@PathVariable Long id, RedirectAttributes ra) {
        driverService.delete(id);
        ra.addFlashAttribute("success", "Driver deleted");
        return "redirect:/admin/drivers";
    }

    /** Create a /driver portal login for this driver. */
    @PostMapping("/{id}/portal-user")
    public String createPortalUser(@PathVariable Long id,
                                   @RequestParam String username,
                                   @RequestParam String email,
                                   @RequestParam String password,
                                   RedirectAttributes ra) {
        try {
            driverService.createPortalUser(id, username, email, password);
            ra.addFlashAttribute("success", "Driver portal login created for '" + username + "'");
        } catch (IllegalArgumentException ex) {
            ra.addFlashAttribute("error", ex.getMessage());
        }
        return "redirect:/admin/drivers/" + id;
    }

    /* ---------- Documents ---------- */

    @PostMapping("/{id}/documents")
    public String addDocument(@PathVariable Long id,
                              @RequestParam DriverDocumentType docType,
                              @RequestParam(required = false) String fileUrl,
                              @RequestParam(required = false) MultipartFile file,
                              @RequestParam(required = false)
                              @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate issuedDate,
                              @RequestParam(required = false)
                              @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate expiryDate,
                              RedirectAttributes ra) {
        String stored = fileStorage.store(file);
        driverService.addDocument(id, docType, stored != null ? stored : fileUrl, issuedDate, expiryDate);
        ra.addFlashAttribute("success", docType + " document added");
        return "redirect:/admin/drivers/" + id + "/edit";
    }

    @PostMapping("/{id}/documents/{docId}/delete")
    public String deleteDocument(@PathVariable Long id, @PathVariable Long docId,
                                 RedirectAttributes ra) {
        driverService.deleteDocument(docId);
        ra.addFlashAttribute("success", "Document removed");
        return "redirect:/admin/drivers/" + id + "/edit";
    }
}
