package com.mzh.library.service.impl;

import com.mzh.library.dao.ReportDao;
import com.mzh.library.entity.AuthenticatedUser;
import com.mzh.library.entity.Permission;
import com.mzh.library.entity.ReportCenter;
import com.mzh.library.exception.DaoException;
import com.mzh.library.service.PermissionPolicy;
import com.mzh.library.service.ReportService;
import com.mzh.library.service.ServiceResult;

import java.util.logging.Level;
import java.util.logging.Logger;

public class ReportServiceImpl implements ReportService {
    private static final Logger LOGGER = Logger.getLogger(ReportServiceImpl.class.getName());
    private static final String UNAVAILABLE_MESSAGE =
        "报表服务暂时不可用，请稍后重试。";
    private static final String DENIED_MESSAGE = "您无权查看报表。";
    private static final int POPULAR_BOOK_LIMIT = 10;

    private final ReportDao reportDao;
    private final PermissionPolicy permissionPolicy;

    public ReportServiceImpl(ReportDao reportDao) {
        this(reportDao, new PermissionPolicy());
    }

    public ReportServiceImpl(ReportDao reportDao, PermissionPolicy permissionPolicy) {
        this.reportDao = reportDao;
        this.permissionPolicy = permissionPolicy;
    }

    @Override
    public ServiceResult<ReportCenter> loadReportCenter(AuthenticatedUser actor) {
        if (!canViewReports(actor)) {
            return ServiceResult.failure(DENIED_MESSAGE);
        }

        try {
            ReportCenter reportCenter = new ReportCenter();
            reportCenter.setInventorySummary(reportDao.loadInventorySummary());
            reportCenter.setBorrowingSummary(reportDao.loadBorrowingSummary());
            reportCenter.setOverdueRows(reportDao.findOverdueRows());
            reportCenter.setPopularBooks(reportDao.findPopularBooks(POPULAR_BOOK_LIMIT));
            return ServiceResult.success(reportCenter);
        } catch (DaoException ex) {
            LOGGER.log(Level.SEVERE, "Unable to load report center actorId=" + actor.getId(), ex);
            return ServiceResult.failure(UNAVAILABLE_MESSAGE);
        }
    }

    private boolean canViewReports(AuthenticatedUser actor) {
        return actor != null && permissionPolicy.allows(actor.getRole(), Permission.VIEW_REPORTS);
    }
}
