import { Response } from 'express';
import { supabase } from '../lib/supabase';
import { AuthenticatedRequest } from '../middleware/auth';
import { getAiConfig } from '../lib/aiConfig';

// İlk mesajdan kısa bir başlık üretir (Claude/ChatGPT'nin yaptığı gibi). Başarısız
// olursa null döner — çağıran taraf bu durumda varsayılan başlığı korur, asıl
// sohbet cevabını etkilemez. Hem dava-dosyası-siz "Yeni Sohbet" (cases.kind='chat')
// hem de chat_threads kayıtları için ortak kullanılır.
async function generateShortTitle(firstMessage: string): Promise<string | null> {
  try {
    const { runpodUrl, aiModel } = getAiConfig();
    const response = await fetch(`${runpodUrl}/api/chat`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        model: aiModel,
        messages: [
          {
            role: 'system',
            content: 'Kullanıcının hukuki sorusunu en fazla 5 kelimelik, kısa ve açıklayıcı bir Türkçe başlığa çevir. Sadece başlığı yaz; tırnak işareti, noktalama veya başka açıklama ekleme.'
          },
          { role: 'user', content: firstMessage.slice(0, 2000) },
        ],
        think: false,
        stream: false,
      }),
    });
    if (!response.ok) return null;
    const data = await response.json();
    const raw = (data.message?.content || '').toString().trim().replace(/^["'“”]+|["'“”]+$/g, '');
    if (!raw) return null;
    return raw.slice(0, 80);
  } catch (err) {
    console.error('Generate Short Title Error:', err);
    return null;
  }
}

// AI modeline chat completion isteği atan ortak yardımcı. RunPod worker uykudaysa
// soğuk başlangıç birkaç dakika sürebilir; burada sunucu tarafında bir zaman aşımı
// dayatmıyoruz (istemci kendi AbortController'ıyla bekleme süresini yönetiyor) —
// böylece yavaş ama başarılı olacak bir yanıtı erkenden kesmiyoruz.
async function callAiChat(messages: { role: string; content: string }[]): Promise<string> {
  const { runpodUrl, aiModel } = getAiConfig();
  const response = await fetch(`${runpodUrl}/api/chat`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ model: aiModel, messages, think: false, stream: false }),
  });
  if (!response.ok) {
    throw new Error(`AI Model request failed: ${response.statusText}`);
  }
  const data = await response.json();
  return data.message?.content || 'Yanıt alınamadı.';
}

export const deleteChatHistory = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { caseId } = req.params;
    if (!caseId || caseId === 'general') {
      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ı.
    // Silme işlemi burada (backend'de, service_role ile) yapılıyor — frontend'in anon
    // client'ı chat_messages'a RLS nedeniyle yazamıyor/silemiyor olabilir.
    const { error } = await supabase.from('chat_messages').delete().eq('case_id', caseId);
    if (error) throw error;
    res.json({ ok: true });
  } catch (error: any) {
    console.error('Delete Chat History Error:', error);
    res.status(500).json({ error: error.message || 'Internal Server Error' });
  }
};

