<?php

namespace App\Models\Tenants;

use App\Models\Members\User;
use App\Models\Orders\Client;
use App\Traits\Auditable;
use App\Traits\BelongsToTenant;
use App\Traits\ModelTrait;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;

/**
 * 현장 모델
 *
 * @property int $id
 * @property int $tenant_id
 * @property string|null $site_code 현장코드
 * @property int|null $client_id 거래처 ID
 * @property string $name
 * @property string|null $address
 * @property float|null $latitude
 * @property float|null $longitude
 * @property bool $is_active
 * @property string $status 상태: unregistered|suspended|active|pending
 * @property int|null $created_by
 * @property int|null $updated_by
 * @property int|null $deleted_by
 * @property-read Client|null $client
 */
class Site extends Model
{
    use Auditable, BelongsToTenant, ModelTrait, SoftDeletes;

    protected $table = 'sites';

    // 상태 상수
    public const STATUS_UNREGISTERED = 'unregistered';

    public const STATUS_SUSPENDED = 'suspended';

    public const STATUS_ACTIVE = 'active';

    public const STATUS_PENDING = 'pending';

    public const STATUSES = [
        self::STATUS_UNREGISTERED,
        self::STATUS_SUSPENDED,
        self::STATUS_ACTIVE,
        self::STATUS_PENDING,
    ];

    protected $fillable = [
        'tenant_id',
        'site_code',
        'client_id',
        'name',
        'address',
        'latitude',
        'longitude',
        'is_active',
        'status',
        'created_by',
        'updated_by',
        'deleted_by',
    ];

    protected $casts = [
        'latitude' => 'decimal:8',
        'longitude' => 'decimal:8',
        'is_active' => 'boolean',
    ];

    protected $attributes = [
        'is_active' => true,
        'status' => self::STATUS_UNREGISTERED,
    ];

    // =========================================================================
    // 관계 정의
    // =========================================================================

    /**
     * 생성자
     */
    public function creator(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    /**
     * 수정자
     */
    public function updater(): BelongsTo
    {
        return $this->belongsTo(User::class, 'updated_by');
    }

    /**
     * 거래처
     */
    public function client(): BelongsTo
    {
        return $this->belongsTo(Client::class);
    }

    // =========================================================================
    // 헬퍼 메서드
    // =========================================================================

    /**
     * GPS 좌표 설정 여부
     */
    public function hasCoordinates(): bool
    {
        return $this->latitude !== null && $this->longitude !== null;
    }

    /**
     * 좌표가 허용 범위 내인지 확인
     */
    public function isWithinRadius(float $latitude, float $longitude, int $radiusMeters = 100): bool
    {
        if (! $this->hasCoordinates()) {
            return true; // 좌표 미설정 시 항상 허용
        }

        $distance = $this->calculateDistance(
            $this->latitude,
            $this->longitude,
            $latitude,
            $longitude
        );

        return $distance <= $radiusMeters;
    }

    /**
     * 두 좌표 간 거리 계산 (미터)
     */
    private function calculateDistance(float $lat1, float $lon1, float $lat2, float $lon2): float
    {
        $earthRadius = 6371000;

        $lat1Rad = deg2rad($lat1);
        $lat2Rad = deg2rad($lat2);
        $deltaLat = deg2rad($lat2 - $lat1);
        $deltaLon = deg2rad($lon2 - $lon1);

        $a = sin($deltaLat / 2) * sin($deltaLat / 2) +
            cos($lat1Rad) * cos($lat2Rad) *
            sin($deltaLon / 2) * sin($deltaLon / 2);

        $c = 2 * atan2(sqrt($a), sqrt(1 - $a));

        return $earthRadius * $c;
    }
}
