<?php

/**
 * 感情分析クラス
 *
 */
class EmotionAnalyzer
{
    private const ARROGANCE_THRESHOLD = 1000;
    private const CAUTION_THRESHOLD = 500;
    private const FEAR_THRESHOLD = 50;
    private const ANGER_THRESHOLD = 20;
    private const ANGER_RATE = 10;
    private const ANGER_RAND_MIN = 0;
    private const ANGER_RAND_MAX = 100;

    /** @var int $turn ターン数 */
    private int $turn;

    /** @var BattleAble $subject 分析対象 */
    private BattleAble $subject;

    /** @var BattleAble $target 分析対象の対戦相手 */
    private BattleAble $target;

    /**
     * constructor
     *
     * @param int $turn ターン数
     * @param BattleAble $subject 分析対象
     * @param BattleAble $target 分析対象の対戦相手
     */
    public function __construct(int $turn, BattleAble $subject, BattleAble $target)
    {
        $this->turn = $turn;
        $this->subject = $subject;
        $this->target = $target;
    }

    /**
     * 感情を解析
     *
     * @return Emotion
     */
    public function analyze(): Emotion
    {
        if ($this->isArrogance()) {
            return Emotion::ARROGANCE;
        }

        if ($this->isCaution()) {
            return Emotion::CAUTION;
        }

        if ($this->isFear()) {
            return Emotion::FEAR;
        }

        if ($this->isAnger()) {
            return Emotion::ANGER;
        }

        return $this->subject instanceof HasEmotion ? $this->subject->getEmotion() : Emotion::COMMON;
    }

    /**
     * 慢心か
     *
     * @return bool true:慢心, false:非慢心
     */
    private function isArrogance(): bool
    {
        // ターンが初回で自身と対象の合計ステータスの差分が閾値以上であれば慢心
        if ($this->turn === Battle::TURN_DEFAULT) {
            return $this->subject->getTotalStatus() - $this->target->getTotalStatus() >= self::ARROGANCE_THRESHOLD;
        }

        return false;
    }

    /**
     * 警戒か
     *
     * @return bool
     */
    private function isCaution(): bool
    {
        // ターンが初回の次で、対象のHP差分が閾値以上の場合は警戒
        if ($this->turn === Battle::TURN_DEFAULT) {
            return $this->target->getTotalStatus() - $this->subject->getTotalStatus() >= self::CAUTION_THRESHOLD;
        }

        return false;
    }

    /**
     * 恐怖か
     *
     * @return bool
     */
    private function isFear(): bool
    {
        // ターンが初回の次で、対象のHP差分が閾値以下の場合は恐怖
        if ($this->turn === Battle::TURN_DEFAULT + 1) {
            return $this->subject->getHpRate() <= self::FEAR_THRESHOLD;
        }

        return false;
    }

    /**
     * 憤怒か
     *
     * @return bool
     */
    private function isAnger(): bool
    {
        // 自身の体力割愛が閾値以下の場合、一定確率で憤怒
        if ($this->subject->getHpRate() <= self::ANGER_THRESHOLD) {
            return RandomUtil::lottery(self::ANGER_RATE);
        }

        return false;
    }
}