import { Request, Response } from 'express';
import { AuthenticatedRequest } from '../middleware/auth';
import { callOllama } from '../lib/aiClient';
import { supabase } from '../lib/supabase';
import fs from 'fs';
import path from 'path';

export const searchPrecedents = async (req: Request, res: Response) => {
  try {
    const { phrase, court_types, page_number } = req.body;

    if (!phrase) {
      return res.status(400).json({ error: 'Arama metni (phrase) zorunludur.' });
    }

    let optimizedPhrase = phrase;
    
    // Eğer sorgu 3 kelimeden uzunsa (doğal dil sorusu ise), AI ile anahtar kelimelere dönüştür
    if (phrase.split(' ').length > 3) {
      const systemPrompt = `Sen uzman bir Türk avukatısın. Kullanıcının uzun ve doğal dille yazdığı hukuki soruyu, Yargıtay içtihat arama motorunda en iyi sonucu verecek şekilde 2 ila en fazla 4 temel hukuki terime/anahtar kelimeye çevir.
SADECE anahtar kelimeleri aralarına boşluk koyarak yaz. Noktalama işareti, açıklama veya ek kelimeler (ve, ile, vb.) kullanma.
Örnek Kullanıcı: İşveren tarafından performans düşüklüğü gerekçesiyle iş sözleşmesi feshedilen işçinin işe iade davası açması halinde ispat yükü kime aittir
Örnek Cevap: performans düşüklüğü ispat yükü işe iade`;

      // AI ile sorgu optimizasyonu isteğe bağlı bir iyileştirme — config eksikse veya
      // istek başarısız olursa arama yine de optimize edilmemiş phrase ile devam eder.
      // Çıktı birkaç kelimelik bir anahtar kelime listesi olduğu için num_predict düşük
      // tutuluyor — hem daha hızlı yanıt hem modelin gereksiz uzatmasını önler.
      try {
        const aiContent = await callOllama([
          { role: 'system', content: systemPrompt },
          { role: 'user', content: phrase },
        ], { numPredict: 40, timeoutMs: 20_000 });
        if (aiContent) {
          optimizedPhrase = aiContent.trim().replace(/["'\n]/g, '');
          console.log(`[AI Search] Orijinal: "${phrase}" -> Optimize: "${optimizedPhrase}"`);
        }
      } catch (err) {
        console.error('AI Query Optimization Error:', err);
      }
    }

    // Yargı MCP REST API'sine (8001 portu veya YARGI_MCP_URL) optimize edilmiş sorgu ile istek at
    const mcpBaseUrl = process.env.YARGI_MCP_URL || 'http://localhost:8001';
    const mcpResponse = await fetch(`${mcpBaseUrl}/search`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        phrase: optimizedPhrase,
        court_types: court_types || ["YARGITAYKARARI", "DANISTAYKARAR"],
        page_number: page_number || 1
      })
    });

    if (!mcpResponse.ok) {
      const errorData = await mcpResponse.text();
      console.error('Yargı MCP API Error:', errorData);
      return res.status(mcpResponse.status).json({ error: 'Arama servisi hata döndürdü', details: errorData });
    }

    let data = await mcpResponse.json();

    // Hukuki niyet ve sonuç (örn. beraat, bozma) odaklı akıllı yeniden sıralama ve puanlama
    let rawItems: any[] = data.decisions || data.results || data.data || data.hits || (Array.isArray(data) ? data : []);

    if (Array.isArray(rawItems) && rawItems.length > 0) {
      const searchTerms = phrase.toLowerCase().split(/\s+/).filter((Boolean) as (value: string) => boolean);
      const isBeraatSearch = searchTerms.some((t: string) => t.includes('beraat'));
      const isBozmaSearch = searchTerms.some((t: string) => t.includes('bozma') || t.includes('bozulması'));

      const scoredItems = rawItems.map((item: any) => {
        const fullText = (
          item.ozet || item.kararMetni || item.summary || item.content || item.title || item.konu || item.birimAdi || ''
        );
        const lowerText = fullText.toLowerCase();

        let baseScore = 70;
        
        // 1. Arama terimlerinin metindeki kapsama oranı
        const matchCount = searchTerms.filter((term: string) => lowerText.includes(term)).length;
        const matchRatio = searchTerms.length > 0 ? matchCount / searchTerms.length : 1;
        baseScore += Math.round(matchRatio * 15);

        // 2. Beraat araması için özel akıbet analizi ve filtreleme
        if (isBeraatSearch) {
          const hasExplicitBeraat = lowerText.includes('beraat') || lowerText.includes('beraatına') || lowerText.includes('beraatine') || lowerText.includes('beraat kararı');
          const isBeraatOnamasi = lowerText.includes('beraatına ilişkin') || lowerText.includes('beraatine ilişkin') || lowerText.includes('beraat hükmünün');
          const isPureMahkumiyetOnama = (lowerText.includes('mahkumiyetine') || lowerText.includes('mahkûmiyetine')) && (lowerText.includes('onanmasına') || lowerText.includes('itirazın reddine'));

          if (hasExplicitBeraat || isBeraatOnamasi) {
            baseScore += 30; // Gerçek beraat içeren kararlar en üste
          }
          if (isPureMahkumiyetOnama && !hasExplicitBeraat) {
            baseScore -= 45; // Mahkumiyet onaması olup beraat içermeyenleri dibe düşür
          }
        }

        // 3. Bozma araması için özel analiz
        if (isBozmaSearch) {
          if (lowerText.includes('bozulmasına') || lowerText.includes('bozma')) {
            baseScore += 25;
          } else if (lowerText.includes('onanmasına')) {
            baseScore -= 30;
          }
        }

        // 4. Pasaj (Özet) Cımbızlama: Aranan netice cümlesini tam ortalayarak özet yap
        const keyTarget = isBeraatSearch ? 'beraat' : (isBozmaSearch ? 'bozulmasına' : searchTerms[0]);
        if (keyTarget && lowerText.includes(keyTarget)) {
          const idx = lowerText.indexOf(keyTarget);
          const start = Math.max(0, idx - 90);
          const end = Math.min(fullText.length, idx + 150);
          item.ozet = '...' + fullText.slice(start, end).trim() + '...';
        }

        const finalScore = Math.max(30, Math.min(98, baseScore));
        return { ...item, relevanceScore: finalScore, score: finalScore };
      });

      // En yüksek beraat/netice eşleşmesine göre yeniden sırala
      scoredItems.sort((a: any, b: any) => b.relevanceScore - a.relevanceScore);

      if (data.results) data.results = scoredItems;
      else if (data.decisions) data.decisions = scoredItems;
      else if (data.data) data.data = scoredItems;
      else if (Array.isArray(data)) data = scoredItems;
    }

    res.json(data);
  } catch (error: any) {
    console.error('Search Precedents Error:', error);
    res.status(500).json({ error: error.message || 'Internal Server Error' });
  }
};

