'use client';
import Link from 'next/link';
import {useEffect,useRef,useState} from 'react';
import {ArrowUpLeft,RotateCcw,Send,X,Headphones,Ticket,RefreshCw} from 'lucide-react';
import {AssistantMark} from './assistant-mark';
import {Sheet,SheetContent,SheetTitle,SheetDescription,SheetClose} from './ui/sheet';
import {chatHistory,obviousChatSecret,requestAssistant,type AssistantConfig,type ChatTurn} from '@/lib/assistant-chat';

export function PlanckAssistant({request,onTicket}:{request:{id:number;prompt:string}|null;onTicket:()=>void}){
 const [open,setOpen]=useState(false),[input,setInput]=useState(''),[turns,setTurns]=useState<ChatTurn[]>([]);
 const [pending,setPending]=useState<number|null>(null),[config,setConfig]=useState<AssistantConfig|null>(null),[configError,setConfigError]=useState(false),[configAttempt,setConfigAttempt]=useState(0);
 const [privacyWarning,setPrivacyWarning]=useState(false);
 const [handledRequest,setHandledRequest]=useState<typeof request>(null);
 const busy=useRef(false),epoch=useRef(0),sequence=useRef(0),active=useRef<AbortController|null>(null);
 const thread=useRef<HTMLDivElement>(null),composer=useRef<HTMLTextAreaElement>(null);
 const inputLength=Array.from(input).length;
 if(request&&request!==handledRequest){setHandledRequest(request);setOpen(true);if(request.prompt)setInput(request.prompt)}
 useEffect(()=>()=>{epoch.current++;active.current?.abort()},[]);
 useEffect(()=>{
  if(!open||config)return;
  const controller=new AbortController();let alive=true;
  const timer=setTimeout(()=>controller.abort(),10000);
  void fetch('/api/chat/config',{credentials:'omit',cache:'no-store',signal:controller.signal}).then(async response=>{
   if(!response.ok)throw new Error();const data=await response.json() as AssistantConfig;
   if(!data||typeof data.title!=='string'||typeof data.greeting!=='string'||typeof data.notice!=='string'||!Array.isArray(data.suggestions)||data.suggestions.some(s=>typeof s!=='string'))throw new Error();
   if(alive)setConfig(data);
  }).catch(()=>{if(alive)setConfigError(true)}).finally(()=>clearTimeout(timer));
  return()=>{alive=false;clearTimeout(timer);controller.abort()};
 },[open,config,configAttempt]);
 useEffect(()=>{if(open&&thread.current)thread.current.scrollTop=thread.current.scrollHeight},[turns,pending,open]);
 async function send(raw:string,retryId?:number){
  const message=raw.trim();if(!message||Array.from(message).length>1500||busy.current||!config)return;
  if(obviousChatSecret(message)){setInput('');setPrivacyWarning(true);return}setPrivacyWarning(false);
  const id=retryId??++sequence.current,currentEpoch=epoch.current;
  const history=chatHistory(turns,retryId);
  busy.current=true;setPending(id);setInput('');
  setTurns(previous=>retryId===undefined?[...previous,{id,message}].slice(-30):previous.map(t=>t.id===id?{id,message}:t));
  const controller=new AbortController();active.current=controller;
  const timer=setTimeout(()=>controller.abort(),70000);
  try{
   const reply=await requestAssistant(message,history,controller.signal);
   if(epoch.current===currentEpoch)setTurns(previous=>previous.map(t=>t.id===id?{id,message,reply}:t));
  }catch(error){
   if(epoch.current===currentEpoch){const safeError=error instanceof Error&&/^(پاسخ|تعداد)/.test(error.message);const reason=controller.signal.aborted?'دریافت پاسخ طول کشید. می‌توانید دوباره تلاش کنید.':safeError?error.message:'اتصال برقرار نشد. دوباره تلاش کنید.';
    setTurns(previous=>previous.map(t=>t.id===id?{id,message,error:reason}:t));}
  }finally{
   clearTimeout(timer);if(epoch.current===currentEpoch){busy.current=false;active.current=null;setPending(null);composer.current?.focus({preventScroll:true})}
  }
 }
 function reset(){epoch.current++;active.current?.abort();active.current=null;busy.current=false;setPending(null);setTurns([]);setInput('');setPrivacyWarning(false);composer.current?.focus({preventScroll:true})}
 const last=turns.at(-1),suggestions=turns.length?(last?.reply?.suggestions||[]):config?.suggestions||[];
 return <><button className="assistant-trigger assistant-brand-trigger" onClick={()=>setOpen(true)} aria-label="باز کردن دستیار پلانک" aria-haspopup="dialog" aria-expanded={open}><AssistantMark/></button>
 <Sheet open={open} onOpenChange={setOpen}><SheetContent side="left" className="assistant-panel planck-chat" dir="rtl" lang="fa" showCloseButton={false}>
  <header className="pc-header"><div className="pc-identity"><AssistantMark/><div><SheetTitle>{config?.title||'دستیار پلانک'}</SheetTitle><SheetDescription>راهنمای خدمات و زیرساخت پلانک</SheetDescription></div></div><div className="pc-tools"><button type="button" onClick={reset} aria-label="گفتگوی تازه" title="گفتگوی تازه"><RotateCcw size={18}/></button><SheetClose aria-label="بستن دستیار"><X size={20}/></SheetClose></div></header>
  <div className="pc-scope"><span/><p>راهنمای عمومی؛ بدون دسترسی به اطلاعات حساب شما</p></div>
  <div className="pc-thread" ref={thread} role="log" aria-label="گفتگو با دستیار پلانک" aria-live="polite" aria-relevant="additions text">
   {!turns.length&&<div className="pc-welcome"><span className="pc-welcome-icon" aria-hidden="true"><AssistantMark/></span><span className="pc-eyebrow">PLANCK ASSISTANT</span><h3>از کجا شروع کنیم؟</h3>{config?<p>{config.greeting}</p>:!configError?<p><output>در حال اتصال به راهنمای پلانک…</output></p>:null}</div>}
   {configError&&!config&&<div className="pc-error" role="alert"><p>راهنمای گفتگو دریافت نشد. لطفاً دوباره تلاش کنید.</p><button onClick={()=>{setConfigError(false);setConfigAttempt(n=>n+1)}}><RefreshCw size={15}/>تلاش مجدد برای اتصال</button></div>}
   {turns.map((turn,index)=><div className="pc-turn" key={turn.id}><article className="pc-message pc-user"><span className="pc-message-label">شما</span><p dir="auto">{turn.message}</p></article>
    {turn.reply&&<article className="pc-message pc-answer"><span className="pc-message-label"><AssistantMark/>دستیار پلانک</span><p dir="auto">{turn.reply.answer}</p></article>}
    {turn.reply?.mode==='fallback'&&<div className="pc-error"><p><output>پاسخ مدل موقتاً دریافت نشد. می‌توانید برای دریافت پاسخ کامل‌تر دوباره تلاش کنید.</output></p>{index===turns.length-1&&<button disabled={pending!==null} onClick={()=>void send(turn.message,turn.id)}><RefreshCw size={15}/>تلاش مجدد</button>}</div>}
    {turn.error&&<div className="pc-error" role="alert"><p>{turn.error}</p>{index===turns.length-1&&<button disabled={pending!==null} onClick={()=>void send(turn.message,turn.id)}><RefreshCw size={15}/>تلاش مجدد</button>}</div>}
   </div>)}
   {pending!==null&&<output className="pc-pending"><span className="pc-dots" aria-hidden="true"><i/><i/><i/></span><span>در حال آماده‌سازی پاسخ…</span></output>}
   {pending===null&&suggestions.length>0&&<div className={`pc-suggestions ${turns.length?'pc-followups':''}`} aria-label={turns.length?'پرسش‌های مرتبط':'پرسش‌های پیشنهادی'}>{turns.length>0&&<p className="pc-followup-heading">پرسش‌های مرتبط</p>}{suggestions.slice(0,4).map(text=><button key={text} type="button" onClick={()=>void send(text)}>{text}<ArrowUpLeft size={16}/></button>)}</div>}
  </div>
  <footer className="pc-footer">{privacyWarning&&<p className="pc-error" role="alert">این پیام ارسال نشد. رمز، کد ورود، کلید خصوصی و عبارت بازیابی را نفرستید؛ سؤال را بدون اطلاعات محرمانه بنویسید.</p>}<form className="pc-composer" aria-busy={pending!==null} onSubmit={event=>{event.preventDefault();void send(input)}}><label className="sr-only" htmlFor="planck-assistant-message">پیام شما</label><textarea id="planck-assistant-message" ref={composer} placeholder="سؤال خود را بنویسید…" rows={2} value={input} dir="auto" onChange={event=>setInput(event.target.value)} aria-describedby="planck-assistant-limit" onKeyDown={event=>{if(event.key==='Enter'&&!event.shiftKey&&!event.nativeEvent.isComposing){event.preventDefault();void send(input)}}}/><button type="submit" disabled={pending!==null||!config||!input.trim()||inputLength>1500} aria-label="ارسال پیام"><Send size={19}/></button></form>
   <div className="pc-composer-meta"><span id="planck-assistant-limit" className={inputLength>1500?'pc-limit-error':''}>{new Intl.NumberFormat('fa').format(inputLength)} / ۱٬۵۰۰</span><span>گفتگو فقط در حافظهٔ این صفحه نگهداری می‌شود.</span></div>
   <p className="pc-notice">{config?.notice||'رمز، کد ورود و عبارت بازیابی را در گفتگو ارسال نکنید.'}</p>
   <div className="pc-support-links"><Link href="/#planck-support" onClick={()=>setOpen(false)}><Headphones size={16}/>پشتیبانی</Link><button type="button" onClick={()=>{setOpen(false);requestAnimationFrame(onTicket)}}><Ticket size={16}/>ارسال تیکت<ArrowUpLeft size={14}/></button></div>
  </footer>
 </SheetContent></Sheet></>;
}
