Moj Meni

Morate biti prijavljeni.

Prijava Registracija
Postavi oglas
Kategorije
Prodajem piliće
7 pregleda
1 prati oglas
Prijavite se za čuvanje

Prodajem piliće

500 RSD


Lokacija: Beograd
Prodavac: mašine alati
Telefon: +381604...
Kontaktiraj prodavca
Morate biti prijavljeni da pošaljete poruku.
PODELI OGLAS:
Opis oglasa
<?php
session_start();
require_once 'config.php';
require_once 'ai_filter.php';

// NAPOMENA: ai_dupli_tekst.php izbacujemo jer si rekao da ne želimo proveru 300 oglasa + opterećenje.
// require_once 'ai_dupli_tekst.php';

if (!isset($_SESSION['korisnik_id'])) {
header("Location: prijava.php");
exit;
}

$korisnik_id = (int)$_SESSION['korisnik_id'];

// Učitaj telefon i lokaciju korisnika (zaključano - ne sme da se menja)
try {
$stmt = $pdo->prepare("SELECT telefon, lokacija, ime FROM korisnici WHERE id = ?");
$stmt->execute([$korisnik_id]);
$korisnik = $stmt->fetch(PDO::FETCH_ASSOC);

if (!$korisnik) {
session_unset();
session_destroy();
header("Location: prijava.php");
exit;
}

// Hirurška provera: ako korisnik nema telefon ili lokaciju (Google registracija bez podataka),
// šaljemo ga da dovrši registraciju pre postavljanja oglasa
if (empty($korisnik['telefon']) || empty($korisnik['lokacija'])) {
header("Location: registracija.php?dovrsi=1");
exit;
}

} catch (Exception $e) {
error_log("DB error (korisnik fetch): " . $e->getMessage());
http_response_code(500);
echo "Došlo je do greške. Pokušajte kasnije.";
exit;
}

// ======================================================
// SERVER RESIZE SLIKA (OBAVEZNO RESAJZOVANJE)
// ======================================================

function mbz_get_image_info($path) {
if (!file_exists($path)) return false;
$info = @getimagesize($path);
if (!$info) return false;

return [
'width' => (int)$info[0],
'height' => (int)$info[1],
'mime' => $info['mime'] ?? ''
];
}

function mbz_create_image_from_file($path, $mime) {
switch ($mime) {
case 'image/jpeg':
return @imagecreatefromjpeg($path);
case 'image/png':
return @imagecreatefrompng($path);
case 'image/gif':
return @imagecreatefromgif($path);
case 'image/webp':
if (function_exists('imagecreatefromwebp')) {
return @imagecreatefromwebp($path);
}
return false;
default:
return false;
}
}

function mbz_save_image_to_file($img, $destPath, $mime, $qualityJpeg = 85) {
switch ($mime) {
case 'image/jpeg':
return @imagejpeg($img, $destPath, $qualityJpeg);
case 'image/png':
// PNG kvalitet: 0 (najbolje) - 9 (najviše kompresije)
return @imagepng($img, $destPath, 6);
case 'image/gif':
return @imagegif($img, $destPath);
case 'image/webp':
if (function_exists('imagewebp')) {
return @imagewebp($img, $destPath, 85);
}
return false;
default:
// fallback: snimi kao jpeg ako ništa drugo ne prolazi
return @imagejpeg($img, $destPath, $qualityJpeg);
}
}

function mbz_resize_image_in_place($path, $maxW = 1600, $maxH = 1600) {
$info = mbz_get_image_info($path);
if (!$info) return false;

$w = $info['width'];
$h = $info['height'];
$mime = $info['mime'];

// Ako je već manje - nema potrebe da radimo resize
if ($w <= $maxW && $h <= $maxH) {
return true;
}

$src = mbz_create_image_from_file($path, $mime);
if (!$src) return false;

// Izračunaj novi odnos
$ratioW = $maxW / $w;
$ratioH = $maxH / $h;
$ratio = min($ratioW, $ratioH);

$newW = (int)floor($w * $ratio);
$newH = (int)floor($h * $ratio);

if ($newW < 1) $newW = 1;
if ($newH < 1) $newH = 1;

$dst = imagecreatetruecolor($newW, $newH);

// Transparentnost za PNG/GIF
if ($mime === 'image/png' || $mime === 'image/gif') {
imagecolortransparent($dst, imagecolorallocatealpha($dst, 0, 0, 0, 127));
imagealphablending($dst, false);
imagesavealpha($dst, true);
}

imagecopyresampled($dst, $src, 0, 0, 0, 0, $newW, $newH, $w, $h);

// Snimanje preko istog fajla
$ok = mbz_save_image_to_file($dst, $path, $mime, 85);

imagedestroy($src);
imagedestroy($dst);

return $ok;
}

