<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

/**
 * 駐輪場管理者モデル - managerテーブル
 * 
 * 駐輪場管理者マスタ情報を管理するモデル
 * 各駐輪場に紐づく管理者の情報、警報送信設定などを保持
 */
class Manager extends Model
{
    /**
     * テーブル名
     *
     * @var string
     */
    protected $table = 'manager';

    /**
     * プライマリキー
     *
     * @var string
     */
    protected $primaryKey = 'manager_id';

    /**
     * タイムスタンプ使用
     *
     * @var bool
     */
    public $timestamps = true;

    const CREATED_AT = 'created_at';
    const UPDATED_AT = 'updated_at';

    /**
     * 一括代入可能な属性
     *
     * @var array
     */
    protected $fillable = [
        'manager_name',        // 管理者名
        'manager_type',        // 管理者種別
        'manager_parkid',      // 所属駐輪場ID
        'manager_device1',     // デバイス1
        'manager_device2',     // デバイス2
        'manager_mail',        // メールアドレス
        'manager_tel',         // 電話番号
        'manager_alert1',      // アラート送信フラグ1
        'manager_alert2',      // アラート送信フラグ2
        'manager_quit_flag',   // 退職フラグ
        'manager_quitday',     // 退職日
        'operator_id'          // 登録オペレータID
    ];

    /**
     * キャストする属性
     *
     * @var array
     */
    protected $casts = [
        'manager_id' => 'integer',
        'manager_parkid' => 'integer',
        'manager_device1' => 'integer',
        'manager_device2' => 'integer',
        'manager_alert1' => 'boolean',
        'manager_alert2' => 'boolean',
        'manager_quit_flag' => 'boolean',
        'operator_id' => 'integer',
        'manager_quitday' => 'date',
        'created_at' => 'datetime',
        'updated_at' => 'datetime'
    ];

    /**
     * 所属駐輪場との関連
     * 
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function park()
    {
        return $this->belongsTo(Park::class, 'manager_parkid', 'park_id');
    }

    /**
     * 登録オペレータとの関連
     * 
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function operator()
    {
        return $this->belongsTo(Ope::class, 'operator_id', 'ope_id');
    }

    /**
     * アクティブな管理者のみを取得するスコープ
     * （退職フラグ = 0）
     * 
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeActive($query)
    {
        return $query->where('manager_quit_flag', 0);
    }

    /**
     * メールアドレスが設定されている管理者のみを取得するスコープ
     * 
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeHasEmail($query)
    {
        return $query->whereNotNull('manager_mail')
                     ->where('manager_mail', '!=', '');
    }

    /**
     * 指定駐輪場の管理者を取得するスコープ
     * 
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param int $parkId 駐輪場ID
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeByPark($query, int $parkId)
    {
        return $query->where('manager_parkid', $parkId);
    }

    /**
     * メール送信対象の駐輪場管理者を取得
     * 
     * 条件：
     * - 退職フラグ = 0（在職中）
     * - メールアドレスが設定されている
     * 
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public static function getMailTargetManagers()
    {
        return self::active()
                   ->hasEmail()
                   ->select(['manager_id', 'manager_name', 'manager_mail', 'manager_parkid'])
                   ->get()
                   ->map(function ($manager) {
                       return [
                           'manager_id' => $manager->manager_id,
                           'name' => $manager->manager_name,
                           'email' => $manager->manager_mail,
                           'park_id' => $manager->manager_parkid
                       ];
                   });
    }

    /**
     * 指定駐輪場のメール送信対象管理者を取得
     * 
     * @param int $parkId 駐輪場ID
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public static function getMailTargetManagersByPark(int $parkId)
    {
        return self::active()
                   ->hasEmail()
                   ->byPark($parkId)
                   ->select(['manager_id', 'manager_name', 'manager_mail', 'manager_parkid'])
                   ->get()
                   ->map(function ($manager) {
                       return [
                           'manager_id' => $manager->manager_id,
                           'name' => $manager->manager_name,
                           'email' => $manager->manager_mail,
                           'park_id' => $manager->manager_parkid
                       ];
                   });
    }

    /**
     * 退職しているかどうかを判定
     * 
     * @return bool 退職しているかどうか
     */
    public function isQuit(): bool
    {
        return (bool) $this->manager_quit_flag;
    }

    /**
     * アクティブ（在職中）かどうかを判定
     * 
     * @return bool 在職中かどうか
     */
    public function isActive(): bool
    {
        return !$this->isQuit();
    }

    /**
     * メールアドレスが設定されているかどうかを判定
     * 
     * @return bool メールアドレスが設定されているかどうか
     */
    public function hasEmail(): bool
    {
        return !empty($this->manager_mail);
    }

    /**
     * 文字列表現
     * 
     * @return string
     */
    public function __toString(): string
    {
        return sprintf(
            'Manager[ID:%d, Name:%s, Park:%d, Email:%s]',
            $this->manager_id,
            $this->manager_name,
            $this->manager_parkid,
            $this->manager_mail ?? 'N/A'
        );
    }
}