interface PrecedentSummary {
  birimAdi?: string;
  mahkeme?: string;
  kararTarihiStr?: string;
  tarih?: string;
  esasNo?: string;
  esas_no?: string;
  kararNo?: string;
  karar_no?: string;
  [key: string]: unknown;
}

// Analiz modu: bulunan kararları kullanıcının anlattığı durumla birlikte AI'ye
// göndererek kısa bir hukuki değerlendirme üretir. Maliyetli bir AI çağrısı olduğu
// için requireAuth ile korunuyor (bkz. routes/precedent.routes.ts).
export const analyzePrecedents = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { situation, results } = req.body as { situation?: string; results?: PrecedentSummary[] };
    if (!situation || !Array.isArray(results) || results.length === 0) {
      return res.status(400).json({ error: 'situation ve results zorunludur.' });
    }

    const listText = results.slice(0, 8).map((r, i) => {
      const mahkeme = r.birimAdi || r.mahkeme || 'Bilinmeyen Mahkeme';
      const tarih = r.kararTarihiStr || r.tarih || '';
      const esas = r.esasNo || r.esas_no || '';
      const karar = r.kararNo || r.karar_no || '';
      return `${i + 1}. ${mahkeme} (${tarih}) — Esas: ${esas}, Karar: ${karar}`;
    }).join('\n');

    const systemPrompt = 'Sen uzman bir Türk avukatısın. Kullanıcının anlattığı hukuki durumu, aşağıda listelenen emsal karar arama sonuçları ışığında kısaca değerlendir. Hangi kararların duruma daha yakın olabileceğini belirt ve olası bir hukuki değerlendirme sun. Emin olmadığın noktalarda bunu açıkça belirt, uydurma bilgi verme. Cevabın yaklaşık 150-250 kelime olsun.';
    const userPrompt = `DURUM:\n${String(situation).slice(0, 3000)}\n\nBULUNAN KARARLAR:\n${listText}`;

    const analysis = await callOllama([
      { role: 'system', content: systemPrompt },
      { role: 'user', content: userPrompt },
    ], { numPredict: 500 }) || 'Analiz üretilemedi.';
    res.json({ analysis });
  } catch (error: any) {
    console.error('Analyze Precedents Error:', error);
    res.status(500).json({ error: error.message || 'Internal Server Error' });
  }
};

