package com.MedInsuranceV2.Version20.Controller;

import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.ParseException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.MedInsuranceV2.Version20.BoughtInsurance.BoughtInsurance;
import com.MedInsuranceV2.Version20.BoughtInsurance.BoughtInsuranceService;
import com.MedInsuranceV2.Version20.Claim.Claim;
import com.MedInsuranceV2.Version20.Claim.ClaimService;
import com.MedInsuranceV2.Version20.Email.EmailService;
import com.MedInsuranceV2.Version20.Insurance.Insurance;
import com.MedInsuranceV2.Version20.Insurance.InsuranceService;
import com.MedInsuranceV2.Version20.User.User;
import com.MedInsuranceV2.Version20.User.UserService;
import com.itextpdf.io.source.OutputStream;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.Principal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException; // NEW IMPORT
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Optional;

@Controller
public class WebController {

    @Autowired
    private UserService userService;

    @Autowired
    private InsuranceService insuranceService;

    @Autowired
    private BoughtInsuranceService boughtInsuranceService;

    @Autowired
    private EmailService emailService;
    
    @Autowired
    private ClaimService claimService;

    @RequestMapping("/homepage")
    public String index() {
        return "index";
    }
//    @GetMapping("/login")
//    public String loginPage() {
//        return "login"; // This JSP should have both login and register forms
//    }
//    @GetMapping("/login")
//    public String loginPage() {
//        return "ScrollDownLoginRegister"; // This JSP should have both login and register forms
//    }
    @GetMapping("/login")
    public String loginPage() {
        return "Model2LoginRegister"; // This JSP should have both login and register forms
    }
//    @GetMapping("/login")
//    public String loginPage() {
//        return "CombinedLoginRegister"; // This JSP should have both login and register forms
//    }

    @PostMapping("/login")
    public String login(@RequestParam("emailId") String emailId, @RequestParam("password") String password, HttpSession session, Model model) {
        Optional<User> user = userService.findUserByEmail(emailId);
        if (user.isPresent() && user.get().getPassword().equals(password)) {
            User loggedInUser = user.get();
            session.setAttribute("userId", loggedInUser.getId());
            session.setAttribute("loggedInUser", loggedInUser);
            session.setAttribute("username",loggedInUser.getName());
            if ("ADMIN".equals(loggedInUser.getRole())) {
                return "redirect:/admin/dashboard";
            } else {
                return "redirect:/home";
            }
        } else {
            model.addAttribute("error", "Invalid credentials");
            return "login";
        }
    }

    @GetMapping("/register")
    public String registerPage() {
        return "register";
    }

    @PostMapping("/register")
    public String register(@ModelAttribute User user, @RequestParam("confirmPassword") String confirmPassword, Model model) {
        if (!user.getPassword().equals(confirmPassword)) {
            model.addAttribute("error", "Passwords do not match!");
            return "register";
        }
        userService.registerUser(user);
        return "redirect:/login";
    }

    @GetMapping("/home")
    public String home(HttpSession session, Model model) {
        Long userId = (Long) session.getAttribute("userId");
        if (userId != null) {
            return "home";
        } else {
            return "redirect:/login";
        }
    }

    @GetMapping("/medicalInsurance")
    public String medicalInsurance(HttpSession session) {
        Long userId = (Long) session.getAttribute("userId");
        if (userId != null) {
            return "medicalInsurance";
        } else {
            return "redirect:/login";
        }
    }

    @GetMapping("/newInsurance")
    public String showNewInsurancePlans(Model model) {
        List<Insurance> allInsurancePolicies = insuranceService.getAllInsurancePolicies();
        model.addAttribute("insurancePlans", allInsurancePolicies);
        return "newInsurance";
    }

    @GetMapping("/processBuy")
    public String processBuyInsurance(@RequestParam("planName") String planName,
                                      @RequestParam("planId") Long planId,
                                      HttpSession session, Model model) {
        Long userId = (Long) session.getAttribute("userId");
        if (userId == null) {
            return "redirect:/login";
        }

        Optional<User> user = userService.findUserById(userId);
        Optional<Insurance> insurance = insuranceService.findById(planId);

        if (user.isPresent() && insurance.isPresent()) {
            BoughtInsurance boughtInsurance = boughtInsuranceService.buyInsurance(user.get(), insurance.get());
            String generatedPolicyNumber = boughtInsurance.getPolicyNumber(); // Get the generated policy number

            return "redirect:/buyInsuranceDetails?planName=" + planName +
                    "&coverage=" + insurance.get().getCoverage() +
                    "&premium=" + insurance.get().getAmountPerYear() +
                    "&boughtInsuranceId=" + boughtInsurance.getId() +
                    "&policyNumber=" + generatedPolicyNumber; // Pass the generated policy number
        } else {
            return "redirect:/newInsurance?error=buyFailed";
        }
    }