// ======================================================
// VARIJABLE
// ======================================================

$greske = [];
$naslov = $opis = '';
$kategorija = $podkategorija = $grupa = 0;
$cena = 0;
$cena_raw = '';
$valuta = 'RSD';
$slike = [];
$obnavlja_se = 0;

// Lokacija i telefon su ZAKLJUČANI iz baze (ne sme iz POST-a)
$lokacija = (string)$korisnik['lokacija'];
$telefon = (string)$korisnik['telefon'];

// ======================================================
// POST LOGIKA
// ======================================================

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

// Učitavanje polja iz forme
$naslov = trim($_POST['naslov'] ?? '');
$kategorija = (int)($_POST['kategorija'] ?? 0);
$podkategorija = (int)($_POST['podkategorija'] ?? 0);
$grupa = (int)($_POST['grupa'] ?? 0);

$cena_raw = trim($_POST['cena'] ?? '');
$tip_cene = $_POST['tip_cene'] ?? 'iznos';
$cena = ($tip_cene === 'iznos') ? (int)preg_replace('/\D/', '', $cena_raw ?: '0') : 0;

$opis = trim($_POST['opis'] ?? '');

// Valuta samo ako je iznos (RSD/EUR)
$valuta = ($tip_cene === 'iznos' && in_array($_POST['valuta'] ?? 'RSD', ['RSD','EUR'], true))
? $_POST['valuta']
: 'RSD';

$obnavlja_se = isset($_POST['obnavlja_se']) ? 1 : 0;

// Saglasnost
if (empty($_POST['saglasnost'])) {
$greske[] = "Morate prihvatiti uslove korišćenja.";
}

// Obavezna polja
if ($naslov === '') $greske[] = "Naslov je obavezan.";
if ($kategorija <= 0) $greske[] = "Morate izabrati kategoriju.";
if ($podkategorija <= 0) $greske[] = "Morate izabrati podkategoriju.";
if ($tip_cene === 'iznos' && $cena <= 0) $greske[] = "Unesite ispravnu cenu.";

// Zabranjene reči (lagano, ne opterećuje server)
$hits = proveriZabranjenSadrzaj($naslov . ' ' . $opis);
if (!empty($hits)) {
$greske[] = "Oglas sadrži zabranjene reči i ne može biti objavljen. (detektovano: " . implode(', ', $hits) . ")";
}

// Priprema uploads direktorijuma
$uploadDir = __DIR__ . '/uploads';
if (!is_dir($uploadDir)) {
if (!mkdir($uploadDir, 0755, true) && !is_dir($uploadDir)) {
$greske[] = "Ne mogu da napravim uploads direktorijum na serveru.";
}
}

// Upload slika (SLIKE NISU OBAVEZNE)
// Napomena: korisnik može da ubaci i velike slike, ali mi ih OBAVEZNO resajzujemo.
if (empty($greske) && !empty($_FILES['slike']['name'][0])) {

$maxFiles = 10;

// Dozvoljeni formati (galerija + kamera)
$allowedExt = ['jpg','jpeg','png','gif','webp'];

foreach ($_FILES['slike']['tmp_name'] as $key => $tmp) {

if (!isset($_FILES['slike']['name'][$key]) || $_FILES['slike']['name'][$key] === '') continue;
if (count($slike) >= $maxFiles) break;

if ($_FILES['slike']['error'][$key] !== UPLOAD_ERR_OK) continue;

$origName = $_FILES['slike']['name'][$key];
$size = (int)($_FILES['slike']['size'][$key] ?? 0);

// Ne ograničavamo "strogo" male veličine, ali moramo imati neku zaštitu da server ne padne.
// Ako želiš, možemo povećati, ali ovo je već dosta visoko.
if ($size > 25 * 1024 * 1024) {
continue;
}

$ext = strtolower(pathinfo($origName, PATHINFO_EXTENSION));
if (!in_array($ext, $allowedExt, true)) continue;

$newName = uniqid('img_', true) . '.' . $ext;
$dest = $uploadDir . '/' . $newName;

if (move_uploaded_file($tmp, $dest)) {

// OBAVEZAN server resize (ako GD postoji)
$resizedOk = mbz_resize_image_in_place($dest, 1600, 1600);
if (!$resizedOk) {
// ako resize padne, ne rušimo oglas, samo logujemo
error_log("Resize failed for: " . $dest);
}

$slike[] = 'uploads/' . $newName;
}
}
}

