import { Response } from 'express';
import { supabase } from '../lib/supabase';
import { AuthenticatedRequest } from '../middleware/auth';
import { runIddianameAnalysis, runCaseNarrativeAnalysis, runStatementAnalysis, runDeficiencyAnalysis, runStrategyAnalysis, runMediationAnalysis, runDigitalInternQa } from './document.controller';
import { findOrCreateCaseByTitle } from '../lib/caseLookup';
import { findRelevantLegislation, LegislationMatch } from '../lib/legislationLookup';

function formatLegislationBlock(matches: LegislationMatch[]): string {
  if (matches.length === 0) return '';
  const body = matches
    .map((m) => `${m.kanun} madde ${m.maddeNo}${m.baslik ? ` - ${m.baslik}` : ''}: ${m.metin}`)
    .join('\n\n');
  return `İLGİLİ MEVZUAT:\n${body}\n\n---\n\n`;
}

function toTraceableLegislation(matches: LegislationMatch[]) {
  return matches.map(({ maddeNo, baslik, kanun }) => ({ maddeNo, baslik, kanun }));
}

export const createCase = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const userId = req.user?.id;
    const title = String(req.body?.title || 'Yeni Sohbet').slice(0, 200);
    // kind ayrımı: 'case' = Dava Dosyaları'nda listelenen gerçek dosyalar,
    // 'chat' = Sohbet ekranındaki "Yeni Sohbet" ile açılan, dosya olmayan konuşmalar.
    // Dava Dosyaları listesi sadece kind='case' olanları gösteriyor.
    const kind = req.body?.kind === 'chat' ? 'chat' : 'case';
    // requireAuth doğrudan kullanıcının kendi id'sini set ediyor; başkasının hesabına
    // dosya oluşturulamaz. Yazma frontend'in anon client'ı yerine burada (service_role
    // ile) yapılıyor, cases için de RLS engeli yaşanmasın diye.
    const { data, error } = await supabase
      .from('cases')
      .insert([{ title, user_id: userId, kind }])
      .select('id, title')
      .single();
    if (error) throw error;
    res.json({ case: data });
  } catch (error: any) {
    console.error('Create Case Error:', error);
    res.status(500).json({ error: error.message || 'Internal Server Error' });
  }
};

// Türkçe İ/I harflerinin regex /i bayrağıyla güvenilir eşleşmemesi (Unicode
// case-folding sorunu) yüzünden manuel normalize ediyoruz.
function normalizeTr(s: string): string {
  return s.replace(/İ/g, 'i').replace(/I/g, 'i').toLowerCase();
}

