<?php

namespace App\Models;

use CodeIgniter\Model;

class TransportScheduleModel extends Model
{
    protected $table         = 'transport_schedules';
    protected $primaryKey    = 'id';
    protected $returnType    = 'array';
    protected $useTimestamps = true;
    protected $dateFormat    = 'datetime';

    protected $allowedFields = [
        'number', 'title', 'route_id', 'vehicle_id', 'driver_id', 'schedule_date',
        'departure_time', 'arrival_time', 'shift_start_time', 'shift_end_time',
        'return_departure_time', 'return_arrival_time',
        'priority', 'status', 'ai_flag', 'ai_flag_seen_at', 'notes', 'started_at', 'completed_at',
        'created_by', 'updated_by',
    ];

    public const STATUSES   = ['planned', 'scheduled', 'in_progress', 'completed', 'cancelled'];
    public const OPEN       = ['planned', 'scheduled', 'in_progress'];
    public const PRIORITIES = ['low', 'normal', 'high', 'urgent'];

    public function scopeForList(?string $search = null, ?string $status = null, ?string $dateFrom = null, ?string $dateTo = null): self
    {
        $this->select(
            'transport_schedules.*,
             routes.name AS route_name,
             routes.number AS route_number,
             vehicles.registration_number AS vehicle_registration,
             drivers.number AS driver_number,
             employees.full_name AS driver_name'
        )
            ->join('transport_routes AS routes', 'routes.id = transport_schedules.route_id', 'left')
            ->join('transport_vehicles AS vehicles', 'vehicles.id = transport_schedules.vehicle_id', 'left')
            ->join('transport_drivers AS drivers', 'drivers.id = transport_schedules.driver_id', 'left')
            ->join('employees', 'employees.id = drivers.employee_id', 'left');

        if ($search) {
            $this->groupStart()
                ->like('transport_schedules.number', $search)
                ->orLike('transport_schedules.title', $search)
                ->orLike('routes.name', $search)
                ->orLike('vehicles.registration_number', $search)
                ->groupEnd();
        }

        if ($status) {
            $this->where('transport_schedules.status', $status);
        }

        if ($dateFrom) {
            $this->where('transport_schedules.schedule_date >=', $dateFrom);
        }

        if ($dateTo) {
            $this->where('transport_schedules.schedule_date <=', $dateTo);
        }

        return $this;
    }

    public function nextNumber(): string
    {
        $prefix = 'TRP-' . date('ymd') . '-';
        $row    = $this->like('number', $prefix, 'after')->orderBy('id', 'DESC')->first();
        $seq    = 1;
        if ($row && preg_match('/-(\d+)$/', $row['number'], $m)) {
            $seq = (int) $m[1] + 1;
        }

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

    /**
     * @return array<string, int>
     */
    public function countByStatus(): array
    {
        $counts = array_fill_keys(self::STATUSES, 0);
        $rows   = $this->select('status, COUNT(*) AS cnt')->groupBy('status')->findAll();
        foreach ($rows as $row) {
            $counts[$row['status']] = (int) $row['cnt'];
        }

        return $counts;
    }

    /**
     * Schedules flagged by an AI plan approval that nobody has seen yet.
     */
    public function countUnseenAiFlags(): int
    {
        return $this->where('ai_flag IS NOT NULL')
            ->where('ai_flag_seen_at', null)
            ->countAllResults();
    }

    /**
     * Mark AI change flags as seen; the red indicator disappears afterwards.
     *
     * @param int[] $ids
     */
    public function markAiFlagsSeen(array $ids): void
    {
        if ($ids === []) {
            return;
        }

        $this->whereIn('id', $ids)
            ->where('ai_flag IS NOT NULL')
            ->where('ai_flag_seen_at', null)
            ->set('ai_flag_seen_at', date('Y-m-d H:i:s'))
            ->update();
    }

    public function getUpcoming(int $limit = 10): array
    {
        return $this->scopeForList()
            ->whereIn('transport_schedules.status', self::OPEN)
            ->where('transport_schedules.schedule_date >=', date('Y-m-d'))
            ->orderBy('transport_schedules.schedule_date', 'ASC')
            ->orderBy('transport_schedules.departure_time', 'ASC')
            ->findAll($limit);
    }
}
