<?php
declare(strict_types=1);

require_once __DIR__ . '/media_assets.php';
require_once __DIR__ . '/revenda_schema.php';


/**
 * Normaliza a conexão usada pelo módulo de branding.
 *
 * O painel legado mistura PDO e SQLite3 em algumas telas (especialmente no
 * dashboard). As rotinas de branding trabalham internamente com PDO para
 * manter prepared statements, transações e tratamento de erros consistentes.
 */
function branding_pdo($db): PDO
{
    if ($db instanceof PDO) {
        return $db;
    }

    if (class_exists('SQLite3', false) && $db instanceof SQLite3) {
        $databaseInfo = @$db->querySingle('PRAGMA database_list', true);
        $databasePath = is_array($databaseInfo) ? trim((string)($databaseInfo['file'] ?? '')) : '';
        if ($databasePath === '') {
            throw new RuntimeException('Não foi possível identificar o banco SQLite usado pelo painel.');
        }

        $pdo = new PDO('sqlite:' . $databasePath, null, null, [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            PDO::ATTR_EMULATE_PREPARES => false,
        ]);
        $pdo->exec('PRAGMA busy_timeout = 30000');
        return $pdo;
    }

    throw new InvalidArgumentException('Conexão de banco inválida no módulo de branding. Use PDO ou SQLite3.');
}

function branding_ensure_schema($db): void
{
    $db = branding_pdo($db);
    revenda_ensure_schema($db);
    $db->exec('PRAGMA busy_timeout = 30000');
    $db->exec("CREATE TABLE IF NOT EXISTS branding_assets (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        owner_type TEXT NOT NULL DEFAULT 'admin',
        owner_id INTEGER NOT NULL DEFAULT 0,
        asset_key TEXT NOT NULL DEFAULT 'logo',
        path TEXT NOT NULL DEFAULT '',
        mime TEXT NOT NULL DEFAULT '',
        sha256 TEXT NOT NULL DEFAULT '',
        size_bytes INTEGER NOT NULL DEFAULT 0,
        width INTEGER NOT NULL DEFAULT 0,
        height INTEGER NOT NULL DEFAULT 0,
        updated_at INTEGER NOT NULL DEFAULT 0,
        UNIQUE(owner_type, owner_id, asset_key)
    )");
    $db->exec('CREATE UNIQUE INDEX IF NOT EXISTS idx_branding_owner_asset ON branding_assets(owner_type, owner_id, asset_key)');

    // Migração transparente da logo global legada.
    $st = $db->prepare("SELECT id FROM branding_assets WHERE owner_type='admin' AND owner_id=0 AND asset_key='logo' LIMIT 1");
    $st->execute();
    if (!$st->fetchColumn()) {
        $legacy = media_panel_root() . '/api/img/logo.png';
        if (is_file($legacy)) {
            try {
                $meta = media_detect_image($legacy, true);
                $ins = $db->prepare("INSERT OR IGNORE INTO branding_assets (owner_type,owner_id,asset_key,path,mime,sha256,size_bytes,width,height,updated_at) VALUES ('admin',0,'logo',?,?,?,?,?,?,?)");
                $ins->execute([
                    'api/img/logo.png',
                    (string)$meta['mime'],
                    (string)$meta['sha256'],
                    (int)$meta['size'],
                    (int)$meta['width'],
                    (int)$meta['height'],
                    (int)(@filemtime($legacy) ?: time()) * 1000,
                ]);
            } catch (Throwable $e) {}
        }
    }
}

function branding_normalize_owner(string $ownerType, int $ownerId): array
{
    $isReseller = strtolower(trim($ownerType)) === 'revendedor' || $ownerId > 0;
    return $isReseller ? ['revendedor', max(0, $ownerId)] : ['admin', 0];
}

