<?php

namespace App\Models\Construction;

use App\Models\Members\User;
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\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;

/**
 * 인수인계보고서 모델
 *
 * @property int $id
 * @property int $tenant_id
 * @property string $report_number
 * @property int|null $contract_id
 * @property string $site_name
 * @property int|null $partner_id
 * @property string|null $partner_name
 * @property int|null $contract_manager_id
 * @property string|null $contract_manager_name
 * @property int|null $construction_pm_id
 * @property string|null $construction_pm_name
 * @property int $total_sites
 * @property float $contract_amount
 * @property string|null $contract_date
 * @property string|null $contract_start_date
 * @property string|null $contract_end_date
 * @property string|null $completion_date
 * @property string $status
 * @property bool $has_secondary_piping
 * @property float $secondary_piping_amount
 * @property string|null $secondary_piping_note
 * @property bool $has_coating
 * @property float $coating_amount
 * @property string|null $coating_note
 * @property array|null $external_equipment_cost
 * @property string|null $special_notes
 * @property bool $is_active
 * @property int|null $created_by
 * @property int|null $updated_by
 * @property int|null $deleted_by
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @property \Illuminate\Support\Carbon|null $deleted_at
 */
class HandoverReport extends Model
{
    use Auditable, BelongsToTenant, ModelTrait, SoftDeletes;

    protected $table = 'handover_reports';

    // 상태 상수
    public const STATUS_PENDING = 'pending';

    public const STATUS_COMPLETED = 'completed';

    protected $fillable = [
        'tenant_id',
        'report_number',
        'contract_id',
        'site_name',
        'partner_id',
        'partner_name',
        'contract_manager_id',
        'contract_manager_name',
        'construction_pm_id',
        'construction_pm_name',
        'total_sites',
        'contract_amount',
        'contract_date',
        'contract_start_date',
        'contract_end_date',
        'completion_date',
        'status',
        'has_secondary_piping',
        'secondary_piping_amount',
        'secondary_piping_note',
        'has_coating',
        'coating_amount',
        'coating_note',
        'external_equipment_cost',
        'special_notes',
        'is_active',
        'created_by',
        'updated_by',
        'deleted_by',
    ];

    protected $casts = [
        'total_sites' => 'integer',
        'contract_amount' => 'decimal:2',
        'contract_date' => 'date:Y-m-d',
        'contract_start_date' => 'date:Y-m-d',
        'contract_end_date' => 'date:Y-m-d',
        'completion_date' => 'date:Y-m-d',
        'has_secondary_piping' => 'boolean',
        'secondary_piping_amount' => 'decimal:2',
        'has_coating' => 'boolean',
        'coating_amount' => 'decimal:2',
        'external_equipment_cost' => 'array',
        'is_active' => 'boolean',
    ];

    protected $attributes = [
        'is_active' => true,
        'status' => self::STATUS_PENDING,
        'total_sites' => 0,
        'contract_amount' => 0,
        'has_secondary_piping' => false,
        'secondary_piping_amount' => 0,
        'has_coating' => false,
        'coating_amount' => 0,
    ];

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

    /**
     * 연결된 계약
     */
    public function contract(): BelongsTo
    {
        return $this->belongsTo(Contract::class, 'contract_id');
    }

    /**
     * 계약담당자
     */
    public function contractManager(): BelongsTo
    {
        return $this->belongsTo(User::class, 'contract_manager_id');
    }

    /**
     * 공사PM
     */
    public function constructionPm(): BelongsTo
    {
        return $this->belongsTo(User::class, 'construction_pm_id');
    }

    /**
     * 공사담당자 목록
     */
    public function managers(): HasMany
    {
        return $this->hasMany(HandoverReportManager::class, 'handover_report_id')
            ->orderBy('sort_order');
    }

    /**
     * 계약 ITEM 목록
     */
    public function items(): HasMany
    {
        return $this->hasMany(HandoverReportItem::class, 'handover_report_id')
            ->orderBy('item_no');
    }

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

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

    // =========================================================================
    // 스코프
    // =========================================================================

    /**
     * 상태별 필터
     */
    public function scopeStatus($query, string $status)
    {
        return $query->where('status', $status);
    }

    /**
     * 거래처별 필터
     */
    public function scopePartner($query, int $partnerId)
    {
        return $query->where('partner_id', $partnerId);
    }

    /**
     * 계약별 필터
     */
    public function scopeContract($query, int $contractId)
    {
        return $query->where('contract_id', $contractId);
    }

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

    /**
     * 상태 라벨 반환
     */
    public function getStatusLabelAttribute(): string
    {
        return match ($this->status) {
            self::STATUS_PENDING => '인수인계대기',
            self::STATUS_COMPLETED => '인수인계완료',
            default => $this->status,
        };
    }

    /**
     * 진행중 여부
     */
    public function isPending(): bool
    {
        return $this->status === self::STATUS_PENDING;
    }

    /**
     * 완료 여부
     */
    public function isCompleted(): bool
    {
        return $this->status === self::STATUS_COMPLETED;
    }

    /**
     * 장비 외 실행금액 합계
     */
    public function getExternalEquipmentTotalAttribute(): float
    {
        if (! $this->external_equipment_cost) {
            return 0;
        }

        return ($this->external_equipment_cost['shipping_cost'] ?? 0)
            + ($this->external_equipment_cost['high_altitude_work'] ?? 0)
            + ($this->external_equipment_cost['public_expense'] ?? 0);
    }
}