// Ako nema grešaka – upis u bazu
if (empty($greske)) {
try {

$slike_json = json_encode($slike, JSON_UNESCAPED_UNICODE);

// Odredi tip sajta prema kategoriji
$stmt = $pdo->prepare("SELECT site_type FROM kategorije WHERE id = ?");
$stmt->execute([$kategorija]);
$site_type = $stmt->fetchColumn();
if (!$site_type) $site_type = 'mojaberza';

$sql = "INSERT INTO oglasi
(korisnik_id, kategorija_id, podkategorija_id, grupa_id,
naslov, opis, cena, valuta, lokacija, slike, telefon,
site_type, datum, pregleda, istaknut, obnavlja_se, poslednje_obnavljanje)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), 0, 0, ?, NOW())";

$stmt = $pdo->prepare($sql);

$stmt->execute([
$korisnik_id,
$kategorija,
$podkategorija,
$grupa > 0 ? $grupa : null,
$naslov,
$opis,
$cena,
$valuta,
$lokacija, // ZAKLJUČANO iz baze
$slike_json,
$telefon, // ZAKLJUČANO iz baze
$site_type,
$obnavlja_se
]);

header("Location: moj-nalog.php?uspeh=1");
exit;

} catch (Exception $e) {
error_log("DB insert error (postavi-oglas): " . $e->getMessage());
$greske[] = "Došlo je do greške prilikom objave oglasa. Pokušajte kasnije.";
}
}
}

// Učitaj kategorije za select
try {
$kategorije = $pdo->query("SELECT id, naziv FROM kategorije ORDER BY naziv")->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $e) {
error_log("DB error (kategorije): " . $e->getMessage());
$kategorije = [];
}

include 'header.php';
?>
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"></script>

<style>
/* KONTEJNERI ZA MIKROFON */
.voice-input-wrapper {
position: relative;
display: flex;
align-items: center;
}

.field-mic-btn {
position: absolute;
right: 10px;
background: transparent;
border: none;
color: #0d6efd;
font-size: 1.4rem;
cursor: pointer;
z-index: 10;
padding: 5px;
display: none;
}

/* MIKROFON U VRHU PORED NASLOVA ZA MOBILNI */
.top-main-mic {
background: transparent;
border: none;
color: #0d6efd;
font-size: 1.8rem;
cursor: pointer;
vertical-align: middle;
margin-left: 10px;
display: none;
}

@media (max-width: 991.98px) {
.field-mic-btn, .top-main-mic {
display: inline-block;
}
}

.field-mic-btn.listening, .top-main-mic.listening {
color: #dc3545;
animation: pulse-mic 1.5s infinite;
}

@keyframes pulse-mic { 0% { opacity: 1; } 50% { opacity: 0.5; } 100% { opacity: 1; } }

#ai_container {
display: none;
}

/* Checkbox obnavljanja */
.auto-renew-label {
background: #e7f7ff;
border-left: 4px solid #0d6efd;
padding: 12px 15px;
border-radius: 6px;
margin: 15px 0;
display: flex;
align-items: center;
gap: 10px;
}
.auto-renew-label input[type="checkbox"] {
transform: scale(1.3);
}

/* Grid za slike */
.slike-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
}

.slika-slot {
width: 100%;
padding-top: 100%;
position: relative;
border: 2px dashed #bbb;
border-radius: 10px;
cursor: grab;
overflow: hidden;
background: #fafafa;
}
.slika-slot:active { cursor: grabbing; }

.slika-slot span.plus {
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
font-size: 36px;
color: #999;
z-index: 5;
}

.slika-slot .label {
position: absolute;
left: 0;
right: 0;
bottom: 8px;
text-align: center;
font-size: 12px;
color: #666;
z-index: 6;
pointer-events: none;
}

.slika-slot img.thumb {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 10px;
}

.slika-slot .remove {
position: absolute;
top: 3px; right: 3px;
background: rgba(0,0,0,0.6);
color: white;
font-size: 18px;
width: 24px;
height: 24px;
text-align: center;
line-height: 24px;
border-radius: 50%;
cursor: pointer;
z-index: 10;
}

.slika-slot.add-btn { cursor: pointer; border-style: dashed; }

/* Sortable stil */
.slika-slot.sortable-ghost {
opacity: 0.4;
border: 2px solid #0d6efd;
}

.slika-slot:first-child {
border-color: #28a745;
position: relative;
}
.slika-slot:first-child::after {
content: "Glavna";
position: absolute;
bottom: 5px;
left: 5px;
background: #28a745;
color: white;
font-size: 10px;
padding: 2px 5px;
border-radius: 3px;
z-index: 11;
}
</style>
<div class="container my-5">
<div class="d-flex align-items-center mb-4">
<h2 class="mb-0">Agent za automatsko postavljanje oglasa glasom <small style="font-size: 0.6em; color: #6c757d;">(u izradi)</small></h2>
<button type="button" class="top-main-mic" onclick="if(window.VoiceAgent && VoiceAgent.start){ VoiceAgent.start(); }">
<i class="bi bi-mic-fill"></i>
</button>
</div>

