<?php

declare(strict_types=1);

namespace App\Domain\Backup\Models;

use App\Domain\Account\Models\Account;
use App\Domain\Backup\Enums\BackupStatus;
use Database\Factories\BackupFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;

class Backup extends Model
{
    /** @use HasFactory<BackupFactory> */
    use HasFactory, SoftDeletes;

    protected $table = 'backups';

    protected $fillable = [
        'account_id', 'parent_backup_id', 'chain_id', 'is_chain_head', 'chain_position',
        'type', 'trigger', 'file_path', 'size_bytes', 'sha256',
        'status', 'last_error', 'started_at', 'completed_at', 'expires_at',
        'contents', 'manifest',
    ];

    protected function casts(): array
    {
        return [
            'status' => BackupStatus::class,
            'contents' => 'array',
            'manifest' => 'array',
            'started_at' => 'datetime',
            'completed_at' => 'datetime',
            'expires_at' => 'datetime',
            'size_bytes' => 'integer',
            'is_chain_head' => 'boolean',
            'chain_position' => 'integer',
        ];
    }

    /**
     * Bu backup'ın bağlı olduğu önceki backup (incremental zincirinde).
     */
    public function parent(): BelongsTo
    {
        return $this->belongsTo(Backup::class, 'parent_backup_id');
    }

    /**
     * Aynı chain_id'ye sahip tüm yedekleri full→latest sırasıyla döner.
     * Restore için chain'i toplamada kullanılır.
     *
     * @return \Illuminate\Database\Eloquent\Collection<int, self>
     */
    public function chainSequence(): \Illuminate\Database\Eloquent\Collection
    {
        if (! $this->chain_id) {
            return collect([$this])->all() instanceof \Illuminate\Database\Eloquent\Collection
                ? collect([$this])
                : \Illuminate\Database\Eloquent\Collection::make([$this]);
        }

        return static::where('chain_id', $this->chain_id)
            ->orderBy('chain_position')
            ->get();
    }

    /**
     * Bu backup incremental mi?
     */
    public function isIncremental(): bool
    {
        return $this->type === 'incremental';
    }

    /**
     * Bu backup chain başı (full) mı?
     */
    public function isChainHead(): bool
    {
        return $this->is_chain_head || ($this->type === 'full' && $this->parent_backup_id === null);
    }

    public function account(): BelongsTo
    {
        return $this->belongsTo(Account::class);
    }

    public function durationSeconds(): ?int
    {
        if (! $this->started_at || ! $this->completed_at) {
            return null;
        }

        return $this->started_at->diffInSeconds($this->completed_at);
    }

    protected static function newFactory(): BackupFactory
    {
        return BackupFactory::new();
    }
}