// Dava dosyasındaki TÜM belgelerin çıkarılmış metnini birleştirip kapsamlı, anlatı
// biçiminde bir "Dosya Özeti" raporu üretir (Dosya Ayrıntı ekranındaki "Özet Hazırla"
// butonu). uploadDocument'ın aksine tek bir belgeye değil, dosyanın o anki tüm
// belgelerine bakıyor.
//
// Dosyada bir iddianame varsa önce SADECE onun üzerinden dar kapsamlı bir ön
// çıkarım yapılıyor (isnat edilen suç, iddia özeti, kritik tarihler); anlatı
// raporu bu ön çıkarımı bağlam olarak alıp tüm belgelerle birlikte üretiliyor —
// böylece iddianamedeki temel olgular raporun başlangıç noktası oluyor.
//
// Not: "Bu dosyadaki tüm evraklar işlenene kadar bekle" kontrolü burada DEĞİL,
// frontend'de (CaseDetail) yapılıyor — çünkü eklentiden indirilip henüz OCR/kayıt
// kuyruğunda bekleyen evraklar sadece Electron'un yerel durumunda görünüyor,
// backend'in bundan haberi yok.
export const summarizeCase = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { caseId } = req.params;
    if (!caseId) {
      return res.status(400).json({ error: 'Geçersiz caseId' });
    }

    const { data: docs, error: docsError } = await supabase
      .from('documents')
      .select('filename, extracted_text')
      .eq('case_id', caseId)
      .order('uploaded_at', { ascending: true });
    if (docsError) throw docsError;

    const withText = (docs || []).filter((d) => d.extracted_text && String(d.extracted_text).trim());
    if (withText.length === 0) {
      return res.status(400).json({ error: 'Bu dosyada metni çıkarılmış belge yok, özet hazırlanamıyor.' });
    }

    const iddianameDoc = withText.find((d) =>
      normalizeTr(d.filename).includes('iddianame') ||
      normalizeTr(String(d.extracted_text)).slice(0, 500).includes('iddianame')
    );

    let iddianameJson: any = null;
    if (iddianameDoc) {
      try {
        const iddianameResult = await runIddianameAnalysis(String(iddianameDoc.extracted_text));
        iddianameJson = iddianameResult.summaryJson;
      } catch (e) {
        console.error('İddianame ön analizi başarısız, rapora iddianamesiz devam ediliyor:', e);
      }
    }

    // Tüm belgeleri modele gönderiyoruz; ~15000 karaktere kırpılıyor, o yüzden belge
    // sayısına göre kabaca dengeli bir pay ayırıyoruz.
    const perDocLimit = Math.max(1000, Math.floor(15000 / withText.length));
    const combinedText = withText
      .map((d) => `--- ${d.filename} ---\n${String(d.extracted_text).slice(0, perDocLimit)}`)
      .join('\n\n');

    const legislationMatches = await findRelevantLegislation(combinedText);

    const analysisInput = formatLegislationBlock(legislationMatches) + (iddianameJson
      ? `İDDİANAME ÖN ANALİZİ (rapora bunu öncelikli bağlam olarak yansıt):\n${JSON.stringify(iddianameJson)}\n\n---\n\nDOSYADAKİ TÜM BELGELER:\n${combinedText}`
      : combinedText);

    const { summaryJson, aiModel } = await runCaseNarrativeAnalysis(analysisInput);

    const { data: analysisRecord, error: analysisError } = await supabase
      .from('analyses')
      .insert([{ case_id: caseId, document_id: null, summary_json: { ...summaryJson, kullanilan_mevzuat: toTraceableLegislation(legislationMatches) }, model_used: aiModel }])
      .select()
      .single();
    if (analysisError) throw analysisError;

    res.json({ analysis: analysisRecord });
  } catch (error: any) {
    console.error('Summarize Case Error:', error);
    res.status(500).json({ error: error.message || 'Internal Server Error' });
  }
};

// Çelişki Avcısı: İfade ve sorgu evraklarını alıp analiz eder.
export const analyzeStatements = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { caseId } = req.params;
    if (!caseId) {
      return res.status(400).json({ error: 'Geçersiz caseId' });
    }

    const { data: docs, error: docsError } = await supabase
      .from('documents')
      .select('filename, extracted_text')
      .eq('case_id', caseId)
      .order('uploaded_at', { ascending: true });
    if (docsError) throw docsError;

    // Sadece ifade, sorgu, beyan, tutanak, duruşma içeren belgeleri filtrele.
    // "tutanak" tek başına çok geniş — "Tebligat Tutanağı" gibi ifade/beyan
    // İÇERMEYEN evrakları da yakalıyordu, çelişki analizine gürültü katıyordu.
    const keywords = ['ifade', 'sorgu', 'beyan', 'tutanak', 'duruşma'];
    const excludeKeywords = ['tebligat', 'tebliğ'];
    const statementDocs = (docs || []).filter((d) => {
      if (!d.extracted_text || !String(d.extracted_text).trim()) return false;
      const fn = normalizeTr(d.filename);
      if (excludeKeywords.some(kw => fn.includes(kw))) return false;
      return keywords.some(kw => fn.includes(kw));
    });

    if (statementDocs.length === 0) {
      return res.status(400).json({ error: 'Bu dosyada ifade/beyan evrakı bulunamadı.' });
    }

    const perDocLimit = Math.max(1000, Math.floor(15000 / statementDocs.length));
    const combinedText = statementDocs
      .map((d) => `--- ${d.filename} ---\n${String(d.extracted_text).slice(0, perDocLimit)}`)
      .join('\n\n');

    const legislationMatches = await findRelevantLegislation(combinedText);
    const analysisInput = formatLegislationBlock(legislationMatches) + `Aşağıdaki belgeler sadece ifade ve sorgu evraklarıdır:\n\n${combinedText}`;

    const { summaryJson, aiModel } = await runStatementAnalysis(analysisInput);

    // Çelişki analizi sonucunu 'analyses' tablosuna kaydet
    const { data: analysisRecord, error: analysisError } = await supabase
      .from('analyses')
      .insert([{ case_id: caseId, document_id: null, summary_json: { statementAnalysis: summaryJson, kullanilan_mevzuat: toTraceableLegislation(legislationMatches) }, model_used: aiModel }])
      .select()
      .single();
    if (analysisError) throw analysisError;

    res.json({ analysis: analysisRecord });
  } catch (error: any) {
    console.error('Analyze Statements Error:', error);
    res.status(500).json({ error: error.message || 'Internal Server Error' });
  }
};