<?php if (!empty($greske)): ?>
<div class="alert alert-danger">
<?php foreach ($greske as $g): ?>
<div><?= htmlspecialchars($g) ?></div>
<?php endforeach; ?>
</div>
<?php endif; ?>

<form method="POST" enctype="multipart/form-data" class="bg-white p-4 rounded shadow" id="oglasForm">
<div class="row">
<div class="col-md-8">

<div class="mb-3" id="ai_container">
<label class="form-label text-primary fw-bold">Glasovno prepoznavanje kategorije (AI)</label>
<div class="voice-input-wrapper">
<input type="text" id="ai_input" class="form-control border-primary" placeholder="Izgovori kategoriju...">
<button type="button" class="field-mic-btn" onclick="startVoiceForFieldSimple('ai_input')">
<i class="bi bi-mic-fill"></i>
</button>
</div>
</div>

<div class="mb-3">
<label class="form-label">Naslov oglasa *</label>
<div class="voice-input-wrapper">
<input type="text" name="naslov" id="naslov_field" class="form-control"
required maxlength="100"
value="<?= htmlspecialchars($naslov) ?>">
<button type="button" class="field-mic-btn" onclick="startVoiceForFieldSimple('naslov_field')">
<i class="bi bi-mic-fill"></i>
</button>
</div>
</div>
<div class="row mb-3">
<div class="col-md-4">
<label class="form-label">Kategorija *</label>
<select name="kategorija" id="kategorija" class="form-select" required>
<option value="">Izaberi kategoriju</option>
<?php foreach($kategorije as $k): ?>
<option value="<?= $k['id'] ?>" <?= ($k['id'] == $kategorija) ? 'selected' : '' ?>>
<?= htmlspecialchars($k['naziv']) ?>
</option>
<?php endforeach; ?>
</select>
</div>

<div class="col-md-4">
<label class="form-label">Podkategorija *</label>
<select name="podkategorija" id="podkategorija" class="form-select" required>
<option value="">Prvo izaberi kategoriju</option>
</select>
</div>

<div class="col-md-4" id="grupa_container" style="display:none;">
<label class="form-label">Grupa (opciono)</label>
<select name="grupa" id="grupa" class="form-select">
<option value="">Izaberi grupu</option>
</select>
</div>
</div>

<div class="auto-renew-label">
<input type="checkbox" name="obnavlja_se" id="obnavlja_se" value="1" <?= $obnavlja_se ? 'checked' : '' ?>>
<label for="obnavlja_se" class="mb-0">
<strong>🔁 Automatski obnavljaj oglas svakih 30 dana</strong><br>
<small class="text-muted">Oglas će se sam obnavljati i ostati na vrhu liste. Možete isključiti ovo kasnije u postavkama oglasa.</small>
</label>
</div>

<div class="mb-3">
<label class="form-label d-block">Stanje *</label>
<label class="me-3">
<input type="radio" name="stanje" value="Novo" required> Novo (samo za firme)
</label>
<label class="me-3">
<input type="radio" name="stanje" value="Polovno nekorišteno"> Polovno nekorišteno
</label>
<label>
<input type="radio" name="stanje" value="Polovno korišteno"> Polovno korišteno
</label>
</div>

<div class="mb-3">
<label class="form-label d-block">Ispravnost *</label>
<label class="me-3">
<input type="radio" name="ispravnost" value="Potpuno ispravno" required> Potpuno ispravno
</label>
<label class="me-3">
<input type="radio" name="ispravnost" value="Neispravno ali kompletno"> Neispravno ali kompletno
</label>
<label>
<input type="radio" name="ispravnost" value="Neispravno i nekompletno"> Neispravno i nekompletno
</label>
</div>

<div class="mb-3">
<label class="form-label">Opis oglasa</label>
<div class="voice-input-wrapper">
<textarea name="opis" id="opis_field" class="form-control" rows="6"><?= htmlspecialchars($opis) ?></textarea>
<button type="button" class="field-mic-btn" style="top:10px;" onclick="startVoiceForFieldSimple('opis_field')">
<i class="bi bi-mic-fill"></i>
</button>
</div>
</div>

<div class="mb-3">
<label class="form-label d-block">Cena *</label>

<label class="d-block">
<input type="radio" name="tip_cene" value="iznos" checked>
Cena (unesi iznos ispod)
</label>

