<?php

namespace App\Models;

use App\Traits\GenerateUuid;
use App\Traits\RouteUuid;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\DB;

final class Remota extends Model
{
    use GenerateUuid;
    use HasFactory;
    use RouteUuid;


    protected $fillable = [
        'equipo',
        'tipo_router_id',
        'puerto',
        'ip_gestion',
        'ubicacion',
        'detalle',
        'zona',
        'encargado',
        'serial',
        'kit_serial',
        'antena_serial',
        'dia_corte',
        'dia_activacion',
        'metodo_de_pago_id',
        'correo_cuenta',
        'password_correo_cuenta',
        'fecha_cuenta',
        'cliente_id',
        'proveedor_id',
        'socio_id',
        'vendedor_id',
        'comision',
        'plan_id',
        'costo',
        'status',
        'uuid',
        'detalles_extra',
        'TxtIdentity',
    ];

    protected static $statuses = [
        'activo',
        'pausada',
        'inactivo',
        'pausada_por_pago',
    ];

    public static function getStatuses()
    {
        return self::$statuses;
    }

    // Mapeo de atributo lógico TxtIdentity a la columna física TxTIdentity
    public function getTxtIdentityAttribute()
    {
        return $this->attributes['TxTIdentity'] ?? null;
    }

    public function setTxtIdentityAttribute($value)
    {
        $this->attributes['TxTIdentity'] = $value;
    }

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

    public function tipoRouter(): BelongsTo
    {
        return $this->belongsTo(ModeloMikrotik::class);
    }
    public function proveedor(): BelongsTo
    {
        return $this->belongsTo(Proveedor::class);
    }

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

    public function vendedor(): BelongsTo
    {
        return $this->belongsTo(Vendedor::class);
    }
    public function metodo_pago(): BelongsTo
    {
        return $this->belongsTo(PaymentMethod::class, 'metodo_de_pago_id');
    }
    public function cobros()
    {
        return Cobranza::where('remota_id', $this->id)->get();
    }
    public function cobrosRemotas()
    {
        return $this->hasMany(Cobranza::class); // Asegúrate de que Cobro sea el modelo correcto
    }
    public function cobrosDel()
    {
        return $this->hasMany(Cobranza::class);
    }
    protected static function boot()
    {
        parent::boot();

        static::deleting(function ($remota) {
            // Obtener el pago pendiente más reciente
            $cobro = $remota->cobrosDel()->orderBy('created_at', 'desc')->first();

            // Si existe, eliminarlo
            if ($cobro) {
                $cobro->delete();
            }
        });
    }
    public function cobrosPagados()
    {
        return $this->cobros()->where('status', 'pagado');
    }
    public function cobrosPendientes()
    {
        return Cobranza::where('remota_id', $this->id)->where('status', 'pendiente')->get();
    }
    public function ultimoCobro()
    {
        return Cobranza::where('remota_id', $this->id)->where('status', 'pendiente')->orderBy('created_at', 'desc')->first();
    }

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

    public static function getActivas()
    {
        return self::where('status', 'activo')->get();
    }

    public static function getAgrupadasPorCorreo()
    {
        return self::select(
            'correo_cuenta',
            DB::raw('count(*) as total'), // Total de registros
            DB::raw('sum(planes.costo) as total_costo'), // Suma de los costos (todos los registros)
            DB::raw('GROUP_CONCAT(remotas.id SEPARATOR ",") as registros'), // Listado de IDs de registros
            DB::raw('count(case when remotas.status = "activo" then 1 end) as activas'), // Contar los activos
            DB::raw('sum(case when remotas.status = "activo" then planes.costo else 0 end) as total_costo_activas'), // Sumar solo el costo de las remotas activas
            DB::raw('GROUP_CONCAT(DISTINCT payment_methods.id SEPARATOR ",") as metodo_de_pago_id'), // Concatenar los IDs de los métodos de pago
            DB::raw('GROUP_CONCAT(DISTINCT payment_methods.name SEPARATOR ",") as metodo_de_pago'), // Concatenar los nombres de los métodos de pago
            DB::raw('GROUP_CONCAT(DISTINCT payment_methods.tope SEPARATOR ",") as metodo_de_pago_tope'), // Concatenar los valores de `tope` de payment_methods
            DB::raw('MAX(DAY(remotas.fecha_cuenta)) as dia_fecha_cuenta'), // Tomar el día de la fecha más reciente
            DB::raw('DATE_FORMAT(historial_de_recargas.fecha_de_recarga, "%d/%m/%Y") as fecha_de_recarga'),
            DB::raw('historial_de_recargas.id as historial_id'), // ID del historial de recargas
            // Nueva columna: cantidad de cuentas NO activas por correo
            DB::raw('(SELECT COUNT(*) FROM remotas r2 WHERE r2.correo_cuenta = remotas.correo_cuenta AND r2.status != "activo") as no_activas')
        )
            ->join('planes', 'planes.id', '=', 'remotas.plan_id') // Relación con la tabla planes
            ->join('payment_methods', 'payment_methods.id', '=', 'remotas.metodo_de_pago_id') // Relación con la tabla payment_methods
            ->leftJoin(
                DB::raw('(
                    SELECT id, correo_de_cuenta, fecha_de_recarga
                    FROM historial_de_recargas
                    WHERE id IN (
                        SELECT MAX(id)
                        FROM historial_de_recargas
                        GROUP BY correo_de_cuenta
                    )
                ) as historial_de_recargas'),
                'historial_de_recargas.correo_de_cuenta',
                '=',
                'correo_cuenta'
            ) // Subconsulta para obtener el último registro por correo
            ->groupBy('correo_cuenta', 'historial_de_recargas.fecha_de_recarga', 'historial_de_recargas.id') // Agrupar por correo y columnas adicionales
            ->get();
    }