export const analyzeDeficiencies = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { caseId } = req.params;
    if (!caseId) {
      return res.status(400).json({ error: 'Geçersiz caseId' });
    }

    const { data: docs, error: docsError } = await supabase
      .from('documents')
      .select('filename, extracted_text')
      .eq('case_id', caseId)
      .order('uploaded_at', { ascending: true });
    if (docsError) throw docsError;

    // Çöp/makbuz niteliğindeki teknik zarf belgeleri hariç metni olan tüm evrakları dahil et
    const trashKeywords = ['makbuz', 'pul', 'zarf', 'masraf', 'havale', 'barkod', 'alındı', 'görüldü', 'ilan'];
    const targetDocs = (docs || []).filter((d) => {
      if (!d.extracted_text || !String(d.extracted_text).trim()) return false;
      const fn = normalizeTr(d.filename);
      return !trashKeywords.some((kw) => fn.includes(kw));
    });

    if (targetDocs.length === 0) {
      return res.status(400).json({ error: 'Bu dosyada analiz edilecek uygun evrak bulunamadı.' });
    }

    const perDocLimit = Math.max(1000, Math.floor(15000 / targetDocs.length));
    const combinedText = targetDocs
      .map((d) => `--- ${d.filename} ---\n${String(d.extracted_text).slice(0, perDocLimit)}`)
      .join('\n\n');

    const analysisInput = `Aşağıdaki belgeler dava dosyasına aittir:\n\n${combinedText}`;

    const { summaryJson, aiModel } = await runDeficiencyAnalysis(analysisInput);

    // Eksiklik analizi sonucunu 'analyses' tablosuna kaydet
    const { data: analysisRecord, error: analysisError } = await supabase
      .from('analyses')
      .insert([{ case_id: caseId, document_id: null, summary_json: { deficiencyAnalysis: summaryJson }, model_used: aiModel }])
      .select()
      .single();
    if (analysisError) throw analysisError;

    res.json({ analysis: analysisRecord });
  } catch (error: any) {
    console.error('Analyze Deficiencies Error:', error);
    res.status(500).json({ error: error.message || 'Internal Server Error' });
  }
};

