<?php

namespace App\Models\Sale;

use App\Models\Agency\Agency;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\Storage;

/**
 * Satışa bağlı fatura kaydı (satış quick-view "Faturalar" sekmesi).
 */
class SaleInvoice extends Model
{
    protected $table = 'sale_invoices';

    public const TYPES = [
        'sale'   => 'Satış Faturası',
        'refund' => 'İade Faturası',
    ];

    public const STATUSES = [
        'draft'     => 'Taslak',
        'issued'    => 'Kesildi',
        'paid'      => 'Ödendi',
        'cancelled' => 'İptal',
    ];

    public const STATUS_COLORS = [
        'draft'     => '#64748b',
        'issued'    => '#2563eb',
        'paid'      => '#059669',
        'cancelled' => '#ef4444',
    ];

    public const BILLING_TYPES = [
        'individual' => 'Şahıs',
        'company'    => 'Şirket',
    ];

    /** Resmi fatura (GİB/e-Arşiv entegrasyonu — ileride bağlanacak) durumu */
    public const OFFICIAL_STATUSES = [
        'pending'   => 'Bekliyor',
        'issued'    => 'Kesildi',
        'cancelled' => 'İptal Edildi',
    ];

    public const OFFICIAL_STATUS_COLORS = [
        'pending'   => '#d97706',
        'issued'    => '#059669',
        'cancelled' => '#ef4444',
    ];

    protected $fillable = [
        'agency_id', 'sale_id', 'customer_id', 'created_by', 'invoice_number', 'invoice_type',
        'billing_type', 'billing_snapshot', 'items',
        'issue_date', 'subtotal', 'discount_total', 'tax_total', 'amount', 'paid_amount', 'currency', 'status', 'notes', 'description',
        'official_status', 'official_issued_at',
        'file_path', 'file_name', 'file_size',
    ];

    protected function casts(): array
    {
        return [
            'issue_date'       => 'date',
            'official_issued_at' => 'datetime',
            'billing_snapshot' => 'array',
            'items'            => 'array',
            'subtotal'         => 'decimal:2',
            'discount_total'   => 'decimal:2',
            'tax_total'        => 'decimal:2',
            'amount'           => 'decimal:2',
            'paid_amount'      => 'decimal:2',
            'file_size'        => 'integer',
        ];
    }

    /** Bu faturaya işlenmiş ödemeler. */
    public function payments()
    {
        return $this->hasMany(\App\Models\Payment\Payment::class, 'invoice_id')->orderByDesc('paid_at');
    }

    /** Faturanın kalan bakiyesi (tahsil edilmemiş tutar). */
    public function getRemainingAmountAttribute(): float
    {
        return round(max(0, (float) $this->amount - (float) $this->paid_amount), 2);
    }

    /** Kısmi tahsilat var mı? */
    public function getIsPartiallyPaidAttribute(): bool
    {
        return (float) $this->paid_amount > 0 && $this->remaining_amount > 0;
    }

    /**
     * Kalem listesinden toplamları hesaplar ve modele yazar (kaydetmez).
     * Kalem: {name, quantity, unit_price, tax_rate, discount_type, discount_value}
     */
    public function recalcFromItems(): void
    {
        $subtotal = 0.0;
        $discount = 0.0;
        $tax = 0.0;
        $total = 0.0;

        foreach ((array) $this->items as $item) {
            $break = SaleItem::breakdown(
                (float) ($item['quantity'] ?? 1),
                (float) ($item['unit_price'] ?? 0),
                (float) ($item['tax_rate'] ?? 0),
                false,
                (string) ($item['discount_type'] ?? 'percent'),
                (float) ($item['discount_value'] ?? 0)
            );

            $subtotal += $break['subtotal'];
            $discount += $break['discount'];
            $tax += $break['tax'];
            $total += $break['total'];
        }

        $this->subtotal = round($subtotal, 2);
        $this->discount_total = round($discount, 2);
        $this->tax_total = round($tax, 2);
        $this->amount = round($total, 2);
    }

    /** Fatura muhatabının görünen adı (şirketse unvan, şahıssa ad soyad). */
    public function getBillingNameAttribute(): string
    {
        $snap = $this->billing_snapshot ?? [];

        return $this->billing_type === 'company'
            ? ($snap['company_name'] ?? $snap['name'] ?? '—')
            : ($snap['name'] ?? '—');
    }

    public function getBillingTypeLabelAttribute(): string
    {
        return self::BILLING_TYPES[$this->billing_type] ?? $this->billing_type;
    }

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

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

    public function customer(): BelongsTo
    {
        return $this->belongsTo(\App\Models\Customer\Customer::class);
    }

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

    public function getTypeLabelAttribute(): string
    {
        return self::TYPES[$this->invoice_type] ?? $this->invoice_type;
    }

    public function getStatusLabelAttribute(): string
    {
        return self::STATUSES[$this->status] ?? $this->status;
    }

    public function getStatusColorAttribute(): string
    {
        return self::STATUS_COLORS[$this->status] ?? '#64748b';
    }

    public function getOfficialStatusLabelAttribute(): string
    {
        return self::OFFICIAL_STATUSES[$this->official_status] ?? (string) $this->official_status;
    }

    public function getOfficialStatusColorAttribute(): string
    {
        return self::OFFICIAL_STATUS_COLORS[$this->official_status] ?? '#64748b';
    }

    public function getFileUrlAttribute(): ?string
    {
        return $this->file_path ? Storage::url($this->file_path) : null;
    }

    public function getFormattedSizeAttribute(): ?string
    {
        if (!$this->file_size) {
            return null;
        }
        $kb = $this->file_size / 1024;

        return $kb >= 1024 ? number_format($kb / 1024, 1) . ' MB' : number_format($kb, 0) . ' KB';
    }
}