        // "correo_cuenta" => "0@cloudsatllc.com"
        // "total" => 1
        // "total_costo" => "140.00"
        // "registros" => "170"
        // "activas" => 1
        // "no_activas" => 0
        // "total_costo_activas" => "140.00"
        // "metodo_de_pago_id" => 1
        // "metodo_de_pago" => "Efectivo"
        // "dia_fecha_cuenta" => 8
        // "metodo_de_pago_tope" => 8








    public function getDiaFechaDeCuentaAttribute()
    {
        $fecha = $this->fecha_cuenta;
        if ($fecha) {
            $fecha = new \DateTime($fecha);
            $fecha = $fecha->format('d');
            return $fecha;
        } else {
            return null;
        }
    }
    public function getFechaDeCuentaAttribute()
    {
        $fecha = $this->fecha_cuenta;
        if ($fecha) {
            $fecha = new \DateTime($fecha);
            $fecha = $fecha->format('d/m/Y');
            return $fecha;
        } else {
            return null;
        }
    }
    public function getFechaCorteAttribute()
    {
        $fecha = $this->dia_corte;
        if ($fecha) {
            $fecha = new \DateTime($fecha);
            $fecha = $fecha->format('d/m/Y');
            return $fecha;
        } else {
            return null;
        }
    }
    public function getFechaActivacionAttribute()
    {
        $fecha = $this->dia_activacion;
        if ($fecha) {
            $fecha = new \DateTime($fecha);
            $fecha = $fecha->format('d/m/Y');
            return $fecha;
        } else {
            return null;
        }
    }
    public function getestadoBadgeAttribute()
    {
        $estado = $this->status;
        if ($estado == 'activo') {
            return 'success';
        } elseif ($estado == 'inactivo') {
            return 'danger';
        } else {
            return 'warning';
        }
    }
    public function proximaAVencer()
    {
        $fechaCorte = Carbon::parse($this->dia_corte);
        $fechaActual = Carbon::now();

        $diferenciaDias = $fechaActual->diffInDays($fechaCorte);

        // return  $diferenciaDias <= 5;
        return $diferenciaDias < 0;
    }
    public function estaVencida()
    {
        $fechaCorte = Carbon::parse($this->dia_corte);
        $fechaActual = Carbon::now();

        $mismoMes = $fechaActual->month === $fechaCorte->month;
        $fechaActualMayor = $fechaActual->greaterThan($fechaCorte);

        return ($mismoMes && $fechaActualMayor) || $fechaActualMayor;
    }


    public function getColorPorVencimiento()
    {
        if ($this->proximaAVencer()) {
            return 'bg-warning';
        } elseif ($this->estaVencida()) {
            return 'bg-danger';
        } else {
            return 'bg-warning';
        }
    }
    public function getAtrasoPorVencimiento()
    {
        if ($this->proximaAVencer()) {
            return 'Proxima';
        } elseif ($this->estaVencida()) {
            return 'Vencida';
        } else {
            return 'Proxima';
        }
    }
    public function getFechaVencimientoCuentaAttribute()
    {
        $fecha = $this->fecha_cuenta;
        if ($fecha) {
            $fecha = new \DateTime($fecha);
            $fecha = $fecha->format('d/m/Y');
            return $fecha;
        } else {
            return null;
        }
    }
    public function getProximaFechaCobroAttribute()
    {
        $fecha = $this->dia_corte;
        $fecha = Carbon::parse($this->dia_corte);
        if ($fecha) {
            $fecha->addMonth();
            $fecha = $fecha->format('d/m/Y');
            return $fecha;
        } else {
            return null;
        }
    }
    public function toSearchableArray()
    {
        return [
            'equipo' => $this->equipo,
            'serial' => $this->serial,
            'antena_serial' => $this->antena_serial,
        ];
    }

    public function getUtilidadEstimada()
    {
        return $this->costo - ($this->comision + $this->plan->costo);
    }


    public function getCostoDeVenta()
    {
        return ($this->plan->costo + $this->comision);
    }

    public function scopeSearch(Builder $query, string $search)
    {
        return $query->orWhere('equipo', 'like', "%$search")
            ->orWhere('serial', 'like', "%$search")
            ->orWhere('antena_serial', 'like', "%$search");
    }
    // remotasPausadasPorPago
}
