<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\MorphMany;

class ServiceTicket extends Model
{
    /**
     * Daftar device_type yang valid.
     */
    const DEVICE_TYPES = ['Laptop', 'PC', 'Printer'];

    /**
     * Daftar status yang valid.
     */
    const STATUSES = ['Pickup Requested', 'Pending', 'Checking', 'Repairing', 'Ready', 'Picked Up', 'Cancelled'];

    protected $fillable = [
        'ticket_code',
        'customer_id',
        'device_type',
        'brand',
        'model',
        'serial_number',
        'problem_desc',
        'pickup_note',
        'initial_diagnosis',
        'diagnosis_findings',
        'probable_cause',
        'recommended_action',
        'estimated_cost',
        'estimated_minutes',
        'diagnosis_completed_at',
        'diagnosis_completed_by',
        'repair_summary',
        'parts_used',
        'final_check_notes',
        'final_check_items',
        'final_check_photo_path',
        'final_check_passed_at',
        'final_check_passed_by',
        'ready_at',
        'status',
        'cancel_reason',
        'picked_up_at',
        'cancelled_at',
        'repair_approved_at',
        'repair_approved_by',
    ];

    protected $casts = [
        'picked_up_at'  => 'datetime',
        'cancelled_at'  => 'datetime',
        'repair_approved_at' => 'datetime',
        'diagnosis_completed_at' => 'datetime',
        'final_check_passed_at' => 'datetime',
        'ready_at' => 'datetime',
        'estimated_cost' => 'decimal:2',
        'final_check_items' => 'array',
    ];

    public static function finalCheckTemplate(string $deviceType): array
    {
        return match ($deviceType) {
            'Laptop' => [
                'POST/boot normal tanpa error',
                'Layar normal (tanpa flicker/artefak)',
                'Keyboard dan touchpad berfungsi',
                'Baterai terdeteksi dan charging normal',
                'Port utama (USB/HDMI/Audio) berfungsi',
                'Koneksi WiFi/Bluetooth normal',
                'Speaker, mikrofon, dan webcam berfungsi',
                'Suhu/fan normal setelah uji singkat',
                'Restart dan shutdown normal',
            ],
            'PC' => [
                'POST/boot normal tanpa error',
                'Output display stabil',
                'Keyboard dan mouse berfungsi',
                'Port utama (USB/LAN/Audio) berfungsi',
                'Jaringan LAN/WiFi normal',
                'Audio input/output normal',
                'Suhu/fan normal setelah uji singkat',
                'Restart dan shutdown normal',
            ],
            'Printer' => [
                'Power on dan panel indikator normal',
                'Paper feed normal (tanpa jam)',
                'Self-test / test page berhasil',
                'Kualitas cetak normal (teks/garis/warna)',
                'Nozzle/alignment normal (jika tersedia)',
                'Tidak ada paper jam',
                'Koneksi USB/LAN/WiFi normal',
                'Fungsi scan/copy normal (untuk MFP)',
            ],
            default => [
                'Unit menyala normal',
                'Fungsi utama berjalan normal',
                'Tidak ada error kritikal',
            ],
        };
    }

    public static function finalCheckMinimumPass(string $deviceType): int
    {
        return match ($deviceType) {
            'Laptop', 'PC' => 5,
            'Printer' => 4,
            default => 2,
        };
    }

    public static function finalCheckRequiredItems(string $deviceType): array
    {
        return match ($deviceType) {
            'Laptop' => [
                'POST/boot normal tanpa error',
                'Layar normal (tanpa flicker/artefak)',
                'Keyboard dan touchpad berfungsi',
                'Baterai terdeteksi dan charging normal',
                'Port utama (USB/HDMI/Audio) berfungsi',
            ],
            'PC' => [
                'POST/boot normal tanpa error',
                'Output display stabil',
                'Keyboard dan mouse berfungsi',
                'Port utama (USB/LAN/Audio) berfungsi',
            ],
            'Printer' => [
                'Power on dan panel indikator normal',
                'Paper feed normal (tanpa jam)',
                'Self-test / test page berhasil',
                'Kualitas cetak normal (teks/garis/warna)',
            ],
            default => [
                'Unit menyala normal',
                'Fungsi utama berjalan normal',
            ],
        };
    }

    // ─────────────────────── Boot ───────────────────────

    protected static function booted(): void
    {
        static::creating(function (ServiceTicket $ticket) {
            if (empty($ticket->ticket_code)) {
                $ticket->ticket_code = static::generateTicketCode();
            }
        });
    }

    /**
     * Generate ticket_code dengan format SRV-YYYYMMDD-XXXX.
     * XXXX = 4 digit angka acak berbasis sequence hari ini.
     */
    public static function generateTicketCode(): string
    {
        $date   = now()->format('Ymd');
        $prefix = "SRV-{$date}-";

        $last = static::where('ticket_code', 'like', $prefix . '%')
            ->orderByDesc('ticket_code')
            ->value('ticket_code');

        $sequence = $last
            ? (int) substr($last, -4) + 1
            : 1;

        return $prefix . str_pad($sequence, 4, '0', STR_PAD_LEFT);
    }

    // ─────────────────────── Relationships ───────────────────────

    /**
     * Customer pemilik tiket ini.
     */
    public function customer(): BelongsTo
    {
        return $this->belongsTo(Customer::class, 'customer_id');
    }

    /**
     * Aset (foto & tanda tangan) untuk tiket ini.
     */
    public function asset(): HasOne
    {
        return $this->hasOne(ServiceAsset::class, 'ticket_id');
    }

    /**
     * Semua log aktivitas untuk tiket ini.
     */
    public function logs(): HasMany
    {
        return $this->hasMany(ServiceLog::class, 'ticket_id');
    }

    public function invoices(): HasMany
    {
        return $this->hasMany(Invoice::class, 'source_id')
            ->where('source_type', Invoice::SOURCE_SERVICE);
    }

    public function diagnosisTechnician(): BelongsTo
    {
        return $this->belongsTo(User::class, 'diagnosis_completed_by');
    }

    public function finalCheckTechnician(): BelongsTo
    {
        return $this->belongsTo(User::class, 'final_check_passed_by');
    }

    public function repairApprover(): BelongsTo
    {
        return $this->belongsTo(User::class, 'repair_approved_by');
    }

    // ─────────────────────── Helpers ───────────────────────

    /**
     * Tandai tiket sebagai "Picked Up" dan catat waktu.
     */
    public function markAsPickedUp(): void
    {
        $this->update([
            'status'       => 'Picked Up',
            'picked_up_at' => now(),
        ]);
    }

    /**
     * Tandai tiket sebagai "Cancelled" dan catat alasan.
     */
    public function cancel(string $reason): void
    {
        $this->update([
            'status'        => 'Cancelled',
            'cancel_reason' => $reason,
            'cancelled_at'  => now(),
        ]);
    }
}
