import React, { useRef } from 'react'; import { useApp } from '../context/AppContext'; import { bidSourceSnapshot } from '../services/bidSource'; import { documentKey } from '../services/preparationChecks'; import { YeterlilikRozeti } from './YeterlilikRozeti'; import { AlertOctagon, AlertTriangle, Eye, CalendarClock, ClipboardList, Route, HelpCircle, Coins, Target, Package, } from 'lucide-react'; import { BidPackageBuilder } from './BidPackageBuilder'; /** * Derin analiz raporu — /api/ai/analyze mode='derin' çıktısını gösterir. * Standart analizden farkı: elenme sebepleri, gözden kaçan ince detaylar, * belge kontrol listesi, süreler ve teklife kadarki yol haritası. * * Model alanları kısmi doldurabilir; her bölüm kendi verisi varsa çizilir. */ const SEVIYE_RENK = { Kritik: 'bg-red-100 text-red-800 border-red-200', Yüksek: 'bg-orange-100 text-orange-800 border-orange-200', Orta: 'bg-amber-100 text-amber-800 border-amber-200', Düşük: 'bg-slate-200 text-slate-700 border-slate-300', }; const FAZ_RENK = { Hazırlık: 'bg-slate-700', 'Belge Toplama': 'bg-blue-600', Teknik: 'bg-indigo-600', Fiyatlandırma: 'bg-emerald-600', Teklif: 'bg-amber-600', Sözleşme: 'bg-purple-600', }; const evidenceLabel = path => { const [field,index] = path.split('.'); return `${({itemsAndSpecs:'Kalem',documentChecklist:'Belge',qualificationCriteria:'Yeterlik',criticalRequirements:'Kritik koşul',risksAndPenalties:'Risk',criticalDetails:'Kritik ayrıntı',disqualificationRisks:'Eleme riski',deadlines:'Süre',roadmap:'Hazırlık adımı'})[field] || 'Bulgu'} ${Number(index)+1}`; }; const dolu = (x) => Array.isArray(x) && x.length > 0; const tl = (n) => typeof n === 'number' && isFinite(n) ? n.toLocaleString('tr-TR', { maximumFractionDigits: 2 }) + ' ₺' : null; const Baslik = ({ icon: Icon, renk, children, not }) => (

{children} {not && {not}}

); export const DeepAnalysisReport = ({ results, tender: selectedTender }) => { const {tenders, mutateTender, savingCount, saveError} = useApp(); const preparationRef = useRef(null); const tender = {...selectedTender, ...tenders.find(t => t.id === selectedTender?.id)}; const sourceSnapshot = bidSourceSnapshot(tender, results); const savedSteps = Array.isArray(tender.checklist) ? tender.checklist : []; const stepDone = key => savedSteps.some(s => s.key === key && s.sourceSnapshot === sourceSnapshot && s.done); const toggleStep = key => mutateTender(tender.id, {checklist:[ ...savedSteps.filter(s => s.key !== key), {key, sourceSnapshot, done:!stepDone(key)}, ]}); if (!results) return null; const { scopeOfWork, disqualificationRisks, criticalDetails, documentChecklist, deadlines, costDrivers, roadmap, questionsForAdministration, itemsAndSpecs, } = results; const varMi = scopeOfWork || dolu(disqualificationRisks) || dolu(criticalDetails) || dolu(documentChecklist) || dolu(deadlines) || dolu(costDrivers) || dolu(roadmap) || dolu(questionsForAdministration) || dolu(itemsAndSpecs); if (!varMi) return null; return (
{results.sourceReview &&

{results.sourceReview.status === 'partial' ? 'Kısmi analiz — kontrol gerekli' : 'Analiz üretildi — kaynak doğrulaması gerekli'}

Kaynak: {results.sourceReview.fileName || 'Gönderilen metin'} · {results.sourceReview.analyzedCharacters} / {results.sourceReview.sourceCharacters} karakter işlendi

{(results.sourceReview.issues || []).map(issue=>

{issue}

)} {results.sourceReview.parts &&

İşlenen bölümler: {results.sourceReview.parts.filter(p=>p.status==='processed').length} / {results.sourceReview.parts.length}

}

Boş bir bölüm, ilgili şartın kaynakta bulunmadığı anlamına gelmez.

} {results.sourceReview?.unverifiedFindings?.length > 0 &&

{results.sourceReview.unverifiedFindings.length} bulgunun tekil kaynak alıntısı doğrulanamadı. Resmi metinden kontrol edin.

} {results.sourceEvidence?.length > 0 &&
Kaynak alıntıları ({results.sourceEvidence.length})

Metinde bulunması, modelin yorumunun doğru olduğunu tek başına kanıtlamaz.

{results.sourceEvidence.map((e,i)=>

{evidenceLabel(e.path)} — {e.status==='located'?'Alıntı kaynakta bulundu':e.status==='ambiguous'?'Alıntı birden fazla yerde geçiyor':'Alıntı kaynakta bulunamadı'}

{e.quote}
)}
} {/* İşin kapsamı */} {scopeOfWork && (
İşin Kapsamı

{scopeOfWork}

)} {/* UYARI — teklifi geçersiz kılan noktalar */} {dolu(disqualificationRisks) && (

Teklifinizi Geçersiz Kılabilecek Noktalar

Bu maddelerden biri eksikse teklif değerlendirme dışı bırakılabilir.

)} {/* Gözden kaçan ince detaylar */} {dolu(criticalDetails) && (
Gözden Kaçmaması Gereken İnce Detaylar
{criticalDetails.map((d, i) => (
{d.title || 'Detay'}
{d.where && ( {d.where} )} {d.level || 'Orta'}
{d.detail &&

{d.detail}

} {d.whyItMatters && (

Neden önemli: {d.whyItMatters}

)}
))}
)} {/* Alınacak ürün/hizmet: evsaf, miktar, tahmini fiyat */} {dolu(itemsAndSpecs) && (
Alınacak Kalemler & Aranan Evsaflar
{itemsAndSpecs.map((k, i) => (
{k.name || '—'}
{k.quantity && ( {k.quantity} )} {tl(k.estimatedUnitPrice) && ( birim {tl(k.estimatedUnitPrice)} )} {tl(k.estimatedTotal) && ( toplam {tl(k.estimatedTotal)} )}
{dolu(k.keySpecs) && (
    {k.keySpecs.map((e, j) => (
  • {e}
  • ))}
)} {k.note &&

{k.note}

}
))}

Fiyatlar yalnızca şartnamede/ilanda geçiyorsa gösterilir; model tahmin üretmez.

)}
{/* Source requirements summarize the single saved preparation checklist. */} {dolu(documentChecklist) && (
Belge Gereksinimleri

Kontrolleri aşağıdaki hazırlık formunda kaynaklarıyla kaydedin.

    {documentChecklist.map((b, i) => { const check = tender.bidDraft?.checks?.documents?.[documentKey(b)]; return
  • {b.document || '—'}

    {b.note}

    {check?.status === 'verified' && check?.evidence?.trim() ? 'Kayıtlı kullanıcı kontrolü var; güncel kaynak kontrolünü hazırlık formundan doğrulayın.' : 'Belge kontrolü bekliyor.'}

  • ; })}
)} {/* Süreler + maliyet sürücüleri */}
{dolu(deadlines) && (
Kritik Tarihler & Süreler
{deadlines.map((d, i) => (
{d.label || '—'} {d.value || '—'}
{d.note &&

{d.note}

}
))}
)} {dolu(costDrivers) && (
Maliyeti Belirleyen Kalemler
    {costDrivers.map((c, i) => (
  • {c}
  • ))}
)}
{/* Yol haritası */} {dolu(roadmap) && (
Teklife Kadar Yol Haritası
    {roadmap.map((a, i) => { const k = JSON.stringify(a); const secili = stepDone(k); return (
  1. {i < roadmap.length - 1 &&
    }
    {a.action || '—'} {a.phase && ( {a.phase} )}
    {a.owner && Kim: {a.owner}} {a.timing && Ne zaman: {a.timing}} {a.output && Çıktı: {a.output}}
  2. ); })}
)} {/* İdareye sorulacaklar */} {dolu(questionsForAdministration) && (
İdareye Sorulması Gereken Belirsizlikler

Bu sorular için şartnamede belirtilen süre içinde idareye açıklama talebi / zeyilname başvurusu yapabilirsiniz.

)} {/* Analiz ve yol haritası okunduktan sonraki adım: teklif zarfını hazırla */} {saveError &&

{saveError}

}
); };