export const analyzeStrategy = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { caseId } = req.params;
    const { clientName, client_name, clientRole, client_role } = req.body || {};
    const nameToUse = clientName || client_name;
    const roleToUse = clientRole || client_role;
    
    if (!caseId) {
      return res.status(400).json({ error: 'Geçersiz caseId' });
    }
    
    if (!nameToUse) {
      return res.status(400).json({ error: 'clientName (Müvekkil Adı) zorunludur' });
    }

    const { data: docs, error: docsError } = await supabase
      .from('documents')
      .select('filename, extracted_text')
      .eq('case_id', caseId)
      .order('uploaded_at', { ascending: true });
    if (docsError) throw docsError;

    // Gereksiz makbuz, pul vb. hariç tüm evrakları strateji için kullan
    const trashKeywords = ['tebligat', 'makbuz', 'pul', 'zarf', 'masraf', 'havale', 'barkod', 'alındı', 'görüldü', 'ilan', 'talimat', 'nüfus', 'sicil', 'sabıka'];
    const targetDocs = (docs || []).filter(d => {
      if (!d.extracted_text || !String(d.extracted_text).trim()) return false;
      const fn = normalizeTr(d.filename);
      return !trashKeywords.some(kw => fn.includes(kw));
    });

    if (targetDocs.length === 0) {
      return res.status(400).json({ error: 'Bu dosyada strateji analizi yapılabilecek evrak bulunamadı.' });
    }

    const perDocLimit = Math.max(1000, Math.floor(25000 / targetDocs.length)); // Strateji için context biraz daha geniş (25k)
    const combinedText = targetDocs
      .map((d) => `--- ${d.filename} ---\n${String(d.extracted_text).slice(0, perDocLimit)}`)
      .join('\n\n');

    const analysisInput = `Aşağıdaki belgeler dava dosyasına aittir:\n\n${combinedText}`;

    const { summaryJson, aiModel } = await runStrategyAnalysis(analysisInput, nameToUse, roleToUse);

    // Strateji analizi sonucunu 'analyses' tablosuna kaydet
    const { data: analysisRecord, error: analysisError } = await supabase
      .from('analyses')
      .insert([{ case_id: caseId, document_id: null, summary_json: { strategyAnalysis: summaryJson, clientName: nameToUse, clientRole: roleToUse }, model_used: aiModel }])
      .select()
      .single();
    if (analysisError) throw analysisError;

    res.json({ analysis: analysisRecord });
  } catch (error: any) {
    console.error('Analyze Strategy Error:', error);
    res.status(500).json({ error: error.message || 'Internal Server Error' });
  }
};

export const analyzeMediation = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { caseId } = req.params;
    const { clientName, client_name } = req.body || {};
    const nameToUse = clientName || client_name;
    
    if (!caseId) {
      return res.status(400).json({ error: 'Geçersiz caseId' });
    }
    
    if (!nameToUse) {
      return res.status(400).json({ error: 'clientName (Müvekkil Adı) zorunludur' });
    }

    const { data: docs, error: docsError } = await supabase
      .from('documents')
      .select('filename, extracted_text')
      .eq('case_id', caseId)
      .order('uploaded_at', { ascending: true });
    if (docsError) throw docsError;

    const trashKeywords = ['tebligat', 'makbuz', 'pul', 'zarf', 'masraf', 'havale', 'barkod', 'alındı', 'görüldü', 'ilan', 'talimat', 'nüfus', 'sicil', 'sabıka'];
    const targetDocs = (docs || []).filter(d => {
      if (!d.extracted_text || !String(d.extracted_text).trim()) return false;
      const fn = (d.filename || '').toLowerCase().replace(/ı/g, 'i').replace(/ğ/g, 'g').replace(/ü/g, 'u').replace(/ş/g, 's').replace(/ö/g, 'o').replace(/ç/g, 'c');
      return !trashKeywords.some(kw => fn.includes(kw));
    });

    if (targetDocs.length === 0) {
      return res.status(400).json({ error: 'Bu dosyada arabuluculuk analizi yapılabilecek evrak bulunamadı.' });
    }

    const perDocLimit = Math.max(1000, Math.floor(25000 / targetDocs.length));
    const combinedText = targetDocs
      .map((d) => `--- ${d.filename} ---\n${String(d.extracted_text).slice(0, perDocLimit)}`)
      .join('\n\n');

    const analysisInput = `Aşağıdaki belgeler dava dosyasına aittir:\n\n${combinedText}`;

    const { summaryJson, aiModel } = await runMediationAnalysis(analysisInput, nameToUse);

    const { data: analysisRecord, error: analysisError } = await supabase
      .from('analyses')
      .insert([{ case_id: caseId, document_id: null, summary_json: { mediationAnalysis: summaryJson, clientName: nameToUse }, analysis_type: 'mediation', model_used: aiModel }])
      .select()
      .single();
    if (analysisError) throw analysisError;

    res.json({ analysis: analysisRecord });
  } catch (error: any) {
    console.error('Analyze Mediation Error:', error);
    res.status(500).json({ error: error.message || 'Internal Server Error' });
  }
};