    @GetMapping("/buyInsuranceDetails")
    public String buyInsuranceDetails(
            @RequestParam("planName") String planName,
            @RequestParam("coverage") double coverage,
            @RequestParam("premium") double premium,
            @RequestParam("boughtInsuranceId") Long boughtInsuranceId,
            @RequestParam("policyNumber") String policyNumber, // Receive the policy number
            Model model) {
        model.addAttribute("planName", planName);
        model.addAttribute("coverage", coverage);
        model.addAttribute("premium", premium);
        model.addAttribute("boughtInsuranceRecordId", boughtInsuranceId);
        model.addAttribute("policyNumber", policyNumber); // Add to model for JSP
        return "buyInsuranceDetails"; // This JSP should have the form to input user details
    }

    @PostMapping("/confirmPurchase")
    public String confirmPurchase(
            @RequestParam("planName") String planName,
            @RequestParam("coverage") double coverage,
            @RequestParam("premium") double premium,
            @RequestParam("fullName") String fullName,
            @RequestParam("dob") String dob, // This is the string from the form
            @RequestParam("address") String address,
            @RequestParam("phoneNumber")String phoneNumber,
            @RequestParam("emailId") String emailId,
            @RequestParam("boughtInsuranceRecordId") Long boughtInsuranceRecordId,
            @RequestParam("policyNumber") String policyNumber,
            HttpSession session,
            Model model) {

        Long userId = (Long) session.getAttribute("userId");
        if (userId == null) {
            return "redirect:/login";
        }

        Optional<User> userOpt = userService.findUserById(userId);

        if (userOpt.isPresent()) {
            Optional<BoughtInsurance> boughtInsuranceOpt = boughtInsuranceService.findById(boughtInsuranceRecordId);

            if (boughtInsuranceOpt.isPresent()) {
                BoughtInsurance boughtInsurance = boughtInsuranceOpt.get();

                // Update the BoughtInsurance entity with the details from the form
                boughtInsurance.setName(fullName);
                boughtInsurance.setAddress(address);
                boughtInsurance.setEmail(emailId);
                boughtInsurance.setPhone(phoneNumber);

                // --- CRITICAL DATE PARSING FIX ---
                try {
                    // Assuming the 'dob' from the form is in "YYYY-MM-DD" format (e.g., from <input type="date">)
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                    boughtInsurance.setDob(LocalDate.parse(dob, formatter));
                } catch (DateTimeParseException e) {
                    System.err.println("Error parsing DOB: " + dob + " - " + e.getMessage());
                    model.addAttribute("error", "Invalid Date of Birth format. Please use YYYY-MM-DD.");
                    // Optionally, return to the form page with an error
                    return "buyInsuranceDetails"; // Or some other error page
                }
                // --- END CRITICAL DATE PARSING FIX ---

                // Save the updated BoughtInsurance record
                boughtInsuranceService.save(boughtInsurance);

                // Send email (your existing logic) - consider moving to a separate thread for performance
                String subject = "Insurance Purchase Confirmation for " + planName;
                String body = "Dear " + fullName + ",\n\n"
                            + "Thank you for purchasing " + planName + " insurance from us.\n"
                            + "Your policy number is: " + policyNumber + "\n"
                            + "Your policy details and invoice have been sent to your email.\n\n"
                            + "Regards,\n"
                            + "MedInsurance Team";
                emailService.sendSimpleEmail(emailId, subject, body);

                // Pass all necessary details to the invoice generation JSP
                model.addAttribute("planName", planName);
                model.addAttribute("coverage", coverage);
                model.addAttribute("premium", premium);
                model.addAttribute("fullName", fullName);
                model.addAttribute("dob", dob); // Pass the original string DOB for the URL
                model.addAttribute("address", address);
                model.addAttribute("phoneNumber", phoneNumber);
                model.addAttribute("emailId", emailId);
                model.addAttribute("policyNumber", policyNumber);

                // Convert java.util.Date to String for the model to match generateInvoice
                DateTimeFormatter pdfDateFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
                String purchaseDateStr = boughtInsurance.getPurchaseDate() != null ?
                                         boughtInsurance.getPurchaseDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().format(pdfDateFormatter) : "N/A";
                String expiryDateStr = boughtInsurance.getExpiryDate() != null ?
                                        boughtInsurance.getExpiryDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().format(pdfDateFormatter) : "N/A";

                model.addAttribute("purchaseDate", purchaseDateStr);
                model.addAttribute("expiryDate", expiryDateStr);


                return "triggerDownloadAndRedirect"; // This will render the JSP that handles download & redirect
            } else {
                System.err.println("BoughtInsurance record not found for ID: " + boughtInsuranceRecordId);
                model.addAttribute("error", "Purchase record not found. Please try again.");
                return "redirect:/newInsurance?error=recordNotFound";
            }
        } else {
            System.err.println("User not found for ID: " + userId);
            model.addAttribute("error", "User not found. Please login again.");
            return "redirect:/login"; // Redirect to login if user not found (session issue)
        }
    }


