<?php

namespace app\models;

use yii\db\ActiveRecord;

/**
 * @property int    $id
 * @property string $entity_type  'course' | 'activity'
 * @property int    $entity_id
 * @property int    $tag_id
 * @property string $created_at
 *
 * @property Tag            $tag
 * @property Course         $course
 * @property CourseActivity $activity
 */
class EntityTag extends ActiveRecord
{
    const TYPE_COURSE   = 'course';
    const TYPE_ACTIVITY = 'activity';

    public static function tableName(): string
    {
        return '{{%entity_tag}}';
    }

    public function rules(): array
    {
        return [
            [['entity_type', 'entity_id', 'tag_id'], 'required'],
            [['entity_type'], 'in', 'range' => [self::TYPE_COURSE, self::TYPE_ACTIVITY]],
            [['entity_id', 'tag_id'], 'integer'],
        ];
    }

    public function getTag(): \yii\db\ActiveQuery
    {
        return $this->hasOne(Tag::class, ['id' => 'tag_id']);
    }

    public function getCourse(): \yii\db\ActiveQuery
    {
        return $this->hasOne(Course::class, ['id' => 'entity_id']);
    }

    public function getActivity(): \yii\db\ActiveQuery
    {
        return $this->hasOne(CourseActivity::class, ['id' => 'entity_id']);
    }

    /**
     * Load all Tag objects for a given entity in one query.
     *
     * @return Tag[]
     */
    public static function getTagsFor(string $entityType, int $entityId): array
    {
        return Tag::find()
            ->innerJoin('{{%entity_tag}} et', 'et.tag_id = {{%tag}}.id')
            ->where(['et.entity_type' => $entityType, 'et.entity_id' => $entityId])
            ->orderBy(['{{%tag}}.tag_name' => SORT_ASC])
            ->all();
    }

    /**
     * Load activity tags for multiple activity IDs in one query.
     * Returns [ activityId => Tag[], ... ]
     */
    public static function getActivityTagMap(array $activityIds): array
    {
        if (empty($activityIds)) {
            return [];
        }
        $ets = self::find()
            ->where(['entity_type' => self::TYPE_ACTIVITY])
            ->andWhere(['entity_id' => $activityIds])
            ->with('tag')
            ->all();

        $map = [];
        foreach ($ets as $et) {
            if ($et->tag) {
                $map[$et->entity_id][] = $et->tag;
            }
        }
        return $map;
    }
}
