'use client';
import Link from 'next/link';
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { DeskFocus, DeskPick } from './desk/Desk';
import type { Building } from './DeskMap';
import { SALE_TYPES, UNIT_TYPES, needsUnit, type SaleType, ringArea } from '@/lib/sale';
import { TEMPLATES } from '@/lib/templates';
import { LANGS, voicesFor, defaultVoiceFor, DEFAULT_VOICE, type Lang } from '@/lib/voices';
import { PLANS, tl } from '@/lib/plans';
import { PlanPrice } from './PlanPrice';
import { idariList, parcelLookup, type ParcelResult } from '@/lib/tkgmClient';
import { apLong, apShort } from '@/lib/ap';
import { PhotoUpload, type Photo } from './PhotoUpload';
import { TourUpload } from './TourUpload';

type Opt = { id: number; text: string };
type Parcel = ParcelResult;
const centroidOf = (p: Parcel) => { const r = p.geometry.coordinates[0]; const n = r.length - 1 || 1; return [r.slice(0, n).reduce((a, c) => a + c[0], 0) / n, r.slice(0, n).reduce((a, c) => a + c[1], 0) / n]; };

function Sel({ label, opts, value, onChange, disabled }: { label: string; opts: Opt[]; value: string; onChange: (v: string) => void; disabled?: boolean }) {
  return (<label className="cell border-b border-r border-ink/15"><span className="tag">{label}</span><select aria-label={label} value={value} disabled={disabled || !opts.length} onChange={(e) => onChange(e.target.value)}><option value="">Seçin</option>{opts.map((o) => <option key={o.id} value={o.id}>{o.text}</option>)}</select></label>);
}
function Step({ n, title, hint, children }: { n: number; title: string; hint?: string; children: React.ReactNode }) {
  return (
    <section className="border-t border-ink/15 px-4 pb-5 pt-3">
      <div className="mb-3 flex items-baseline gap-2.5"><span className="num bg-ink px-1.5 text-[12px] font-bold text-white">{n}</span><div><h2 className="text-[16px] font-bold">{title}</h2>{hint && <p className="text-[12.5px] text-ink-soft">{hint}</p>}</div></div>
      {children}
    </section>
  );
}
/** "101/5, 101/7 102/1" → [[101,5],[101,7],[102,1]] */
function parseList(s: string) { return [...s.matchAll(/(\d+)\s*\/\s*(\d+)/g)].map((m) => [m[1], m[2]] as [string, string]).slice(0, 20); }

