<?php
/**
 * TripAttachments — photos/documents attached to a trip.
 *
 * Two producer paths:
 *   * Web (dispatcher / ops): multipart upload via TripAttachmentsController::uploadAction
 *   * Mobile (driver): base64 in JSON via ApiController::tripAttachAction
 *                       (also called by ApiController::tripStartAction when the
 *                        driver takes plates/cargo/odometer photos at start).
 *
 * Attachments live under uploads/trip/{trip_id}/ so file listings and
 * housekeeping stay simple.
 */
class TripAttachments extends Model
{
    public const CATEGORIES = [
        'truck_plate_horse'   => 'Truck plate (horse)',
        'truck_plate_trailer' => 'Trailer plate',
        'truck_front'         => 'Truck front',
        'cargo_loadout'       => 'Cargo (loading)',
        'odometer_start'      => 'Odometer at start',
        'damage'              => 'Damage',
        'incident'            => 'Incident',
        'pod_signature'       => 'POD signature',
        'pod_photo'           => 'POD photo',
        'cargo_received'      => 'Cargo (received)',
        'odometer_end'        => 'Odometer at end',
        'dropoff_site'        => 'Dropoff site',
        'receipt'             => 'Receipt',
        'other'               => 'Other',
    ];

    /** Categories that are captured at trip-start on the mobile app. */
    public const START_CATEGORIES = [
        'truck_plate_horse', 'truck_plate_trailer', 'truck_front', 'cargo_loadout', 'odometer_start',
    ];

    public function forTrip(int $tripId): array
    {
        return (new DB())->mySelect(
            "SELECT a.c0d, a.category, a.caption, a.file_url, a.file_name, a.file_size, a.mime_type,
                    a.taken_at, a.taken_lat, a.taken_lng, a.source, a.trip_stop_id,
                    a.uploaded_by, a.driver_id, a.created_on,
                    u.full_name AS uploaded_by_name, d.full_name AS driver_name
               FROM trip_attachments a
          LEFT JOIN users   u ON u.c0d = a.uploaded_by
          LEFT JOIN drivers d ON d.c0d = a.driver_id
              WHERE a.trip_id = :tid AND a.deleted = 0
           ORDER BY FIELD(a.category, 'truck_plate_horse','truck_plate_trailer','truck_front','cargo_loadout','odometer_start','damage','incident','pod_signature','pod_photo','cargo_received','odometer_end','dropoff_site','receipt','other'),
                    a.created_on ASC",
            [':tid' => $tripId]
        ) ?: [];
    }

    public function byId(int $id): array
    {
        $rs = (new DB())->mySelect("SELECT * FROM trip_attachments WHERE c0d = :id AND deleted = 0 LIMIT 1", [':id' => $id]);
        return $rs[0] ?? [];
    }

    /**
     * Persist one attachment row. Caller has already saved the file on disk
     * and knows its public URL. Returns the new attachment id.
     */
    public function create(array $d): int
    {
        $r = (new DB())->insertUpdate(
            "INSERT INTO trip_attachments
                (tenant_id, trip_id, trip_stop_id, category, caption,
                 file_url, file_name, file_size, mime_type,
                 taken_at, taken_lat, taken_lng, source, uploaded_by, driver_id, created_on)
             VALUES
                (:tenant, :tid, :sid, :cat, :cap,
                 :url, :name, :size, :mime,
                 :tat, :tlat, :tlng, :src, :uu, :du, NOW())",
            [
                ':tenant' => defined('DEFAULT_TENANT_ID') ? DEFAULT_TENANT_ID : 1,
                ':tid'    => (int)$d['trip_id'],
                ':sid'    => !empty($d['trip_stop_id']) ? (int)$d['trip_stop_id'] : null,
                ':cat'    => isset(self::CATEGORIES[$d['category'] ?? '']) ? $d['category'] : 'other',
                ':cap'    => isset($d['caption']) ? mb_substr((string)$d['caption'], 0, 255) : null,
                ':url'    => (string)$d['file_url'],
                ':name'   => isset($d['file_name']) ? mb_substr((string)$d['file_name'], 0, 160) : null,
                ':size'   => isset($d['file_size']) ? (int)$d['file_size'] : null,
                ':mime'   => isset($d['mime_type']) ? mb_substr((string)$d['mime_type'], 0, 60)  : null,
                ':tat'    => $d['taken_at']  ?? null,
                ':tlat'   => isset($d['taken_lat']) ? (float)$d['taken_lat'] : null,
                ':tlng'   => isset($d['taken_lng']) ? (float)$d['taken_lng'] : null,
                ':src'    => in_array($d['source'] ?? '', ['web','mobile','import'], true) ? $d['source'] : 'web',
                ':uu'     => !empty($d['uploaded_by']) ? (int)$d['uploaded_by'] : null,
                ':du'     => !empty($d['driver_id'])   ? (int)$d['driver_id']   : null,
            ]
        );
        return (int)$r['last_id'];
    }

    public function softDelete(int $id, int $uid): void
    {
        (new DB())->insertUpdate(
            "UPDATE trip_attachments SET deleted = 1 WHERE c0d = :id",
            [':id' => $id]
        );
    }

    /** Category → human label. */
    public static function label(string $cat): string
    {
        return self::CATEGORIES[$cat] ?? ucwords(str_replace('_', ' ', $cat));
    }
}
