<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class TrasladoPrenda extends Model
{
    protected $table = 'traslados_prenda';

    protected $fillable = [
        'orden_produccion_id',
        'referencia_type',
        'referencia_id',
        'origen',
        'destino',
        'cantidad_enviada',
        'cantidad_recibida',
        'prendas_defectuosas',
        'reparaciones',
        'saldos',
        'residual',
        'fecha_envio',
        'fecha_recepcion',
        'estado',
        'ingresado_por',
        'notas',
    ];

    protected $casts = [
        'fecha_envio' => 'datetime',
        'fecha_recepcion' => 'datetime',
    ];

    public function ordenProduccion()
    {
        return $this->belongsTo(OrdenProduccion::class);
    }

    public function referencia()
    {
        return $this->morphTo();
    }

    public function ingresadoPor()
    {
        return $this->belongsTo(User::class, 'ingresado_por');
    }

    public static function crearDesdeReferencia(Model $referencia, string $origen, string $destino, array $payload = []) : self
    {
        $defaults = [
            'orden_produccion_id' => $referencia->orden_produccion_id,
            'referencia_type' => get_class($referencia),
            'referencia_id' => $referencia->id,
            'origen' => $origen,
            'destino' => $destino,
            'cantidad_enviada' => $payload['cantidad_enviada'] ?? ($referencia->cantidad_enviada ?? 0),
            'cantidad_recibida' => $payload['cantidad_recibida'] ?? ($referencia->cantidad_recibida ?? null),
            'prendas_defectuosas' => $payload['prendas_defectuosas'] ?? ($referencia->prendas_defectuosas ?? 0),
            'reparaciones' => $payload['reparaciones'] ?? ($referencia->reparaciones ?? 0),
            'saldos' => $payload['saldos'] ?? ($referencia->saldos ?? 0),
            'fecha_envio' => $payload['fecha_envio'] ?? ($referencia->fecha_envio ?? null),
            'fecha_recepcion' => $payload['fecha_recepcion'] ?? ($referencia->fecha_recepcion ?? null),
            'estado' => 'recibido',
        ];

        $cantidad_enviada = (int) $defaults['cantidad_enviada'];
        $cantidad_recibida = (int) ($defaults['cantidad_recibida'] ?? 0);
        $prendas_defectuosas = (int) ($defaults['prendas_defectuosas'] ?? 0);
        $reparaciones = (int) ($defaults['reparaciones'] ?? 0);
        $saldos = (int) ($defaults['saldos'] ?? 0);

        $defaults['residual'] = $cantidad_enviada - ($cantidad_recibida + $prendas_defectuosas + $reparaciones + $saldos);

        $traslado = self::create($defaults);

        // Si el traslado es a bodega y la OP ya está finalizada, crear inventario (si no existe)
        if ($traslado->destino === 'bodega') {
            $traslado->maybeCreateInventory();
        }

        return $traslado;
    }

    public function markAsReceived(array $data = [], $userId = null)
    {
        // Actualizar campos si se envían
        $this->cantidad_recibida = $data['cantidad_recibida'] ?? $this->cantidad_recibida;
        $this->prendas_defectuosas = $data['prendas_defectuosas'] ?? $this->prendas_defectuosas ?? 0;
        $this->reparaciones = $data['reparaciones'] ?? $this->reparaciones ?? 0;
        $this->saldos = $data['saldos'] ?? $this->saldos ?? 0;
        $this->fecha_recepcion = $data['fecha_recepcion'] ?? now();
        $this->estado = 'recibido';

        // Si cantidad_recibida no se proporcionó, inferirla
        if ($this->cantidad_recibida === null) {
            $this->cantidad_recibida = (int) $this->cantidad_enviada - ((int) $this->prendas_defectuosas + (int) $this->reparaciones + (int) $this->saldos);
            if ($this->cantidad_recibida < 0) {
                $this->cantidad_recibida = 0;
            }
        }

        if ($userId) {
            $this->ingresado_por = $userId;
        }

        $this->residual = (int) $this->cantidad_enviada - ((int) $this->cantidad_recibida + (int) $this->prendas_defectuosas + (int) $this->reparaciones + (int) $this->saldos);

        $this->save();

        // Si destino bodega, intentar crear inventario
        if ($this->destino === 'bodega') {
            $this->maybeCreateInventory();
        }

        return $this;
    }

    protected function maybeCreateInventory()
    {
        $op = $this->ordenProduccion;
        if (! $op) return;

        if ($op->estado === 'finalizada' && !\App\Models\InventarioPrenda::where('orden_produccion_id', $op->id)->exists()) {
            $cantidad = self::where('orden_produccion_id', $op->id)
                ->where('destino', 'bodega')
                ->sum('cantidad_recibida');

            if ($cantidad > 0) {
                \App\Models\InventarioPrenda::create([
                    'orden_produccion_id' => $op->id,
                    'cantidad_terminada' => $cantidad,
                    'cantidad_disponible' => $cantidad,
                    'fecha_ingreso' => now(),
                    'estado' => 'en_bodega',
                ]);
            }
        }
    }
}