<div class="input-group mt-2 mb-3">
<input type="text" name="cena" id="cena_field" class="form-control" placeholder="25000" value="<?= htmlspecialchars($cena_raw) ?>">
<span class="input-group-text">
<input type="radio" name="valuta" value="RSD" checked> RSD
</span>
<span class="input-group-text">
<input type="radio" name="valuta" value="EUR"> EUR
</span>
</div>

<label class="d-block mt-2">
<input type="radio" name="tip_cene" value="dogovor">
Po dogovoru
</label>

<label class="d-block">
<input type="radio" name="tip_cene" value="poziv">
Na poziv
</label>
</div>

<div class="mb-3">
<label class="form-label">
Slike (max 10) <small>(Prva slika je naslovna, prevuci za promenu reda)</small><br>
<small class="text-muted">Slike nisu obavezne. Na mobilnom ima posebno: Kamera (ubacuješ jednu po jednu) i Galerija (više odjednom). Sve slike se resajzuju.</small>
</label>

<div id="slikeGrid" class="slike-grid"></div>
</div>

<div class="form-check mb-4">
<input type="checkbox" name="saglasnost" class="form-check-input" id="saglasnost"
<?= isset($_POST['saglasnost']) ? 'checked' : '' ?> required>
<label class="form-check-label" for="saglasnost">
Saglasan sam sa <a href="pravilnik.php" target="_blank">pravilima sajta</a>.
</label>
</div>

</div>

<div class="col-md-4">
<div class="bg-light p-3 rounded border sticky-top" style="top:15px;">

<small class="text-muted d-block mb-2">
Lokacija (zaključana): <strong><?= htmlspecialchars($korisnik['lokacija']) ?></strong>
</small>

<small class="text-muted d-block mb-3">
Telefon (zaključan): <strong><?= htmlspecialchars($korisnik['telefon']) ?></strong>
</small>

<button type="submit" id="submitBtn" class="btn btn-lg w-100">
Objavi oglas
</button>

</div>
</div>

</div>
</form>
</div>

<style>
#submitBtn {
background-color: #dc3545 !important;
border-color: #dc3545 !important;
transition: all 0.3s;
color: white;
}
#submitBtn.valid {
background-color: #28a745 !important;
border-color: #28a745 !important;
}
</style>
<script>
// =====================================================
// 1) GLASOVNI UNOS (real-time ispis + tačka na kraju opisa)
// =====================================================
async function startVoiceForFieldSimple(fieldId) {
const field = document.getElementById(fieldId);
if (!field) return;

const btn = field.parentElement.querySelector('.field-mic-btn') || field.parentElement.querySelector('.btn-outline-secondary');

if (!('webkitSpeechRecognition' in window || 'SpeechRecognition' in window)) {
alert("Glasovni unos nije podržan u vašem pretraživaču.");
return;
}

if (btn) {
btn.classList.add('listening');
btn.disabled = true;
}

const originalValue = (fieldId === 'opis_field') ? field.value.trim() : "";

try {
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
const recognition = new SpeechRecognition();

recognition.lang = 'sr-RS';
recognition.interimResults = true;
recognition.maxAlternatives = 1;
recognition.continuous = true;

recognition.onresult = (event) => {
let interimTranscript = '';
let finalTranscript = '';

for (let i = event.resultIndex; i < event.results.length; ++i) {
if (event.results[i].isFinal) {
finalTranscript += event.results[i][0].transcript;
} else {
interimTranscript += event.results[i][0].transcript;
}
}

const currentText = finalTranscript || interimTranscript;

if (currentText.trim()) {
let processedText = currentText.trim();

if (fieldId === 'naslov_field') {
field.value = processedText.charAt(0).toUpperCase() + processedText.slice(1);
}
else if (fieldId === 'opis_field') {
let newVal = processedText.charAt(0).toUpperCase() + processedText.slice(1);
field.value = originalValue !== "" ? (originalValue + " " + newVal) : newVal;
}
else if (fieldId === 'ai_input') {
field.value = processedText;
}

field.dispatchEvent(new Event('input', { bubbles: true }));
field.dispatchEvent(new Event('change', { bubbles: true }));
}
};

recognition.onerror = (event) => {
console.error("Greška:", event.error);
stopRecognition();
};

recognition.onend = () => {
stopRecognition();
};

function stopRecognition() {
try { recognition.stop(); } catch(e) {}

if (btn) {
btn.classList.remove('listening');
btn.disabled = false;
}

if (fieldId === 'opis_field' && field.value.trim() !== "" && !field.value.trim().endsWith('.')) {
field.value = field.value.trim() + ".";
field.dispatchEvent(new Event('input', { bubbles: true }));
field.dispatchEvent(new Event('change', { bubbles: true }));
}

if (fieldId === 'ai_input') {
// kad završi dikcija za kategoriju, pokušaj autofill
const q = field.value.trim();
if (q.length >= 3) {
aiAutoFill(q);
}
}
}

recognition.start();

// auto stop posle kratke tišine (da se brzo završi)
let silenceTimer;
recognition.onsoundstart = () => clearTimeout(silenceTimer);
recognition.onsoundend = () => {
silenceTimer = setTimeout(() => {
stopRecognition();
}, 2000);
};

} catch (error) {
console.error("Greška pri glasovnom unosu:", error);
if (btn) {
btn.classList.remove('listening');
btn.disabled = false;
}
}
}

