<?php
declare(strict_types=1);

/** Phase 1 device registry — auto-register on crash upload. */
final class DeviceRepository {
    public static function externalKey(array $device): string {
        $parts = array_filter([
            (string) ($device['manufacturer'] ?? ''),
            (string) ($device['brand'] ?? ''),
            (string) ($device['model'] ?? ''),
            (string) ($device['product'] ?? ''),
            (string) ($device['device'] ?? ''),
            (string) ($device['serial'] ?? ''),
            (string) ($device['android_id'] ?? ''),
        ], static fn ($v) => $v !== '');
        if ($parts === []) {
            return 'unknown';
        }
        return substr(hash('sha256', implode('|', $parts)), 0, 32);
    }

    public static function upsertFromPayload(int $companyId, array $device, string $source = 'auto'): int {
        $companyId = max(1, $companyId);
        $externalId = self::externalKey($device);
        $now = (int) round(microtime(true) * 1000);
        $manufacturer = trim((string) ($device['manufacturer'] ?? ''));
        $model = trim((string) ($device['model'] ?? ''));
        $display = trim($manufacturer . ' ' . $model);
        $meta = json_encode($device, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        if ($meta === false) {
            $meta = '{}';
        }

        $pdo = Database::pdo();
        if (Database::isMysql()) {
            $stmt = $pdo->prepare(
                'INSERT INTO devices (company_id, external_id, display_name, manufacturer, model, source,
                    registered_at_ms, last_seen_at_ms, meta_json)
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
                 ON DUPLICATE KEY UPDATE
                    display_name = VALUES(display_name),
                    manufacturer = VALUES(manufacturer),
                    model = VALUES(model),
                    last_seen_at_ms = VALUES(last_seen_at_ms),
                    meta_json = VALUES(meta_json)'
            );
            $stmt->execute([
                $companyId,
                $externalId,
                $display !== '' ? $display : null,
                $manufacturer !== '' ? $manufacturer : null,
                $model !== '' ? $model : null,
                $source,
                $now,
                $now,
                $meta,
            ]);
            $sel = $pdo->prepare(
                'SELECT id FROM devices WHERE company_id = ? AND external_id = ? LIMIT 1'
            );
            $sel->execute([$companyId, $externalId]);
            return (int) $sel->fetchColumn();
        }

        $stmt = $pdo->prepare(
            'SELECT id FROM devices WHERE company_id = ? AND external_id = ? LIMIT 1'
        );
        $stmt->execute([$companyId, $externalId]);
        $existing = $stmt->fetchColumn();
        if ($existing !== false) {
            $upd = $pdo->prepare(
                'UPDATE devices SET display_name = ?, manufacturer = ?, model = ?,
                    last_seen_at_ms = ?, meta_json = ? WHERE id = ?'
            );
            $upd->execute([
                $display !== '' ? $display : null,
                $manufacturer !== '' ? $manufacturer : null,
                $model !== '' ? $model : null,
                $now,
                $meta,
                (int) $existing,
            ]);
            return (int) $existing;
        }
        $ins = $pdo->prepare(
            'INSERT INTO devices (company_id, external_id, display_name, manufacturer, model, source,
                registered_at_ms, last_seen_at_ms, meta_json)
             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)'
        );
        $ins->execute([
            $companyId,
            $externalId,
            $display !== '' ? $display : null,
            $manufacturer !== '' ? $manufacturer : null,
            $model !== '' ? $model : null,
            $source,
            $now,
            $now,
            $meta,
        ]);
        return (int) $pdo->lastInsertId();
    }
}