export function NewOrder({ credits, defaultPlan, defaults, prefill }: { credits: number; defaultPlan?: string; defaults: { name: string; phone: string; logo?: boolean }; prefill?: { il?: string; ilce?: string; mahalle?: string; ada?: string; parsel?: string } }) {
  const [il, setIl] = useState<Opt[]>([]); const [ilce, setIlce] = useState<Opt[]>([]); const [mah, setMah] = useState<Opt[]>([]);
  const [f, setF] = useState({ il: prefill?.il || '', ilce: prefill?.ilce || '', mahalle: prefill?.mahalle || '', ada: prefill?.ada || '', parsel: prefill?.parsel || '' });
  const [batch, setBatch] = useState(false); const [list, setList] = useState('');
  const [parcels, setParcels] = useState<Parcel[]>([]); const [lookErr, setLookErr] = useState(''); const [looking, setLooking] = useState(false);
  const [tpl, setTpl] = useState('prestij'); const [plan, setPlan] = useState(defaultPlan && PLANS.some((p) => p.id === defaultPlan) ? defaultPlan : 'tek');
  const [imar, setImar] = useState({ imarDurum: '', emsal: '', taks: '', gabari: '' });
  const [hl, setHl] = useState(['', '', '']); const [headline, setHeadline] = useState('');
  const [contact, setContact] = useState({ contactName: defaults.name, contactPhone: defaults.phone });
  const [voice, setVoice] = useState(DEFAULT_VOICE); const [playing, setPlaying] = useState('');
  // v2: video dili, isteğe bağlı fiyat ve karekod linki
  const [lang, setLang] = useState<Lang>('tr'); const [price, setPrice] = useState(''); const [qrUrl, setQrUrl] = useState('');
  const VOICES = voicesFor(lang);
  const audio = useRef<HTMLAudioElement | null>(null);
  const [busy, setBusy] = useState(''); const [err, setErr] = useState('');
  // ne satılıyor
  const [sale, setSale] = useState({ type: 'arsa' as SaleType, unitType: '', unitArea: '', rooms: '', floorNo: '', buildYear: '', share: '' });
  const [target, setTarget] = useState<[number, number] | null>(null); const [picking, setPicking] = useState(false);
  const [buildings, setBuildings] = useState<Building[] | null>(null);
  // satılan bölüm (hisse ya da yapı): parselin tamamı satılmıyorsa haritada çizilir
  const [ring, setRing] = useState<[number, number][]>([]); const [drawing, setDrawing] = useState(false);
  const canDraw = sale.type === 'hisse' || sale.type === 'yapi';
  const [photos, setPhotos] = useState<Photo[]>([]);
  const photosBusy = photos.some((p) => !p.key && !p.err);
  const [tourKey, setTourKey] = useState<string | null>(null); const [tourBusy, setTourBusy] = useState(false);
  // art arda dokunuşlar kaybolmasın: köşe her zaman güncel listeye eklenir
  const addVertex = useCallback((ll: [number, number]) => setRing((r) => (r.length < 60 ? [...r, ll] : r)), []);
  function preview(id: string) {
    if (!audio.current) { audio.current = new Audio(); audio.current.onended = () => setPlaying(''); }
    const a = audio.current;
    if (playing === id) { a.pause(); setPlaying(''); return; }
    a.src = `/sesler/${id}.mp3?v=3`; a.currentTime = 0; a.play().then(() => setPlaying(id)).catch(() => setPlaying(''));
  }

  useEffect(() => { idariList('il').then(setIl).catch(() => setLookErr('İl listesi yüklenemedi, sayfayı yenileyin.')); }, []);
  useEffect(() => { setIlce([]); if (f.il) idariList('ilce', f.il).then(setIlce).catch(() => setLookErr('İlçe listesi yüklenemedi.')); }, [f.il]);
  useEffect(() => { setMah([]); if (f.ilce) idariList('mahalle', f.ilce).then(setMah).catch(() => setLookErr('Mahalle listesi yüklenemedi.')); }, [f.ilce]);

  const targets = batch ? parseList(list) : f.ada && f.parsel ? [[f.ada, f.parsel] as [string, string]] : [];
  async function lookOne(ada: string, parsel: string) {
    const waits = [4, 10, 20, 40];
    for (let i = 0; ; i++) {
      try { return await parcelLookup(f.mahalle, ada, parsel); }
      catch (e) {
        if ((e as { notFound?: boolean }).notFound) throw Object.assign(new Error(`${ada}/${parsel} Tapu Kadastro kayıtlarında bulunamadı.`), { final: true });
        if (i >= waits.length) throw Object.assign(new Error('Tapu Kadastro servisi şu anda yoğun. Bilgileriniz duruyor; birkaç dakika sonra yeniden deneyebilirsiniz.'), { final: true });
        for (let s = waits[i]; s > 0; s--) { setLookErr(`Tapu Kadastro servisi yoğun, ${s} sn içinde otomatik olarak yeniden deneniyor…`); await new Promise((r) => setTimeout(r, 1000)); }
        setLookErr('');
      }
    }
  }
  async function lookup() {
    setLooking(true); setLookErr(''); setParcels([]);
    const found: Parcel[] = []; const miss: string[] = [];
    for (const [a, p] of targets) {
      try { found.push(await lookOne(a, p)); setParcels([...found]); }
      catch (e) { if (/yoğun/.test((e as Error).message)) { setLookErr((e as Error).message); break; } miss.push(`${a}/${p}`); }
    }
    if (miss.length) setLookErr(miss.length === 1 && !batch ? 'Bu ada/parsel numarası Tapu Kadastro kayıtlarında bulunamadı. Numaraları kontrol edin.' : `Bulunamayanlar: ${miss.join(', ')}`);
    setLooking(false);
  }
  // Bağlantıyla (ana sayfadaki sorgu) gelindiyse parsel kendiliğinden bulunur
  const auto = useRef(!!(prefill?.mahalle && prefill?.ada && prefill?.parsel));
  useEffect(() => { if (auto.current && mah.length) { auto.current = false; lookup(); } });
  const focus = useMemo(() => parcels.map((p, i) => ({ key: `${apShort(p.ada, p.parsel)}`, geometry: p.geometry, tone: (i === 0 ? 'main' : 'other') as 'main' | 'other', label: parcels.length > 1 ? `${apShort(p.ada, p.parsel)}` : `${Math.round(p.alan).toLocaleString('tr-TR')} m²` })), [parcels]);
  const main = parcels[0] ?? null;
  const N = parcels.length;
  // yeni parsel: satış bilgisi sıfırlanır; kat mülkiyeti/irtifakı varsa varsayılan "daire"
  useEffect(() => {
    setTarget(null); setPicking(false); setBuildings(null); setRing([]); setDrawing(false);
    const kat = /kat\s*(mülk|irtif)/i.test(main?.zemin || '');
    setSale((x) => ({ ...x, type: kat ? 'bagimsiz' : 'arsa', unitType: kat ? 'Daire' : x.unitType }));
  }, [main]);
  const onPick = useCallback((ll: [number, number]) => { setTarget(ll); setPicking(false); }, []);
  const pick = useMemo(() => (N === 1 ? { active: picking, value: target, onPick, onBuildings: setBuildings, drawing: drawing && canDraw, ring: canDraw ? ring : [], onVertex: addVertex } : null), [N, picking, target, onPick, drawing, canDraw, ring, addVertex]);
  const saleErr = N !== 1 ? '' : needsUnit(sale.type) && !sale.unitType ? 'Ne satıldığını seçin: yapı türü eksik.'
    : sale.type === 'yapi' && !target ? 'Satılan yapıyı haritada işaretleyin.'
      : sale.type === 'hisse' && !/^\d{1,5}\/\d{1,6}$/.test(sale.share) ? 'Hisse oranını 1/2 biçiminde yazın.'
        : sale.rooms && !/^\d{1,2}\+\d{1,2}$/.test(sale.rooms) ? 'Oda sayısını 3+1 biçiminde yazın.'
          : canDraw && ring.length > 0 && ring.length < 3 ? 'Satılan bölüm için en az 3 köşe çizin ya da çizimi temizleyin.' : '';
  const needPlan = credits < N;
  const P = PLANS.find((p) => p.id === plan)!;
  useEffect(() => { if (needPlan && P.credits < N - credits) { const fit = PLANS.find((p) => p.credits >= N - credits); if (fit) setPlan(fit.id); } }, [N, credits, needPlan, P.credits]);

  async function submit() {
    if (!N) return;
    if (saleErr) { setErr(saleErr); return; }
    if (photosBusy || tourBusy) { setErr('Fotoğraflar yükleniyor, birkaç saniye bekleyin.'); return; }
    if (photos.some((p) => p.err)) { setErr('Yüklenemeyen fotoğrafı silin ya da yeniden ekleyin.'); return; }
    setErr('');
    const batchId = N > 1 ? 'b' + Math.random().toString(36).slice(2, 12) : undefined;
    const body = (p: Parcel, defer: boolean) => {
      const c = centroidOf(p);
      return JSON.stringify({
        plan, template: tpl, voice, lang, batchId, deferCheckout: defer || undefined, geometry: p.geometry, il: p.il, ilce: p.ilce, mahalle: p.mahalle, mahalleId: Number(f.mahalle), ada: String(p.ada), parsel: String(p.parsel),
        areaM2: p.alan, nitelik: p.nitelik, centroidLon: c[0], centroidLat: c[1],
        ...Object.fromEntries(Object.entries(imar).filter(([, v]) => v)), highlights: hl.map((x) => x.trim()).filter(Boolean), headline: headline || undefined,
        ...Object.fromEntries(Object.entries(contact).filter(([, v]) => v)),
        ...(N === 1 && Number(price.replace(/\D/g, '')) >= 1000 ? { price: Number(price.replace(/\D/g, '')) } : {}),
        ...(N === 1 && qrUrl.trim() ? { qrUrl: qrUrl.trim() } : {}),
        ...(N === 1 && photos.length ? { photoKeys: photos.map((p) => p.key!) } : {}),
        ...(N === 1 && tourKey ? { tourKey } : {}),
        ...(N === 1 && sale.type !== 'arsa' ? {
          saleType: sale.type, ...(needsUnit(sale.type) ? { unitType: sale.unitType, unitArea: Number(sale.unitArea) || undefined, rooms: sale.rooms || undefined,
            floorNo: sale.type === 'bagimsiz' ? sale.floorNo || undefined : undefined, buildYear: Number(sale.buildYear) || undefined } : {}),
          share: sale.type === 'hisse' ? sale.share : undefined, target: sale.type === 'yapi' && target ? target : undefined,
          targetRing: canDraw && ring.length >= 3 ? ring : undefined,
        } : {}),
      });
    };
    // Önce diğer parseller (krediden ya da ödeme sonrası başlar), en son ilk parsel: ödeme gerekiyorsa ödeme sayfası bununla açılır.
    let last: { redirect?: string; error?: string } = {};
    const order = [...parcels.slice(1), parcels[0]];
    for (let i = 0; i < order.length; i++) {
      setBusy(N > 1 ? `Sipariş ${i + 1}/${N} oluşturuluyor…` : 'Hazırlanıyor…');
      const r = await fetch('/api/orders', { method: 'POST', headers: { 'content-type': 'application/json' }, body: body(order[i], i < order.length - 1) });
      last = await r.json().catch(() => ({}));
      if (!r.ok) { setErr(last.error || 'Sipariş oluşturulamadı'); setBusy(''); return; }
    }
    if (last.redirect) { location.href = N > 1 && last.redirect.startsWith('/panel') ? '/panel/siparisler' : last.redirect; return; }
    setErr(last.error || 'Sipariş oluşturulamadı'); setBusy('');
  }

  return (
    <div className="flex min-h-full flex-col">
      <DeskFocus parcels={focus} compare />
      <DeskPick pick={pick} />
      <div className="px-4 pb-3 pt-4"><div className="tag">Stüdyo</div><h1 className="text-[22px] font-extrabold leading-tight">Yeni ilan videosu</h1></div>
      <Step n={1} title="Parseli bulun" hint="Sınır ve yüzölçümü Tapu Kadastro kaydından gelir, haritada çizilir.">
        <div className="grid grid-cols-2 border-l border-t border-ink/15">
          <Sel label="İl" opts={il} value={f.il} onChange={(v) => setF({ ...f, il: v, ilce: '', mahalle: '' })} />
          <Sel label="İlçe" opts={ilce} value={f.ilce} onChange={(v) => setF({ ...f, ilce: v, mahalle: '' })} disabled={!f.il} />
          <div className="col-span-2"><Sel label="Mahalle / köy" opts={mah} value={f.mahalle} onChange={(v) => setF({ ...f, mahalle: v })} disabled={!f.ilce} /></div>
        </div>
        <div className="mt-3 flex gap-4 text-[13px] font-semibold">
          {[[false, 'Tek parsel'], [true, 'Toplu (aynı mahalle)']].map(([b, l]) => <button key={String(b)} type="button" onClick={() => { setBatch(b as boolean); setParcels([]); setLookErr(''); }} className={`border-b-2 pb-1 ${batch === b ? 'border-signal' : 'border-transparent text-ink-soft'}`}>{l as string}</button>)}
        </div>
        <div className="mt-2 grid grid-cols-[1fr_1fr_auto] border-l border-t border-ink/15">
          {batch ? (
            <label className="cell col-span-2 border-b border-r border-ink/15"><span className="tag">Ada / parsel listesi (en çok 20)</span><input className="num" value={list} onChange={(e) => setList(e.target.value)} placeholder="101/5, 101/7, 102/1" /></label>
          ) : (<>
            <label className="cell border-b border-r border-ink/15"><span className="tag">Ada</span><input aria-label="Ada" className="num" inputMode="numeric" value={f.ada} onChange={(e) => setF({ ...f, ada: e.target.value.replace(/\D/g, '') })} placeholder="101" /></label>
            <label className="cell border-b border-r border-ink/15"><span className="tag">Parsel</span><input aria-label="Parsel" className="num" inputMode="numeric" value={f.parsel} onChange={(e) => setF({ ...f, parsel: e.target.value.replace(/\D/g, '') })} placeholder="5" /></label>
          </>)}
          <button onClick={lookup} disabled={!f.mahalle || !targets.length || looking} className="bg-ink px-4 text-[14px] font-bold text-white disabled:opacity-40">{looking ? 'Aranıyor…' : batch && targets.length > 1 ? `${targets.length} parseli bul` : 'Haritada bul'}</button>
        </div>
        {lookErr && <p role="status" className="mt-2 bg-ink px-3 py-2 text-[13px] text-white">{lookErr}</p>}
        {N > 0 && (
          <ul className="mt-3 border-t border-ink/15">
            {parcels.map((p, i) => (
              <li key={`${apShort(p.ada, p.parsel)}`} className="flex items-center justify-between gap-2 border-b border-ink/10 py-2 text-[13.5px]">
                <span className="flex items-center gap-2"><i className={`h-2.5 w-2.5 ${i === 0 ? 'bg-signal' : 'border border-ink'}`} /><b>{apLong(p.ada, p.parsel)}</b> <span className="text-ink-soft">{p.mevkii || p.mahalle}</span></span>
                <span className="num text-ink-soft">{Math.round(p.alan).toLocaleString('tr-TR')} m²{p.nitelik ? ` · ${p.nitelik}` : ''}</span>
              </li>
            ))}
          </ul>
        )}
      </Step>

      {N === 1 && main && (
        <Step n={2} title="Ne satıyorsunuz?" hint="Video, satılanı buna göre anlatır; tapu niteliği yine kayıttaki gibi gösterilir.">
          {buildings && (
            <p className={`mb-2 px-3 py-2 text-[13px] ${buildings.length && sale.type === 'arsa' ? 'bg-signal-soft font-semibold' : 'bg-paper-2'}`}>
              {/* OSM'de Türkiye'nin bina kaydı seyrek: yapı bulunamaması "yapı yok" demek değildir */}
              {buildings.length ? `Harita verisinde bu parselin içinde ${buildings.length} yapı görünüyor.` : 'Uydu görüntüsünde parselin üzerinde ev ya da başka bir yapı varsa, aşağıdan ne sattığınızı seçin.'}
              {buildings.length > 0 && sale.type === 'arsa' && ' Boş arsa değilse aşağıdan doğru seçeneği işaretleyin.'}
              {buildings.length > 1 && sale.type !== 'yapi' && sale.type !== 'bagimsiz' && ' Yalnızca birini satıyorsanız “Parseldeki yapılardan biri”ni seçin.'}
            </p>
          )}
          {/kat/i.test(main.zemin || '') && <p className="mb-2 bg-paper-2 px-3 py-2 text-[13px]">Tapu kaydı: <b>{main.zemin}</b>. Bağımsız bölüm (daire, dükkân) satıyor olabilirsiniz.</p>}
          <div className="border-t border-ink/15">
            {SALE_TYPES.map((t) => (
              <label key={t.id} className="flex cursor-pointer items-start gap-3 border-b border-ink/10 py-2">
                <input type="radio" name="saleType" checked={sale.type === t.id} onChange={() => { setSale({ ...sale, type: t.id, unitType: t.id === 'bagimsiz' && !sale.unitType ? 'Daire' : sale.unitType }); if (t.id !== 'yapi') setPicking(false); if (t.id !== 'yapi' && t.id !== 'hisse') setDrawing(false); }} className="mt-1 accent-[#FF6A1F]" />
                <span><b className="text-[14px]">{t.label}</b><span className="block text-[12.5px] text-ink-soft">{t.hint}</span></span>
              </label>
            ))}
          </div>
          {needsUnit(sale.type) && (
            <div className="mt-3 grid grid-cols-2 gap-2">
              <div className="col-span-2"><label className="label">Yapı türü</label>
                <select className="field" value={sale.unitType} onChange={(e) => setSale({ ...sale, unitType: e.target.value })}><option value="">Seçin</option>{UNIT_TYPES.map((u) => <option key={u}>{u}</option>)}</select></div>
              <div><label className="label">Brüt alan (m²)</label><input className="field num" inputMode="numeric" maxLength={6} placeholder="140" value={sale.unitArea} onChange={(e) => setSale({ ...sale, unitArea: e.target.value.replace(/\D/g, '') })} /></div>
              <div><label className="label">Oda sayısı</label><input className="field num" maxLength={5} placeholder="3+1" value={sale.rooms} onChange={(e) => setSale({ ...sale, rooms: e.target.value.replace(/[^\d+]/g, '') })} /></div>
              {sale.type === 'bagimsiz' && <div><label className="label">Kat</label><input className="field" maxLength={20} placeholder="2 ya da Bahçe katı" value={sale.floorNo} onChange={(e) => setSale({ ...sale, floorNo: e.target.value })} /></div>}
              <div><label className="label">Yapım yılı</label><input className="field num" inputMode="numeric" maxLength={4} placeholder="2012" value={sale.buildYear} onChange={(e) => setSale({ ...sale, buildYear: e.target.value.replace(/\D/g, '') })} /></div>
            </div>
          )}
          {sale.type === 'yapi' && (
            <div className="mt-3">
              <button type="button" onClick={() => { setPicking(!picking); setDrawing(false); }} className={`btn-sm btn w-full ${picking ? 'bg-signal text-ink' : target ? 'btn-line' : 'btn-ink'}`}>
                {picking ? 'Haritada satılan yapıya dokunun… (iptal)' : target ? 'Seçildi ✓ · değiştir' : 'Satılan yapıyı haritada seçin'}
              </button>
              <p className="mt-1 text-[12px] text-ink-soft">Haritada parselin içinde satılan evin çatısına dokunun; videodaki işaret oraya konur. Beyaz çizgiyle çizili bir yapıya dokunursanız işaret o yapının ortasına yerleşir.</p>
            </div>
          )}
          {sale.type === 'hisse' && (
            <div className="mt-3 w-40"><label className="label">Hisse oranı</label><input className="field num" maxLength={12} placeholder="1/2" value={sale.share} onChange={(e) => setSale({ ...sale, share: e.target.value.replace(/[^\d/]/g, '') })} /></div>
          )}
          {canDraw && (
            <div className="mt-3 border-t border-ink/10 pt-3">
              <div className="label">Satılan bölüm (isteğe bağlı)</div>
              <p className="mb-2 text-[12px] text-ink-soft">Parselin tamamını satmıyorsanız satılan kısmı çizin: haritada parselin içinde köşelere sırayla dokunun. Videoda bu bölüm vurgulanır ve yaklaşık alanı söylenir.</p>
              <div className="flex flex-wrap gap-2">
                <button type="button" onClick={() => { setDrawing(!drawing); setPicking(false); }} className={`btn-sm btn ${drawing ? 'bg-signal text-ink' : ring.length >= 3 ? 'btn-line' : 'btn-ink'}`}>
                  {drawing ? `Çiziliyor · ${ring.length} köşe · bitir` : ring.length >= 3 ? 'Çizildi ✓ · köşe ekle' : 'Satılan bölümü çiz'}
                </button>
                {ring.length > 0 && <button type="button" onClick={() => setRing(ring.slice(0, -1))} className="btn-sm btn btn-line">Son köşeyi sil</button>}
                {ring.length > 0 && <button type="button" onClick={() => setRing([])} className="btn-sm btn btn-line">Temizle</button>}
              </div>
              {ring.length >= 3 && <p className="mt-1.5 text-[12.5px] font-semibold">Çizilen alan ≈ {Math.round(ringArea(ring)).toLocaleString('tr-TR')} m² (parselin {Math.round(main.alan).toLocaleString('tr-TR')} m²’si)</p>}
            </div>
          )}
          <div className="mt-3 border-t border-ink/10 pt-3">
            <div className="label">Fotoğraflar (isteğe bağlı)</div>
            <p className="mb-2 text-[12px] text-ink-soft">
              {needsUnit(sale.type) ? 'Evin içinden ve dışından fotoğraflar ekleyin; videoda, yapı anlatılırken bu sırayla gösterilir.' : 'Araziden, manzaradan ya da yoldan fotoğraf ekleyebilirsiniz; videoda parsel anlatıldıktan sonra gösterilir.'}
              {' '}Fotoğraf eklemezseniz video yalnızca uydu görüntüsüyle hazırlanır.
            </p>
            <PhotoUpload photos={photos} onChange={setPhotos} />
            <div className="mt-3">
              <div className="label">360° sanal tur (isteğe bağlı)</div>
              <p className="mb-2 text-[12px] text-ink-soft">360° kamerayla çekilmiş tek bir panorama fotoğrafı ekleyin; izleme sayfasında alıcı etrafına bakabilir. (Normal fotoğraf değil, equirectangular 360° görsel olmalı.)</p>
              <TourUpload onKey={(k, b) => { setTourKey(k); setTourBusy(b); }} />
            </div>
          </div>
        </Step>
      )}

      <Step n={3} title="Şablon" hint="Üzerine gelince ya da dokununca örnek oynar.">
        <div className="grid grid-cols-3 gap-2">
          {TEMPLATES.map((t) => (
            <button key={t.id} type="button" onClick={() => setTpl(t.id)} className={`relative text-left ${tpl === t.id ? 'outline outline-[3px] outline-offset-0 outline-signal' : ''}`}>
              <video src={`/ornekler/${t.id}.mp4`} poster={`/ornekler/${t.id}.jpg`} muted loop playsInline preload="none" onMouseEnter={(e) => e.currentTarget.play().catch(() => {})} onMouseLeave={(e) => e.currentTarget.pause()} className="block aspect-[9/16] w-full bg-ink object-cover" />
              <span className={`absolute left-0 top-0 px-1.5 py-0.5 text-[11.5px] font-bold uppercase ${tpl === t.id ? 'bg-signal text-ink' : 'bg-white text-ink'}`}>{t.name}</span>
            </button>
          ))}
        </div>
      </Step>

      <Step n={4} title="Dil ve ses" hint="Yabancı alıcılar için: seçtiğiniz dilde seslendirme, altyazı ve haritadaki kartlar. Yer adları olduğu gibi kalır.">
        <div className="mb-2 inline-flex border border-ink/20">
          {LANGS.map((l) => (
            <button key={l.id} type="button" onClick={() => { setLang(l.id); setVoice(defaultVoiceFor(l.id)); }}
              className={`h-8 px-3 text-[13px] font-semibold ${lang === l.id ? 'bg-ink text-white' : 'bg-white text-ink hover:bg-paper-2'}`}>{l.name}</button>
          ))}
        </div>
        <div className="border-t border-ink/15">
          {VOICES.map((v) => (
            <label key={v.id} className="flex cursor-pointer items-center gap-3 border-b border-ink/10 py-2 text-[14px]"><input type="radio" name="voice" checked={voice === v.id} onChange={() => setVoice(v.id)} className="accent-[#FF6A1F]" />
              <span className="flex-1"><b>{v.name}</b> <span className="text-[12.5px] text-ink-soft">{v.note}</span></span>
              <button type="button" onClick={(e) => { e.preventDefault(); preview(v.id); }} className={`h-7 px-2.5 text-[12.5px] font-semibold ${playing === v.id ? 'bg-signal text-ink' : 'bg-ink text-white'}`}>{playing === v.id ? 'Durdur' : 'Dinle'}</button>
            </label>
          ))}
        </div>
      </Step>

      <Step n={5} title="İmar ve notlar" hint="Boş bıraktığınız bilgi videoya eklenmez.">
        <div className="grid grid-cols-2 gap-2">
          <div className="col-span-2"><label className="label">İmar durumu</label><input className="field" maxLength={80} placeholder="Konut alanı / Tarla / Ticari…" value={imar.imarDurum} onChange={(e) => setImar({ ...imar, imarDurum: e.target.value })} /></div>
          <div><label className="label">Emsal (KAKS)</label><input className="field" maxLength={12} placeholder="0.40" value={imar.emsal} onChange={(e) => setImar({ ...imar, emsal: e.target.value })} /></div>
          <div><label className="label">TAKS</label><input className="field" maxLength={12} placeholder="0.20" value={imar.taks} onChange={(e) => setImar({ ...imar, taks: e.target.value })} /></div>
          <div><label className="label">Gabari</label><input className="field" maxLength={12} placeholder="6.50 m" value={imar.gabari} onChange={(e) => setImar({ ...imar, gabari: e.target.value })} /></div>
          <div><label className="label">Başlık</label><input className="field" maxLength={80} placeholder="Denize yakın arsa" value={headline} onChange={(e) => setHeadline(e.target.value)} /></div>
          {hl.map((h, i) => <div key={i} className={i === 2 ? 'col-span-2' : ''}><label className="label">Not {i + 1}</label><input className="field" maxLength={60} placeholder={['Denize 2 km', 'Elektrik ve su mevcut', 'Asfalt yola cephe'][i]} value={h} onChange={(e) => setHl(hl.map((x, j) => (j === i ? e.target.value : x)))} /></div>)}
        </div>
      </Step>

      <Step n={6} title="Kapanış kartı">
        <div className="grid grid-cols-2 gap-2">
          <div><label className="label">Ad / ofis adı</label><input className="field" maxLength={60} value={contact.contactName} onChange={(e) => setContact({ ...contact, contactName: e.target.value })} /></div>
          <div><label className="label">Telefon</label><input className="field" maxLength={30} value={contact.contactPhone} onChange={(e) => setContact({ ...contact, contactPhone: e.target.value })} placeholder="0 (5xx) xxx xx xx" /></div>
          {N <= 1 && <>
            <div><label className="label">İlan fiyatı (TL, isteğe bağlı)</label><input className="field num" inputMode="numeric" maxLength={16} placeholder="3.750.000" value={price}
              onChange={(e) => { const d = e.target.value.replace(/\D/g, '').slice(0, 10); setPrice(d ? Number(d).toLocaleString('tr-TR') : ''); }} /></div>
            <div><label className="label">Karekod linki (isteğe bağlı)</label><input className="field" type="url" maxLength={300} placeholder="https://www.sahibinden.com/ilan/… ya da https://wa.me/905…" value={qrUrl} onChange={(e) => setQrUrl(e.target.value)} /></div>
          </>}
        </div>
        {N <= 1 && <p className="mt-1.5 text-[12.5px] text-ink-soft">Fiyat girerseniz videonun ilk saniyesinde ve kapanış kartında görünür. Karekod, kapanış kartında bu linke götürür.</p>}
        <p className="mt-2 text-[12.5px] text-ink-soft">{defaults.logo ? "Kartta Ayarlar'a yüklediğiniz logo kullanılır. " : 'Kartta logonuzun görünmesi için '}<a href="/panel/ayarlar" className="font-semibold underline underline-offset-2">{defaults.logo ? 'Logoyu değiştir' : "Ayarlar'dan logo yükleyin"}</a></p>
      </Step>

      <div className="sticky bottom-0 mt-auto border-t-2 border-ink bg-white px-4 py-3">
        <div className="flex items-baseline justify-between gap-3 text-[13.5px]">
          <span className="min-w-0 truncate font-bold">{main ? (N > 1 ? `${main.mahalle} · ${N} parsel` : `${main.mahalle} ${apShort(main.ada, main.parsel)}`) : 'Parsel seçilmedi'}</span>
          <span className="shrink-0 text-ink-soft">{TEMPLATES.find((t) => t.id === tpl)?.name} · {VOICES.find((v) => v.id === voice)?.name}</span>
        </div>
        {needPlan && (
          <div className="mt-2 grid grid-cols-3 border-l border-t border-ink/15">
            {PLANS.map((p) => (
              <label key={p.id} className={`cell cursor-pointer border-b border-r border-ink/15 py-2 ${plan === p.id ? 'bg-signal-soft' : ''} ${p.credits < N - credits ? 'opacity-40' : ''}`}>
                <span className="tag flex items-center gap-1.5"><input type="radio" name="plan" checked={plan === p.id} disabled={p.credits < N - credits} onChange={() => setPlan(p.id)} className="accent-[#FF6A1F]" />{p.name}</span>
                <PlanPrice plan={p} size="sm" badge={false} /><span className="text-[11.5px] text-ink-soft">{p.credits} video</span>
              </label>
            ))}
          </div>
        )}
        {needPlan && N > 1 && credits > 0 && <p className="mt-1.5 text-[12px] text-ink-soft">{credits} parsel kredinizden başlar; kalan {N - credits} için paket seçin.</p>}
        {err && <p className="mt-2 text-[13px] font-semibold text-survey-dark">{err}</p>}
        <button onClick={submit} disabled={!N || !!busy || photosBusy || tourBusy} className="btn-signal mt-2 w-full">{busy || (!N ? 'Önce parseli bulun' : photosBusy || tourBusy ? 'Fotoğraflar yükleniyor…' : !needPlan ? `${N > 1 ? `${N} videoyu` : 'Videoyu'} üret · ${N} kredi` : `${tl(P.price)} öde ve üret`)}</button>
        <p className="mt-1.5 text-center text-[11.5px] text-ink-soft">Krediniz: {credits}. Ödeme Dodo Payments ile alınır; üretim tamamlanmazsa kredi iade edilir.</p>
        <p className="mt-1 text-center text-[11.5px] text-ink-soft">Sipariş vererek üretimin hemen başlamasını ve <Link href="/mesafeli-satis" className="underline underline-offset-2">Mesafeli Satış Sözleşmesi</Link>&apos;ni kabul edersiniz; üretimi başlayan videoda cayma hakkı yoktur.</p>
      </div>
    </div>
  );
}
