package dev.lions.user.manager.client.exception;

import jakarta.faces.application.ViewExpiredException;
import jakarta.faces.context.ExceptionHandler;
import jakarta.faces.context.ExceptionHandlerWrapper;
import jakarta.faces.context.FacesContext;
import jakarta.faces.event.ExceptionQueuedEvent;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.util.Iterator;

/**
 * Redirige vers la page d'accueil lorsque la vue a expiré (session ou state saving),
 * au lieu d'afficher une stack trace.
 */
public class ViewExpiredExceptionHandler extends ExceptionHandlerWrapper {

    private final ExceptionHandler wrapped;

    public ViewExpiredExceptionHandler(ExceptionHandler wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public ExceptionHandler getWrapped() {
        return wrapped;
    }

    @Override
    public void handle() {
        Iterator<ExceptionQueuedEvent> it = getUnhandledExceptionQueuedEvents().iterator();
        while (it.hasNext()) {
            ExceptionQueuedEvent event = it.next();
            Throwable t = event.getContext().getException();
            if (t instanceof ViewExpiredException) {
                it.remove();
                FacesContext fc = FacesContext.getCurrentInstance();
                if (fc != null && !fc.getResponseComplete()) {
                    try {
                        String ctx = fc.getExternalContext().getRequestContextPath();
                        fc.getExternalContext().redirect(ctx == null || ctx.isEmpty() ? "/" : ctx + "/");
                        fc.responseComplete();
                    } catch (IOException e) {
                        // fallback: set status and let default handling
                        HttpServletResponse resp = (HttpServletResponse) fc.getExternalContext().getResponse();
                        if (resp != null && !resp.isCommitted()) {
                            resp.setStatus(HttpServletResponse.SC_FOUND);
                            try {
                                resp.sendRedirect(fc.getExternalContext().getRequestContextPath() + "/");
                            } catch (IOException ignored) {
                            }
                        }
                    }
                }
                return;
            }
        }
        getWrapped().handle();
    }
}
