package com.mvrent.carrental.controller;

import com.mvrent.carrental.model.SettlementStatus;
import com.mvrent.carrental.model.VendorSettlement;
import com.mvrent.carrental.service.ConfigService;
import com.mvrent.carrental.service.ExcelService;
import com.mvrent.carrental.service.PdfService;
import com.mvrent.carrental.service.SettlementService;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.time.LocalDate;
import java.util.Map;

@Controller
@RequiredArgsConstructor
@PreAuthorize("hasRole('ADMIN') or hasAuthority('MANAGE_BILLING')")
public class AdminSettlementController {

    static final MediaType XLSX =
            MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

    private final SettlementService settlementService;
    private final PdfService pdfService;
    private final ExcelService excelService;
    private final ConfigService configService;

    @PostMapping("/admin/vendors/{vendorId}/settlements")
    public String generate(@PathVariable Long vendorId,
                           @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate periodStart,
                           @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate periodEnd,
                           RedirectAttributes ra) {
        try {
            VendorSettlement s = settlementService.generate(vendorId, periodStart, periodEnd);
            ra.addFlashAttribute("success", "Settlement generated — net payable Rs. " + s.getNetPayable());
            return "redirect:/admin/settlements/" + s.getId();
        } catch (IllegalArgumentException ex) {
            ra.addFlashAttribute("error", ex.getMessage());
            return "redirect:/admin/vendors/" + vendorId;
        }
    }

    @GetMapping("/admin/settlements")
    public String list(Model model) {
        model.addAttribute("settlements", settlementService.findAll());
        return "admin/settlements";
    }

    @GetMapping("/admin/settlements/{id}")
    public String detail(@PathVariable Long id, Model model) {
        VendorSettlement s = settlementService.findById(id);
        model.addAttribute("settlement", s);
        model.addAttribute("trips", settlementService.tripsFor(s));
        return "admin/settlement-detail";
    }

    @PostMapping("/admin/settlements/{id}/status")
    public String status(@PathVariable Long id, @RequestParam SettlementStatus status, RedirectAttributes ra) {
        settlementService.updateStatus(id, status);
        ra.addFlashAttribute("success", "Settlement set to " + status);
        return "redirect:/admin/settlements/" + id;
    }

    @GetMapping("/admin/settlements/{id}/pdf")
    public ResponseEntity<byte[]> pdf(@PathVariable Long id) {
        VendorSettlement s = settlementService.findById(id);
        byte[] pdf = pdfService.render("pdf/settlement", Map.of(
                "settlement", s, "trips", settlementService.tripsFor(s),
                "orgName", configService.getOrganization().getName()));
        return ResponseEntity.ok().contentType(MediaType.APPLICATION_PDF)
                .header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"settlement-" + s.getId() + ".pdf\"")
                .body(pdf);
    }

    @GetMapping("/admin/settlements/{id}/excel")
    public ResponseEntity<byte[]> excel(@PathVariable Long id) {
        VendorSettlement s = settlementService.findById(id);
        byte[] xlsx = excelService.settlementWorkbook(s, settlementService.tripsFor(s));
        return ResponseEntity.ok().contentType(XLSX)
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"settlement-" + s.getId() + ".xlsx\"")
                .body(xlsx);
    }
}