function branding_direct_record($db, string $ownerType, int $ownerId, bool $ensureSchema = true): array
{
    $db = branding_pdo($db);
    [$ownerType, $ownerId] = branding_normalize_owner($ownerType, $ownerId);
    if ($ensureSchema) branding_ensure_schema($db);

    if ($ownerType === 'revendedor' && $ownerId > 0) {
        try {
            $st = $db->prepare('SELECT logo_path,logo_updated_at FROM revendedores WHERE id=? LIMIT 1');
            $st->execute([$ownerId]);
            $rev = $st->fetch(PDO::FETCH_ASSOC) ?: [];
            $path = media_clean_relative_path((string)($rev['logo_path'] ?? ''));
            $full = $path !== '' ? media_absolute_path($path) : '';
            if ($full !== '' && is_file($full)) {
                $row = [];
                try {
                    $asset = $db->prepare("SELECT * FROM branding_assets WHERE owner_type='revendedor' AND owner_id=? AND asset_key='logo' LIMIT 1");
                    $asset->execute([$ownerId]);
                    $row = $asset->fetch(PDO::FETCH_ASSOC) ?: [];
                } catch (Throwable $e) {}
                return [
                    'owner_type' => 'revendedor',
                    'owner_id' => $ownerId,
                    'path' => $path,
                    'mime' => (string)($row['mime'] ?? media_mime_for_path($full)),
                    'sha256' => (string)($row['sha256'] ?? ''),
                    'size_bytes' => (int)($row['size_bytes'] ?? (@filesize($full) ?: 0)),
                    'width' => (int)($row['width'] ?? 0),
                    'height' => (int)($row['height'] ?? 0),
                    'updated_at' => max((int)($rev['logo_updated_at'] ?? 0), (int)($row['updated_at'] ?? 0), (int)(@filemtime($full) ?: 0)),
                    'is_fallback' => false,
                ];
            }
        } catch (Throwable $e) {}
    }

    $row = [];
    try {
        $st = $db->prepare("SELECT * FROM branding_assets WHERE owner_type='admin' AND owner_id=0 AND asset_key='logo' LIMIT 1");
        $st->execute();
        $row = $st->fetch(PDO::FETCH_ASSOC) ?: [];
    } catch (Throwable $e) {}
    $path = media_clean_relative_path((string)($row['path'] ?? ''));
    $full = $path !== '' ? media_absolute_path($path) : '';
    if ($full === '' || !is_file($full)) {
        $legacy = media_panel_root() . '/api/img/logo.png';
        if (is_file($legacy)) {
            $path = 'api/img/logo.png';
            $full = $legacy;
        }
    }
    if ($full === '' || !is_file($full)) return [];
    return [
        'owner_type' => 'admin',
        'owner_id' => 0,
        'path' => $path,
        'mime' => (string)($row['mime'] ?? media_mime_for_path($full)),
        'sha256' => (string)($row['sha256'] ?? ''),
        'size_bytes' => (int)($row['size_bytes'] ?? (@filesize($full) ?: 0)),
        'width' => (int)($row['width'] ?? 0),
        'height' => (int)($row['height'] ?? 0),
        'updated_at' => max((int)($row['updated_at'] ?? 0), (int)(@filemtime($full) ?: 0)),
        'is_fallback' => $ownerType === 'revendedor',
    ];
}

function branding_logo_url($db, string $ownerType = 'admin', int $ownerId = 0): string
{
    $db = branding_pdo($db);
    [$ownerType, $ownerId] = branding_normalize_owner($ownerType, $ownerId);
    $record = branding_direct_record($db, $ownerType, $ownerId);
    if (!$record) return '';
    $base = rtrim(media_public_base_url(), '/');
    $query = 'app_image=1';
    if ($ownerType === 'revendedor' && $ownerId > 0) {
        $query .= '&owner_type=revendedor&owner_id=' . $ownerId;
    }
    $version = (int)($record['updated_at'] ?? 0);
    if ($version > 0) $query .= '&v=' . $version;
    return $base . '/controllers/logo.php?' . $query;
}