export const getPrecedentDocument = async (req: Request, res: Response) => {
  try {
    const documentId = String(req.params.documentId || '');

    if (!documentId) {
      return res.status(400).json({ error: 'documentId zorunludur.' });
    }

    const mcpBaseUrl = process.env.YARGI_MCP_URL || 'http://localhost:8001';
    const mcpResponse = await fetch(`${mcpBaseUrl}/document/${encodeURIComponent(documentId)}`);

    if (!mcpResponse.ok) {
      const errorData = await mcpResponse.text();
      console.error('Yargı MCP API Error:', errorData);
      return res.status(mcpResponse.status).json({ error: 'Belge servisi hata döndürdü', details: errorData });
    }

    const data = await mcpResponse.json();
    res.json(data);
  } catch (error: any) {
    console.error('Get Precedent Document Error:', error);
    res.status(500).json({ error: error.message || 'Internal Server Error' });
  }
};

export const cachePrecedentDocument = async (req: Request, res: Response) => {
  try {
    const { item, content } = req.body;
    
    if (!item || !item.documentId || !content) {
      return res.status(400).json({ error: 'Eksik veri (item veya content)' });
    }

    const documentId = String(item.documentId);

    // 0. Duplicate Kontrolü (Veritabanında var mı?)
    try {
      const { data: existing } = await supabase
        .from('cached_precedents')
        .select('document_id')
        .eq('document_id', documentId)
        .single();
        
      if (existing) {
        console.log(`[Cache] Karar zaten arşivde mevcut, işlem atlandı: ${documentId}`);
        return res.json({ success: true, message: 'Zaten ön bellekte', cached: true });
      }
    } catch (err) {
      // Eğer tablo boşsa veya hata verirse devam et, sorun yok.
    }

    // 1. BunnyCDN'e Yükle
    const bunnyZone = process.env.BUNNY_STORAGE_ZONE || '';
    const bunnyKey = process.env.BUNNY_STORAGE_API_KEY || '';
    const bunnyCdnUrl = process.env.BUNNY_CDN_URL || '';
    
    let uploadedToCdn = false;
    let finalCdnUrl = '';

    if (bunnyZone && bunnyKey) {
      try {
        const uploadUrl = `https://storage.bunnycdn.com/${bunnyZone}/precedents/${documentId}.txt`;
        const response = await fetch(uploadUrl, {
          method: 'PUT',
          headers: {
            'AccessKey': bunnyKey,
            'Content-Type': 'text/plain; charset=utf-8'
          },
          body: content
        });

        if (response.ok) {
          uploadedToCdn = true;
          finalCdnUrl = bunnyCdnUrl ? `${bunnyCdnUrl}/precedents/${documentId}.txt` : uploadUrl;
          console.log(`[Cache] BunnyCDN'e yüklendi: ${documentId}`);
        } else {
          console.error(`[Cache] BunnyCDN Yükleme Hatası: ${response.statusText}`);
        }
      } catch (err) {
        console.error('[Cache] BunnyCDN Bağlantı Hatası:', err);
      }
    } else {
      console.warn('[Cache] BunnyCDN ayarları eksik. Sadece DB kaydı yapılacak.');
    }

    // 2. Supabase DB'ye Metadata Kaydet (Lazy Caching & Meilisearch Indexing)
    try {
      const { error } = await supabase
        .from('cached_precedents')
        .upsert({
          document_id: documentId,
          mahkeme: item.mahkeme || '',
          karar_no: item.karar_no || '',
          esas_no: item.esas_no || '',
          tarih: item.tarih || '',
          konu: item.konu || '',
          ozet: item.ozet || '',
          cdn_url: finalCdnUrl || null,
          created_at: new Date().toISOString()
        }, { onConflict: 'document_id' });
        
      if (error) {
        console.error('[Cache] Supabase kayıt hatası:', error.message);
      } else {
        console.log(`[Cache] Başarıyla kaydedildi: ${documentId}`);
      }
    } catch (dbErr) {
      console.error('[Cache] Supabase try-catch hatası:', dbErr);
    }
    
    res.json({ success: true, message: 'Ön belleğe alındı' });
  } catch (error: any) {
    console.error('Cache Precedent Document Error:', error);
    res.status(500).json({ error: error.message || 'Internal Server Error' });
  }
};