// =====================================================
// 2) AI AUTO FILL kategorije (samo pomaže odabir - ostalo na klik)
// =====================================================
function aiAutoFill(q){
fetch("ai_kategorija_resolver.php?q=" + encodeURIComponent(q))
.then(r => r.json())
.then(data => {
if (data.need_choice) {
let txt = "Nađeno je više mogućih kategorija:\n\n";
data.options.forEach((o, i) => { txt += (i+1) + ") " + o.naziv + "\n"; });
let izbor = prompt(txt);
if (!izbor) return;
izbor = parseInt(izbor);
if (!data.options[izbor-1]) return;

let odabran = data.options[izbor-1];
document.getElementById("kategorija").value = odabran.kategorija_id;

fetch('ajax-podkategorije.php?id=' + odabran.kategorija_id)
.then(r => r.json())
.then(pod => {
const podSelect = document.getElementById("podkategorija");
podSelect.innerHTML = "";
pod.forEach(function(p){
let opt = document.createElement("option");
opt.value = p.id;
opt.textContent = p.naziv;
podSelect.appendChild(opt);
});
if (pod.length > 0) {
podSelect.value = pod[0].id;
ucitajGrupe(podSelect.value);
}
updateButton();
});
return;
}

if (data.success) {
document.getElementById("kategorija").value = data.kategorija_id;

fetch('ajax-podkategorije.php?id=' + data.kategorija_id)
.then(r => r.json())
.then(pod => {
const podSelect = document.getElementById("podkategorija");
podSelect.innerHTML = "";
pod.forEach(function(p){
let opt = document.createElement("option");
opt.value = p.id;
opt.textContent = p.naziv;
podSelect.appendChild(opt);
});

if (data.podkategorija_id) {
podSelect.value = data.podkategorija_id;
ucitajGrupe(data.podkategorija_id);
}
updateButton();
});
return;
}
})
.catch(err => {
console.error("AI autofill error:", err);
});
}

document.addEventListener("DOMContentLoaded", function(){
const aiInput = document.getElementById("ai_input");
if (!aiInput) return;

aiInput.addEventListener("input", function(){
const q = this.value.trim();
if (q.length >= 3) {
aiAutoFill(q);
}
});
});

// =====================================================
// 3) AJAX logika - podkategorije i grupe
// =====================================================
(function(){
const katSelect = document.getElementById('kategorija');
const podSelect = document.getElementById('podkategorija');
const grupaSelect = document.getElementById('grupa');
const grupaContainer = document.getElementById('grupa_container');

function ucitajPodkategorije(katId, selectedId = 0) {
if (!katId) {
podSelect.innerHTML = '<option value="">Prvo izaberi kategoriju</option>';
grupaContainer.style.display = 'none';
return;
}

podSelect.innerHTML = '<option>Učitavanje...</option>';

fetch('ajax-podkategorije.php?id=' + encodeURIComponent(katId))
.then(r => r.json())
.then(data => {
podSelect.innerHTML = '<option value="">Izaberi podkategoriju</option>';
if (!Array.isArray(data)) return;

data.forEach(p => {
const opt = document.createElement('option');
opt.value = p.id;
opt.textContent = p.naziv;
podSelect.appendChild(opt);
});

if (selectedId) {
podSelect.value = String(selectedId);
ucitajGrupe(selectedId);
}

updateButton();
})
.catch(() => {
podSelect.innerHTML = '<option value="">Greška pri učitavanju</option>';
updateButton();
});
}

window.ucitajGrupe = function(podkatId) {
if (!podkatId) {
grupaContainer.style.display = 'none';
return;
}

fetch('ajax-grupe.php?id=' + encodeURIComponent(podkatId))
.then(r => r.json())
.then(data => {
if (Array.isArray(data) && data.length > 0) {
grupaSelect.innerHTML = '<option value="">Izaberi grupu</option>';

data.forEach(g => {
const opt = document.createElement('option');
opt.value = g.id;
opt.textContent = g.naziv;
grupaSelect.appendChild(opt);
});

grupaContainer.style.display = 'block';
} else {
grupaContainer.style.display = 'none';
}

updateButton();
})
.catch(() => {
grupaContainer.style.display = 'none';
updateButton();
});
}

if (katSelect) {
katSelect.addEventListener('change', function () {
ucitajPodkategorije(this.value, 0);
});
}

if (podSelect) {
podSelect.addEventListener('change', function() {
ucitajGrupe(this.value);
});
}
})();

