package de.cannamanage.service;

import de.cannamanage.domain.enums.PlanTier;
import de.cannamanage.service.exception.QuotaExceededException;
import de.cannamanage.service.exception.QuotaViolationCode;
import de.cannamanage.service.repository.SubscriptionRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.UUID;

/**
 * Service to enforce plan tier restrictions on features.
 * 
 * Tier rules:
 * - Forum: only Pro/Enterprise (Starter/Trial → 403)
 * - Info Board: Starter = 5 posts/month, Pro/Enterprise = unlimited
 * - Events: all tiers (no limit)
 * - Notifications: all tiers
 */
@Slf4j
@Service
public class PlanTierService {

    private static final int STARTER_INFO_BOARD_MONTHLY_LIMIT = 5;
    private static final int STARTER_INFO_BOARD_CATEGORIES_LIMIT = 3;
    private static final int PRO_FORUM_CATEGORIES_LIMIT = 5;

    private final SubscriptionRepository subscriptionRepository;

    public PlanTierService(SubscriptionRepository subscriptionRepository) {
        this.subscriptionRepository = subscriptionRepository;
    }

    /**
     * Get the current plan tier for a club.
     */
    public PlanTier getClubTier(UUID clubId) {
        return subscriptionRepository.findByClubId(clubId)
                .map(sub -> sub.getPlanTier())
                .orElse(PlanTier.TRIAL);
    }

    /**
     * Check if a club has access to the forum feature.
     * Forum is only available for Pro and Enterprise tiers.
     * 
     * @throws QuotaExceededException if the club's tier doesn't support forum
     */
    public void requireForumAccess(UUID clubId) {
        PlanTier tier = getClubTier(clubId);
        if (tier == PlanTier.STARTER || tier == PlanTier.TRIAL) {
            log.debug("Forum access denied for club {} (tier: {})", clubId, tier);
            throw new QuotaExceededException(
                    QuotaViolationCode.TIER_UPGRADE_REQUIRED,
                    "Forum ist nur im Pro- oder Enterprise-Tarif verfügbar. " +
                    "Bitte upgrade deinen Tarif, um das Forum zu nutzen."
            );
        }
    }

    /**
     * Check if a club can create a new forum category.
     * Pro: max 5 categories, Enterprise: unlimited.
     * 
     * @throws QuotaExceededException if the category limit is reached
     */
    public void checkForumCategoryLimit(UUID clubId, int currentCategoryCount) {
        PlanTier tier = getClubTier(clubId);
        if (tier == PlanTier.PRO && currentCategoryCount >= PRO_FORUM_CATEGORIES_LIMIT) {
            throw new QuotaExceededException(
                    QuotaViolationCode.TIER_UPGRADE_REQUIRED,
                    "Im Pro-Tarif sind maximal " + PRO_FORUM_CATEGORIES_LIMIT + " Forum-Kategorien möglich. " +
                    "Upgrade auf Enterprise für unbegrenzte Kategorien."
            );
        }
    }

    /**
     * Check if a club can create a new info board post this month.
     * Starter: max 5/month, Pro/Enterprise: unlimited.
     * 
     * @throws QuotaExceededException if the monthly post limit is reached
     */
    public void checkInfoBoardPostLimit(UUID clubId, int postsThisMonth) {
        PlanTier tier = getClubTier(clubId);
        if ((tier == PlanTier.STARTER || tier == PlanTier.TRIAL)
                && postsThisMonth >= STARTER_INFO_BOARD_MONTHLY_LIMIT) {
            throw new QuotaExceededException(
                    QuotaViolationCode.TIER_UPGRADE_REQUIRED,
                    "Im Starter-Tarif sind maximal " + STARTER_INFO_BOARD_MONTHLY_LIMIT +
                    " Beiträge pro Monat im Schwarzen Brett möglich. " +
                    "Upgrade auf Pro für unbegrenzte Beiträge."
            );
        }
    }

    /**
     * Check if a club can create a new info board category.
     * Starter: max 3 categories, Pro/Enterprise: unlimited.
     * 
     * @throws QuotaExceededException if the category limit is reached
     */
    public void checkInfoBoardCategoryLimit(UUID clubId, int currentCategoryCount) {
        PlanTier tier = getClubTier(clubId);
        if ((tier == PlanTier.STARTER || tier == PlanTier.TRIAL)
                && currentCategoryCount >= STARTER_INFO_BOARD_CATEGORIES_LIMIT) {
            throw new QuotaExceededException(
                    QuotaViolationCode.TIER_UPGRADE_REQUIRED,
                    "Im Starter-Tarif sind maximal " + STARTER_INFO_BOARD_CATEGORIES_LIMIT +
                    " Kategorien im Schwarzen Brett möglich. Upgrade auf Pro für mehr."
            );
        }
    }

    /**
     * Check if a club has Enterprise tier (for custom FROM address feature).
     * 
     * @throws QuotaExceededException if the club is not Enterprise
     */
    public void requireEnterpriseTier(UUID clubId) {
        PlanTier tier = getClubTier(clubId);
        if (tier != PlanTier.ENTERPRISE) {
            throw new QuotaExceededException(
                    QuotaViolationCode.TIER_UPGRADE_REQUIRED,
                    "Diese Funktion ist nur im Enterprise-Tarif verfügbar."
            );
        }
    }

    /**
     * Check if a club has at least Pro tier.
     */
    public boolean isProOrHigher(UUID clubId) {
        PlanTier tier = getClubTier(clubId);
        return tier == PlanTier.PRO || tier == PlanTier.ENTERPRISE;
    }

    /**
     * Check if a club has Enterprise tier.
     */
    public boolean isEnterprise(UUID clubId) {
        return getClubTier(clubId) == PlanTier.ENTERPRISE;
    }
}