    @GetMapping("/payment/generateInvoice")
    public void generateInvoice(
        @RequestParam("planName") String planName,
        @RequestParam("coverage") double coverage,
        @RequestParam("premium") double premium,
        @RequestParam("fullName") String fullName,
        @RequestParam("dob") String dob, // Still expects string, as passed from JSP
        @RequestParam("address") String address,
        @RequestParam(value = "emailId") String emailId,
        @RequestParam(value = "policyNumber") String policyNumber,
        @RequestParam(value = "purchaseDate") String purchaseDate,
        @RequestParam(value = "expiryDate") String expiryDate,
        @RequestParam(value = "phoneNumber", required = false) String phoneNumber,
        HttpServletResponse response) throws IOException, DocumentException {

        String displayPhoneNumber = (phoneNumber != null && !phoneNumber.trim().isEmpty()) ? phoneNumber : "N/A";

        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition", "attachment; filename=\"invoice_" + planName.replaceAll(" ", "_") + ".pdf\"");

        Font headerFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 18, BaseColor.DARK_GRAY);
        Font subHeaderFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 12, BaseColor.BLACK);
        Font normalFont = FontFactory.getFont(FontFactory.HELVETICA, 10, BaseColor.BLACK);
        Font boldFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD, 10, BaseColor.BLACK);

        Document document = new Document();
        try {
            PdfWriter.getInstance(document, response.getOutputStream());
            document.open();

            Paragraph invoiceTitle = new Paragraph("INVOICE", headerFont);
            invoiceTitle.setAlignment(Element.ALIGN_CENTER);
            invoiceTitle.setSpacingAfter(20f);
            document.add(invoiceTitle);

            PdfPTable infoTable = new PdfPTable(2);
            infoTable.setWidthPercentage(80);
            infoTable.setSpacingAfter(20f);
            infoTable.setWidths(new float[]{1, 1});
            infoTable.setHorizontalAlignment(Element.ALIGN_CENTER);

            PdfPCell customerCell = new PdfPCell();
            customerCell.setBorder(PdfPCell.NO_BORDER);
            customerCell.setHorizontalAlignment(Element.ALIGN_LEFT);
            customerCell.addElement(new Paragraph("Bill To:", subHeaderFont));
            customerCell.addElement(new Paragraph("Name: " + fullName, normalFont));
            customerCell.addElement(new Paragraph("DOB: " + dob, normalFont));
            customerCell.addElement(new Paragraph("Address: " + address, normalFont));
            customerCell.addElement(new Paragraph("Phone: " + displayPhoneNumber, normalFont));
            customerCell.addElement(new Paragraph("Email: " + emailId, normalFont));
            infoTable.addCell(customerCell);

            PdfPCell dateCell = new PdfPCell();
            dateCell.setBorder(PdfPCell.NO_BORDER);
            dateCell.setHorizontalAlignment(Element.ALIGN_RIGHT);
            dateCell.addElement(new Paragraph("Invoice Date:", subHeaderFont));
            dateCell.addElement(new Paragraph(LocalDate.now().format(DateTimeFormatter.ofPattern("dd-MM-yyyy")), normalFont));
            infoTable.addCell(dateCell);

            document.add(infoTable);

            PdfPTable planTable = new PdfPTable(3);
            planTable.setWidthPercentage(80);
            planTable.setSpacingBefore(10f);
            planTable.setSpacingAfter(20f);
            planTable.setWidths(new float[]{3, 4, 2});
            planTable.setHorizontalAlignment(Element.ALIGN_CENTER);

            PdfPCell cell;

            cell = new PdfPCell(new Phrase("Description", boldFont));
            cell.setBackgroundColor(BaseColor.LIGHT_GRAY);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setPadding(5);
            planTable.addCell(cell);

            cell = new PdfPCell(new Phrase("Coverage", boldFont));
            cell.setBackgroundColor(BaseColor.LIGHT_GRAY);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setPadding(5);
            planTable.addCell(cell);

            cell = new PdfPCell(new Phrase("Premium (Annual)", boldFont));
            cell.setBackgroundColor(BaseColor.LIGHT_GRAY);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setPadding(5);
            planTable.addCell(cell);

            cell = new PdfPCell(new Phrase("Insurance Plan: " + planName, normalFont));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setPadding(5);
            planTable.addCell(cell);

            cell = new PdfPCell(new Phrase(String.format("₹%.2f", coverage), normalFont));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setPadding(5);
            planTable.addCell(cell);

            cell = new PdfPCell(new Phrase(String.format("₹%.2f", premium), normalFont));
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
            cell.setPadding(5);
            planTable.addCell(cell);

            document.add(planTable);

            PdfPTable totalTable = new PdfPTable(2);
            totalTable.setWidthPercentage(80);
            totalTable.setWidths(new float[]{7, 2});
            totalTable.setHorizontalAlignment(Element.ALIGN_CENTER);

            cell = new PdfPCell(new Phrase("TOTAL AMOUNT DUE", boldFont));
            cell.setBorder(PdfPCell.NO_BORDER);
            cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
            cell.setPadding(5);
            totalTable.addCell(cell);

            cell = new PdfPCell(new Phrase(String.format("₹%.2f", premium), boldFont));
            cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
            cell.setPadding(5);
            totalTable.addCell(cell);

            document.add(totalTable);

            Paragraph thankYou = new Paragraph("Thank you for your purchase!", normalFont);
            thankYou.setAlignment(Element.ALIGN_CENTER);
            thankYou.setSpacingBefore(30f);
            document.add(thankYou);

            Paragraph contactInfo = new Paragraph("For any inquiries, please contact us at support@example.com", normalFont);
            contactInfo.setAlignment(Element.ALIGN_CENTER);
            document.add(contactInfo);

        } finally {
            if (document != null && document.isOpen()) {
                document.close();
            }
        }
    }

    @GetMapping("/viewInsurance")
    public String viewInsurance(HttpSession session, Model model,
                                @RequestParam(value = "success", required = false) String successMessage,
                                @RequestParam(value = "error", required = false) String errorMessage,
                                RedirectAttributes redirectAttributes) {

        Long userId = (Long) session.getAttribute("userId");
        if (userId == null) {
            redirectAttributes.addFlashAttribute("error", "Please log in to view your policies.");
            return "redirect:/login";
        }

        Optional<User> userOpt = userService.findUserById(userId);
        if (userOpt.isEmpty()) {
            System.err.println("User ID " + userId + " found in session but not in database.");
            redirectAttributes.addFlashAttribute("error", "User not found. Please log in again.");
            return "redirect:/login";
        }

        if (successMessage != null) {
            model.addAttribute("success", successMessage);
        }
        if (errorMessage != null) {
            model.addAttribute("error", errorMessage);
        }

        List<BoughtInsurance> boughtInsurances = boughtInsuranceService.findBoughtInsurancesByUserId(userId);
        Date currentDateTime = new Date(); // Still good to have if needed elsewhere, but not for expiry now

        // Enhance each BoughtInsurance object with its latest claim status and action flags for display
        for (BoughtInsurance bi : boughtInsurances) {
            List<Claim> claimsForPolicy = claimService.findByBoughtInsurance_Id(bi.getId());

            String displayClaimStatus = "No Claim Filed"; // Default
            boolean hasAnyClaimFiled = !claimsForPolicy.isEmpty(); // Flag: true if any claim exists for this policy
            boolean canFileNewClaim = false; // Flag: true if a NEW claim can be filed

            if (hasAnyClaimFiled) {
                Optional<Claim> latestClaimOpt = claimsForPolicy.stream()
                    .max(Comparator.comparing(Claim::getFilingDate));

                if (latestClaimOpt.isPresent()) {
                    Claim latestClaim = latestClaimOpt.get();
                    displayClaimStatus = latestClaim.getStatus(); // PENDING, APPROVED, DENIED

                    // A new claim can be filed ONLY IF the latest claim was DENIED.
                    // We've removed the 'isPolicyActive' check here as requested.
                    if (displayClaimStatus.equals("DENIED")) {
                        canFileNewClaim = true;
                    }
                }
            } else {
                // No claims filed yet. Allow filing regardless of policy expiry (as requested).
                canFileNewClaim = true;
            }
System.out.println("Policy ID: " + bi.getId() + ", Claim Status: " + displayClaimStatus + ", Can File New Claim: " + canFileNewClaim + ", Has Any Claim Filed: " + hasAnyClaimFiled);
            model.addAttribute("claimStatus" + bi.getId(), displayClaimStatus);
            model.addAttribute("canFileNewClaim" + bi.getId(), canFileNewClaim); // Renamed for clarity
            model.addAttribute("hasAnyClaimFiled" + bi.getId(), hasAnyClaimFiled); // New flag

            // Removed the "isExpired" model attribute as requested.
            // boolean isExpired = (bi.getExpiryDate() != null && bi.getExpiryDate().before(currentDateTime));
            // model.addAttribute("isExpired_" + bi.getId(), isExpired);
        }

        model.addAttribute("boughtInsurances", boughtInsurances); // Keep the original list for iteration
        model.addAttribute("currentDateTime", currentDateTime); // Pass current date for any remaining JSP needs

        return "showBoughtInsurance"; // This JSP will display the policies
    }
    
    @GetMapping("/downloadBoughtInvoice")
    public void downloadBoughtInvoice(@RequestParam("boughtInsuranceId") Long boughtInsuranceId,
                                    HttpServletResponse response) throws IOException, DocumentException {
        Optional<BoughtInsurance> boughtInsuranceOpt = boughtInsuranceService.findById(boughtInsuranceId);

        if (boughtInsuranceOpt.isPresent()) {
            BoughtInsurance boughtInsurance = boughtInsuranceOpt.get();

            // Extract details from the fetched object
            String planName = boughtInsurance.getInsurance().getName();
            double coverage = boughtInsurance.getInsurance().getCoverage();
            double premium = boughtInsurance.getInsurance().getAmountPerYear();
            String fullName = boughtInsurance.getName();
            String dob = boughtInsurance.getDob() != null ? boughtInsurance.getDob().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) : "N/A";
            String address = boughtInsurance.getAddress();
            String phoneNumber = boughtInsurance.getPhone();
            String emailId = boughtInsurance.getEmail();
            String policyNumber = boughtInsurance.getPolicyNumber();

            // Format dates for the PDF
            DateTimeFormatter pdfDateFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
            String purchaseDateStr = boughtInsurance.getPurchaseDate() != null ?
                                     boughtInsurance.getPurchaseDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().format(pdfDateFormatter) : "N/A";
            String expiryDateStr = boughtInsurance.getExpiryDate() != null ?
                                    boughtInsurance.getExpiryDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().format(pdfDateFormatter) : "N/A";


            // Call the existing generateInvoice method with the retrieved details
            generateInvoice(planName, coverage, premium, fullName, dob, address, emailId, policyNumber, purchaseDateStr, expiryDateStr, phoneNumber, response);

        } else {
            response.sendError(HttpServletResponse.SC_NOT_FOUND, "Invoice not found for the given ID.");
        }
    }

    @GetMapping("/claimInsuranceForm")
    public String claimInsuranceForm(
            @RequestParam("boughtInsuranceId") Long boughtInsuranceId,
            HttpSession session,
            Model model) {

        Long userId = (Long) session.getAttribute("userId");
        if (userId == null) {
            return "redirect:/login"; // Redirect to login if user is not authenticated
        }

        Optional<BoughtInsurance> boughtInsuranceOpt = boughtInsuranceService.findById(boughtInsuranceId);

        if (boughtInsuranceOpt.isPresent()) {
            BoughtInsurance boughtInsurance = boughtInsuranceOpt.get();

            // Security check: Ensure the policy belongs to the logged-in user
            // This prevents users from trying to claim policies that aren't theirs
            if (!boughtInsurance.getUser().getId().equals(userId)) {
                System.out.println("Unauthorized attempt to access claim form for policy ID: " + boughtInsuranceId + " by user ID: " + userId);
                model.addAttribute("error", "You are not authorized to claim this policy.");
                return "redirect:/viewInsurance"; // Redirect back with an error
            }

            // Check if policy is already claimed or expired
            Date currentDate = new Date(); // Get current date for comparison
            if (boughtInsurance.isClaimed()) {
                model.addAttribute("error", "This policy has already been claimed.");
                return "redirect:/viewInsurance"; // Redirect back with an error
            }
            if (boughtInsurance.getExpiryDate() != null && boughtInsurance.getExpiryDate().before(currentDate)) {
                 model.addAttribute("error", "This policy has expired and cannot be claimed.");
                 return "redirect:/viewInsurance"; // Redirect back with an error
            }


            // Pass the entire BoughtInsurance object to the model
            model.addAttribute("boughtInsurance", boughtInsurance);

            return "claimInsuranceForm"; // Go to the claim form JSP
        } else {
            model.addAttribute("error", "Policy not found.");
            return "redirect:/viewInsurance"; // Redirect if policy not found
        }
    }
    @PostMapping("/submitClaim")
    public String submitClaim(
            @RequestParam("boughtInsuranceId") Long boughtInsuranceId,
            @RequestParam("incidentDate") String incidentDateStr,
            @RequestParam("reason") String reason,
            HttpSession session,
            Model model) throws java.text.ParseException {

        Long userId = (Long) session.getAttribute("userId");
        if (userId == null) {
            return "redirect:/login";
        }

        Optional<User> userOpt = userService.findUserById(userId);
        if (userOpt.isEmpty()) {
            return "redirect:/login";
        }

        Optional<BoughtInsurance> boughtInsuranceOpt = boughtInsuranceService.findById(boughtInsuranceId);
        if (boughtInsuranceOpt.isPresent()) {
            BoughtInsurance boughtInsurance = boughtInsuranceOpt.get();

            // Security check: Ensure the policy belongs to the logged-in user
            if (!boughtInsurance.getUser().getId().equals(userId)) {
                model.addAttribute("error", "You are not authorized to claim this policy.");
                return "redirect:/viewInsurance";
            }

            // Check if policy is expired (still good to check here before even filing)
            Date currentDate = new Date();
            if (boughtInsurance.getExpiryDate() != null && boughtInsurance.getExpiryDate().before(currentDate)) {
                 model.addAttribute("error", "This policy has expired and cannot be claimed.");
                 return "redirect:/viewInsurance";
            }
           
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date incidentDate = sdf.parse(incidentDateStr);

            Claim claim = new Claim();
            claim.setBoughtInsurance(boughtInsurance);
            claim.setFilingDate(new Date()); // Current date when the user files it
            claim.setIncidentDate(incidentDate);
            claim.setReason(reason.replace("\n", "<br/>"));
            claim.setStatus("PENDING"); // Initial status when filed by user

            // --- Populate the new required fields for Claim entity ---
            User currentUser = userOpt.get(); // Get the current logged-in user
            claim.setUser(currentUser); // Set the user who filed the claim
            claim.setInsuranceName(boughtInsurance.getInsurance().getName()); // Get insurance name from bought policy

            // Populate customer details from the BoughtInsurance policy
            claim.setCustomerName(boughtInsurance.getName());
            claim.setCustomerEmail(boughtInsurance.getEmail());
            claim.setCustomerPhone(boughtInsurance.getPhone());
            // --- End population of new fields ---


            claimService.save(claim); // Save the new claim

            model.addAttribute("success", "Your claim has been filed successfully and is awaiting review!");
            return "redirect:/viewInsurance";

        } else {
            model.addAttribute("error", "Bought Insurance not found.");
            return "redirect:/viewInsurance";
        }
    }

    @GetMapping("/about")
    public String aboutPage() {
        return "about";
    }

    @GetMapping("/logout")
    public String logout(HttpSession session) {
        session.invalidate();
        return "index";
    }
}