// =====================================================
// 4) TIP CENE - disable inputa kad nije "iznos"
// =====================================================
document.querySelectorAll("input[name='tip_cene']").forEach(r => {
r.addEventListener("change", function() {
const disabled = this.value !== "iznos";
const cenaInput = document.querySelector("[name='cena']");
if (cenaInput) cenaInput.disabled = disabled;

document.querySelectorAll("input[name='valuta']").forEach(v => v.disabled = disabled);

updateButton();
});
});

// =====================================================
// 5) SLIKE: mobilni (KAMERA prva + GALERIJA), desktop (GALERIJA)
// =====================================================
const grid = document.getElementById("slikeGrid");
let filesArray = [];

// Sortable - pomeranje redosleda (prva slika = glavna)
if (grid) {
new Sortable(grid, {
animation: 150,
filter: '.add-btn',
onEnd: function (evt) {
// Rekonstruiši niz po DOM redosledu
const newFilesArray = [];
grid.querySelectorAll('.slika-slot[data-id]').forEach(slot => {
const id = slot.getAttribute('data-id');
if (filesArray[id]) newFilesArray.push(filesArray[id]);
});
filesArray = newFilesArray;
renderGrid();
}
});
}

// Client-side resize (obavezno resajzovanje pre slanja, da upload bude lakši)
function resizeImageClient(file, maxW, maxH, quality) {
return new Promise((resolve, reject) => {
try {
const img = new Image();
const url = URL.createObjectURL(file);

img.onload = () => {
let w = img.width;
let h = img.height;

// Ako je već manje - samo vrati original (ali i dalje možeš da forsiraš konverziju ako želiš)
if (w <= maxW && h <= maxH) {
URL.revokeObjectURL(url);
resolve(file);
return;
}

const ratio = Math.min(maxW / w, maxH / h);
const newW = Math.max(1, Math.floor(w * ratio));
const newH = Math.max(1, Math.floor(h * ratio));

const canvas = document.createElement('canvas');
canvas.width = newW;
canvas.height = newH;

const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, newW, newH);

// Snimi kao JPEG radi veličine (najstabilnije za upload)
canvas.toBlob((blob) => {
URL.revokeObjectURL(url);
if (!blob) {
resolve(file);
return;
}
const resizedFile = new File([blob], file.name.replace(/\.(png|gif|webp)$/i, '.jpg'), { type: 'image/jpeg' });
resolve(resizedFile);
}, 'image/jpeg', quality);

};

img.onerror = () => {
URL.revokeObjectURL(url);
resolve(file);
};

img.src = url;

} catch (e) {
resolve(file);
}
});
}