export const chatMessage = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { caseId } = req.params;
    const { content } = req.body;
    const userId = req.user?.id;

    if (!content || !caseId) {
      return res.status(400).json({ error: 'Missing caseId or content' });
    }

    // kind='case' olan gerçek dava dosyalarının başlığı UYAP'tan/kullanıcıdan geliyor —
    // bu asla otomatik yeniden adlandırılmamalı. Otomatik başlık üretimi SADECE
    // kind='chat' (Sohbet'teki "Yeni Sohbet") kayıtları için geçerli.
    const { data: caseRow } = await supabase.from('cases').select('kind').eq('id', caseId).maybeSingle();
    const caseKind = caseRow?.kind || 'case';

    const { data: userMessage, error: userMsgError } = await supabase
      .from('chat_messages')
      .insert([{ case_id: caseId, user_id: userId, role: 'user', content }])
      .select().single();
    if (userMsgError) throw userMsgError;

    // 1. Dosyaya ait belge analizlerini çek (EKSİK OLAN KISIM)
    const { data: analyses } = await supabase
      .from('analyses')
      .select('summary_json')
      .eq('case_id', caseId);

    const { data: documents } = await supabase
      .from('documents')
      .select('filename, extracted_text')
      .eq('case_id', caseId);

    // 2. Geçmiş sohbet
    const { data: pastMessages } = await supabase
      .from('chat_messages')
      .select('role, content')
      .eq('case_id', caseId)
      .order('created_at', { ascending: true })
      .limit(10);

    // 3. Belge bağlamını sistem promptuna göm
    let documentContext = '';
    if (documents && documents.length > 0) {
      documentContext = '\n\nDOSYAYA AİT BELGELER:\n' +
        documents.map(d => `--- ${d.filename} ---\n${d.extracted_text}`).join('\n\n');
    } else {
      documentContext = '\n\nBu dosyaya henüz hiçbir belge yüklenmemiştir. Genel hukuki bilgiyle cevap ver, ama bunu kullanıcıya açıkça belirt.';
    }

    if (analyses && analyses.length > 0) {
      documentContext += '\n\nÖNCEKİ ANALİZ ÖZETİ:\n' + JSON.stringify(analyses[analyses.length - 1].summary_json);
    }

    const systemPrompt = `Sen bir hukuk asistanısın. Bu dava dosyasıyla ilgili kullanıcının sorularını, aşağıda verilen belge içeriğine dayanarak cevaplıyorsun. Eğer belge yoksa veya soruyu cevaplamaya yetmiyorsa, bunu açıkça belirt, uydurma bilgi verme.${documentContext}`;

    const messages: any[] = [{ role: 'system', content: systemPrompt }];
    if (pastMessages) {
      pastMessages.forEach(m => messages.push({ role: m.role, content: m.content }));
    } else {
      messages.push({ role: 'user', content });
    }

    const aiContent = await callAiChat(messages);

    const { data: aiMessage, error: aiMsgError } = await supabase
      .from('chat_messages')
      .insert([{ case_id: caseId, user_id: userId, role: 'assistant', content: aiContent }])
      .select().single();
    if (aiMsgError) throw aiMsgError;

    // Bu dosyanın ilk mesajıysa (kullanıcının bu isteklen önce hiç mesajı yoktu) VE
    // bu gerçek bir dava dosyası değil de dosyasız bir sohbetse, ilk mesajdan kısa
    // bir başlık üretip yeniden adlandır.
    let newTitle: string | null = null;
    const isFirstMessage = !pastMessages || pastMessages.length <= 1;
    if (isFirstMessage && caseKind === 'chat') {
      newTitle = await generateShortTitle(content);
      if (newTitle) {
        const { error: titleError } = await supabase
          .from('cases')
          .update({ title: newTitle })
          .eq('id', caseId);
        if (titleError) {
          console.error('Case Title Update Error:', titleError);
          newTitle = null;
        }
      }
    }

    res.json({ message: aiMessage, newTitle });
  } catch (error: any) {
    console.error('Chat Error:', error);
    res.status(500).json({ error: error.message || 'Internal Server Error' });
  }
};

// Genel (dosyasız) Sohbet/Asistan sayfası için — chat_threads/thread_messages
// tabloları cases ile hiçbir ilişkiye sahip değil (bkz. sql/9_chat_threads.sql).
// Thread oluşturma/silme/geçmiş okuma doğrudan frontend'den Supabase ile yapılıyor
// (events/clients/drafts ile aynı desen); burada sadece AI çağrısı + mesaj kaydı var.
export const sendThreadMessage = async (req: AuthenticatedRequest, res: Response) => {
  try {
    const { threadId } = req.params;
    const { content } = req.body;
    const userId = req.user?.id;

    if (!content || !threadId) {
      return res.status(400).json({ error: 'Missing threadId or content' });
    }

    const { data: thread } = await supabase
      .from('chat_threads')
      .select('id, user_id')
      .eq('id', threadId)
      .maybeSingle();
    if (!thread || thread.user_id !== userId) {
      return res.status(403).json({ error: 'Bu sohbete erişim yetkiniz yok.' });
    }

    const { error: userMsgError } = await supabase
      .from('thread_messages')
      .insert([{ thread_id: threadId, user_id: userId, role: 'user', content }]);
    if (userMsgError) throw userMsgError;

    const { data: pastMessages } = await supabase
      .from('thread_messages')
      .select('role, content')
      .eq('thread_id', threadId)
      .order('created_at', { ascending: true })
      .limit(20);

    const generalSystemPrompt = 'Sen bir hukuk asistanısın. Belirli bir dava dosyasına bağlı olmayan genel hukuki soruları cevaplıyorsun. Emin olmadığın noktalarda bunu açıkça belirt, uydurma bilgi verme.';
    const messages: any[] = [{ role: 'system', content: generalSystemPrompt }];
    if (pastMessages && pastMessages.length > 0) {
      pastMessages.forEach(m => messages.push({ role: m.role, content: m.content }));
    } else {
      messages.push({ role: 'user', content });
    }

    const aiContent = await callAiChat(messages);

    const { data: aiMessage, error: aiMsgError } = await supabase
      .from('thread_messages')
      .insert([{ thread_id: threadId, user_id: userId, role: 'assistant', content: aiContent }])
      .select().single();
    if (aiMsgError) throw aiMsgError;

    let newTitle: string | null = null;
    const isFirstMessage = !pastMessages || pastMessages.length <= 1;
    if (isFirstMessage) {
      newTitle = await generateShortTitle(content);
      if (newTitle) {
        const { error: titleError } = await supabase
          .from('chat_threads')
          .update({ title: newTitle })
          .eq('id', threadId);
        if (titleError) {
          console.error('Thread Title Update Error:', titleError);
          newTitle = null;
        }
      }
    }

    res.json({ message: aiMessage, newTitle });
  } catch (error: any) {
    console.error('Send Thread Message Error:', error);
    res.status(500).json({ error: error.message || 'Internal Server Error' });
  }
};