function branding_save_logo($db, string $ownerType, int $ownerId, array $stored): array
{
    $db = branding_pdo($db);
    [$ownerType, $ownerId] = branding_normalize_owner($ownerType, $ownerId);
    if ($ownerType === 'revendedor' && $ownerId <= 0) throw new RuntimeException('Revenda inválida.');
    branding_ensure_schema($db);

    $newPath = media_clean_relative_path((string)($stored['path'] ?? ''));
    if ($newPath === '' || !is_file(media_absolute_path($newPath))) throw new RuntimeException('A nova logo não foi gravada corretamente.');
    if ($ownerType === 'revendedor') {
        $checkRev = $db->prepare('SELECT id FROM revendedores WHERE id=? LIMIT 1');
        $checkRev->execute([$ownerId]);
        if (!$checkRev->fetchColumn()) throw new RuntimeException('Revenda não encontrada.');
    }
    $old = branding_direct_record($db, $ownerType, $ownerId);
    $updated = media_monotonic_version((int)($old['updated_at'] ?? 0));

    $db->beginTransaction();
    try {
        $up = $db->prepare("INSERT INTO branding_assets (owner_type,owner_id,asset_key,path,mime,sha256,size_bytes,width,height,updated_at)
            VALUES (?,?,'logo',?,?,?,?,?,?,?)
            ON CONFLICT(owner_type,owner_id,asset_key) DO UPDATE SET path=excluded.path,mime=excluded.mime,sha256=excluded.sha256,size_bytes=excluded.size_bytes,width=excluded.width,height=excluded.height,updated_at=excluded.updated_at");
        $up->execute([
            $ownerType, $ownerId, $newPath, (string)($stored['mime'] ?? ''), (string)($stored['sha256'] ?? ''),
            (int)($stored['size'] ?? 0), (int)($stored['width'] ?? 0), (int)($stored['height'] ?? 0), $updated,
        ]);
        if ($ownerType === 'revendedor') {
            $rev = $db->prepare("UPDATE revendedores SET logo_path=?,logo_updated_at=?,updated_at=strftime('%s','now') WHERE id=?");
            $rev->execute([$newPath, $updated, $ownerId]);
        }
        $db->commit();
    } catch (Throwable $e) {
        if ($db->inTransaction()) $db->rollBack();
        throw $e;
    }

    $oldPath = (string)($old['path'] ?? '');
    if ($oldPath !== '' && $oldPath !== $newPath && media_path_is_managed($oldPath)) media_delete_relative_file($oldPath);
    return branding_direct_record($db, $ownerType, $ownerId);
}

function branding_delete_logo($db, string $ownerType, int $ownerId): void
{
    $db = branding_pdo($db);
    [$ownerType, $ownerId] = branding_normalize_owner($ownerType, $ownerId);
    branding_ensure_schema($db);
    $old = branding_direct_record($db, $ownerType, $ownerId);
    // Para revenda, direct_record pode ser fallback global. Só apague se realmente pertence à revenda.
    $oldPath = (($old['owner_type'] ?? '') === $ownerType && (int)($old['owner_id'] ?? -1) === $ownerId)
        ? (string)($old['path'] ?? '') : '';

    $db->beginTransaction();
    try {
        $del = $db->prepare("DELETE FROM branding_assets WHERE owner_type=? AND owner_id=? AND asset_key='logo'");
        $del->execute([$ownerType, $ownerId]);
        if ($ownerType === 'revendedor') {
            $db->prepare("UPDATE revendedores SET logo_path='',logo_updated_at=?,updated_at=strftime('%s','now') WHERE id=?")
                ->execute([media_monotonic_version(), $ownerId]);
        }
        $db->commit();
    } catch (Throwable $e) {
        if ($db->inTransaction()) $db->rollBack();
        throw $e;
    }
    if ($oldPath !== '' && media_path_is_managed($oldPath)) media_delete_relative_file($oldPath);
}