function renderGrid() {
if (!grid) return;

grid.innerHTML = "";

filesArray.forEach((f, index) => {
const slot = document.createElement("div");
slot.className = "slika-slot";
slot.setAttribute('data-id', index);

const img = document.createElement("img");
img.className = "thumb";
img.src = URL.createObjectURL(f);
slot.appendChild(img);

const x = document.createElement("div");
x.className = "remove";
x.textContent = "×";
x.onclick = (e) => {
e.stopPropagation();
filesArray.splice(index, 1);
renderGrid();
updateButton();
};
slot.appendChild(x);

grid.appendChild(slot);
});

// Add slotovi
if (filesArray.length < 10) {

const isMobile = window.matchMedia && window.matchMedia("(max-width: 991.98px)").matches;

// MOBILNI: prvo KAMERA (jedna po jedna), pa GALERIJA (više)
if (isMobile) {

// KAMERA (po jedna slika)
const addCamera = document.createElement("div");
addCamera.className = "slika-slot add-btn";
addCamera.innerHTML = `
<span class="plus"><i class="bi bi-camera-fill"></i></span>
<div class="label">Kamera</div>
<input class="pick-camera" type="file" accept="image/*" capture="environment" style="display:none">
`;

const inCam = addCamera.querySelector(".pick-camera");

addCamera.onclick = (e) => {
inCam.click();
};

inCam.onchange = async (e) => {
const f = e.target.files && e.target.files[0] ? e.target.files[0] : null;
if (f && f.type && f.type.match('image.*')) {
if (filesArray.length < 10) {
const resized = await resizeImageClient(f, 1600, 1600, 0.85);
filesArray.push(resized);
}
renderGrid();
updateButton();
}
inCam.value = "";
};

grid.appendChild(addCamera);

// GALERIJA (više slika)
const addGallery = document.createElement("div");
addGallery.className = "slika-slot add-btn";
addGallery.innerHTML = `
<span class="plus"><i class="bi bi-images"></i></span>
<div class="label">Galerija</div>
<input class="pick-gallery" type="file" accept="image/*" multiple style="display:none">
`;

const inGal = addGallery.querySelector(".pick-gallery");

addGallery.onclick = (e) => {
inGal.click();
};

inGal.onchange = async (e) => {
const list = e.target.files;
if (list && list.length) {
for (let f of list) {
if (filesArray.length >= 10) break;
if (f && f.type && f.type.match('image.*')) {
const resized = await resizeImageClient(f, 1600, 1600, 0.85);
filesArray.push(resized);
}
}
renderGrid();
updateButton();
}
inGal.value = "";
};

grid.appendChild(addGallery);

} else {
// DESKTOP: samo GALERIJA
const addSlot = document.createElement("div");
addSlot.className = "slika-slot add-btn";
addSlot.innerHTML = `
<span class="plus">+</span>
<input class="pick-images" type="file" accept="image/*" multiple style="display:none">
`;

const inPick = addSlot.querySelector(".pick-images");

addSlot.onclick = (e) => {
inPick.click();
};

inPick.onchange = async (e) => {
const list = e.target.files;
if (list && list.length) {
for (let f of list) {
if (filesArray.length >= 10) break;
if (f && f.type && f.type.match('image.*')) {
const resized = await resizeImageClient(f, 1600, 1600, 0.85);
filesArray.push(resized);
}
}
renderGrid();
updateButton();
}
inPick.value = "";
};

grid.appendChild(addSlot);
}
}
}

renderGrid();

// =====================================================
// 6) Dugme boja: SLIKE NISU OBAVEZNE
// =====================================================
function updateButton() {
const naslov = document.querySelector("[name='naslov']") ? document.querySelector("[name='naslov']").value.trim() : "";
const kategorija = document.getElementById("kategorija") ? document.getElementById("kategorija").value : "";
const podkategorija = document.getElementById("podkategorija") ? document.getElementById("podkategorija").value : "";

const stanje = document.querySelector("input[name='stanje']:checked");
const ispravnost = document.querySelector("input[name='ispravnost']:checked");
const saglasnost = document.getElementById("saglasnost") ? document.getElementById("saglasnost").checked : false;

const tipCene = document.querySelector("input[name='tip_cene']:checked") ? document.querySelector("input[name='tip_cene']:checked").value : "iznos";
const cenaInput = document.querySelector("[name='cena']");
const cenaOk = (tipCene === "iznos" && cenaInput && cenaInput.value.trim() !== "") || tipCene !== "iznos";

const sveOk = naslov && kategorija && podkategorija && stanje && ispravnost && saglasnost && cenaOk;

const btn = document.getElementById("submitBtn");
if (btn) btn.classList.toggle("valid", !!sveOk);
}

document.querySelectorAll("input, select, textarea").forEach(el => {
el.addEventListener("input", updateButton);
el.addEventListener("change", updateButton);
});

updateButton();

// =====================================================
// 7) Submit - upiši slike u pravi input (ako ih ima)
// =====================================================
document.getElementById("oglasForm").addEventListener("submit", function(e) {

// očisti stare
const stari = this.querySelectorAll(".dynamic-img-input");
stari.forEach(s => s.remove());

// ako nema slika - ništa, jer slike nisu obavezne
if (!filesArray || filesArray.length === 0) {
return;
}

const dt = new DataTransfer();
filesArray.forEach(f => dt.items.add(f));

const input = document.createElement("input");
input.type = "file";
input.name = "slike[]";
input.multiple = true;
input.files = dt.files;
input.style.display = "none";
input.className = "dynamic-img-input";
this.appendChild(input);
});

// =====================================================
// 8) VoiceAgent override (da ne puca ako ne postoji VoiceAgent)
// =====================================================
(function(){
if (!window.VoiceAgent || !VoiceAgent.start) return;

const originalVoiceStart = VoiceAgent.start;

VoiceAgent.start = async function() {
const mainMic = document.querySelector('.top-main-mic');
if (mainMic) mainMic.classList.add('listening');

const c = document.getElementById('ai_container');
if (c) c.style.display = 'block';

await originalVoiceStart.call(this);

if (mainMic) mainMic.classList.remove('listening');
};
})();
</script>

<?php include 'footer.php'; ?>