// UYAP Evrak İndirici eklentisinin "Taraf Bilgileri" sekmesinden yakaladığı
// davacı/davalı/sanık + vekil bilgisini kaydeder. AI'nin OCR metninden tahmin
// ettiği "Taraflar" alanından çok daha güvenilir — doğrudan UYAP'ın yapılandırılmış
// verisi. case_title ile eşleştirme registerLocalDocument ile aynı mantık.
export const updateCaseParties = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const userId = req.user?.id;
    const { case_title, parties } = req.body || {};

    if (!case_title || !Array.isArray(parties) || parties.length === 0) {
      return res.status(400).json({ error: 'case_title ve parties zorunludur.' });
    }

    const caseId = await findOrCreateCaseByTitle(userId as string, case_title);

    const { data, error } = await supabase
      .from('cases')
      .update({ parties })
      .eq('id', caseId)
      .select('id, title, parties')
      .single();
    if (error) throw error;

    res.json({ case: data });
  } catch (error: any) {
    console.error('Update Case Parties Error:', error);
    res.status(500).json({ error: error.message || 'Internal Server Error' });
  }
};

export const deleteCase = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { caseId } = req.params;
    if (!caseId) {
      return res.status(400).json({ error: 'Geçersiz caseId' });
    }
    // requireAuth zaten bu caseId'nin isteği yapan kullanıcıya ait olduğunu doğruladı.
    // documents/analyses/chat_messages tabloları case_id üzerinden ON DELETE CASCADE
    // ile tanımlı (bkz. sql/1.sql), yani cases satırını silmek hepsini birlikte siliyor.
    const { error } = await supabase.from('cases').delete().eq('id', caseId);
    if (error) throw error;
    res.json({ ok: true });
  } catch (error: any) {
    console.error('Delete Case Error:', error);
    res.status(500).json({ error: error.message || 'Internal Server Error' });
  }
};

export const analyzeDigitalIntern = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { caseId } = req.params;
    const { question, query } = req.body || {};
    const questionToUse = question || query;

    if (!caseId) {
      return res.status(400).json({ error: 'Geçersiz caseId' });
    }

    if (!questionToUse || !String(questionToUse).trim()) {
      return res.status(400).json({ error: 'Soru (question) girmelisiniz.' });
    }

    const { data: docs, error: docsError } = await supabase
      .from('documents')
      .select('filename, extracted_text')
      .eq('case_id', caseId)
      .order('uploaded_at', { ascending: true });
    if (docsError) throw docsError;

    const targetDocs = (docs || []).filter(d => d.extracted_text && String(d.extracted_text).trim());

    if (targetDocs.length === 0) {
      return res.status(400).json({ error: 'Bu dosyada arama yapılabilecek evrak bulunamadı.' });
    }

    const perDocLimit = Math.max(1000, Math.floor(30000 / targetDocs.length));
    const combinedText = targetDocs
      .map((d) => `--- ${d.filename} ---\n${String(d.extracted_text).slice(0, perDocLimit)}`)
      .join('\n\n');

    const analysisInput = `Aşağıdaki belgeler dava dosyasına aittir:\n\n${combinedText}`;

    const { summaryJson, aiModel } = await runDigitalInternQa(analysisInput, questionToUse);
    const userId = req.user?.id;

    // Dijital Stajyer sonucunu hem 'analyses' hem de 'chat_messages' tablosuna kaydet
    await supabase
      .from('analyses')
      .insert([{ case_id: caseId, document_id: null, summary_json: { digitalInternResult: summaryJson, question: questionToUse }, model_used: aiModel }]);

    if (userId) {
      await supabase.from('chat_messages').insert([
        {
          case_id: caseId,
          user_id: userId,
          role: 'assistant',
          content: JSON.stringify(summaryJson),
          chat_mode: 'intern'
        }
      ]);
    }

    res.json({ result: summaryJson, modelUsed: aiModel });
  } catch (error: any) {
    console.error('Digital Intern Error:', error);
    res.status(500).json({ error: error.message || 'Internal Server Error' });
  }
};
