'use client';
import {useEffect,useRef,useState} from 'react';
import {ImagePlus,Ruler} from 'lucide-react';
import {toast} from 'sonner';
import {Dialog,DialogContent,DialogHeader,DialogTitle,DialogDescription} from './ui/dialog';
import {backgroundSchema,backgroundUrl,calibratedSize,type Background} from '@/lib/background';
import {uploadBackground} from '@/lib/background-client';
import type {PDFDocumentProxy} from 'pdfjs-dist';
type P={x:number;y:number};
export function BackgroundEditor({background,onApply,requireAccess,userId}:{background?:Background;onApply:(b:Background|undefined)=>void;requireAccess:()=>Promise<boolean>;userId:string}){const [open,setOpen]=useState(false);return <><button onClick={()=>setOpen(true)} title="Háttéralaprajz és méretarány"><ImagePlus/><span>Háttéralaprajz</span></button><Dialog open={open} onOpenChange={setOpen}><DialogContent className="background-dialog"><DialogHeader><DialogTitle>Háttéralaprajz</DialogTitle><DialogDescription>Kép vagy PDF egy oldala az aktuális szint mögött. Két ponttal megadható a méretarány; a villamos terv elemei változatlanul maradnak.</DialogDescription></DialogHeader>{open&&<BackgroundForm background={background} requireAccess={requireAccess} userId={userId} onApply={b=>{onApply(b);setOpen(false)}}/>}</DialogContent></Dialog></>}
function BackgroundForm({background,onApply,requireAccess,userId}:{background?:Background;onApply:(b:Background|undefined)=>void;requireAccess:()=>Promise<boolean>;userId:string}){
 const [draft,setDraft]=useState<Background|undefined>(background),[src,setSrc]=useState(background?backgroundUrl(background.assetId):''),[blob,setBlob]=useState<Blob>(),[busy,setBusy]=useState(false),[error,setError]=useState(''),[points,setPoints]=useState<P[]>([]),[meters,setMeters]=useState(''),[pages,setPages]=useState(0),[page,setPage]=useState(1),[calibrating,setCalibrating]=useState(false);
 const input=useRef<HTMLInputElement>(null),pdf=useRef<PDFDocumentProxy|null>(null),alive=useRef(true),name=useRef('');
 useEffect(()=>{alive.current=true;return()=>{alive.current=false;void pdf.current?.loadingTask.destroy()}},[]);
 async function rendered(canvas:HTMLCanvasElement,label:string){const jpg=await new Promise<Blob>((resolve,reject)=>canvas.toBlob(b=>b?resolve(b):reject(Error('A kép nem dolgozható fel.')),'image/jpeg',.9));if(jpg.size>2_000_000)throw Error('A feldolgozott kép túl részletes. Használj kisebb képet vagy PDF-oldalt.');if(!alive.current)return;const {blobData}=await import('@/lib/background-client');setSrc(await blobData(jpg));setBlob(jpg);const factor=Math.min(800/canvas.width,560/canvas.height);setDraft({assetId:crypto.randomUUID(),name:label.slice(0,180),x:0,y:0,w:canvas.width*factor,h:canvas.height*factor,opacity:.55,visible:true,calibrated:false});setPoints([]);setMeters('');setCalibrating(true)}
 async function renderPage(number:number){if(!pdf.current)return;setBusy(true);setError('');try{const p=await pdf.current.getPage(number),base=p.getViewport({scale:1}),viewport=p.getViewport({scale:Math.min(2400/base.width,2400/base.height,3)}),canvas=document.createElement('canvas');canvas.width=Math.ceil(viewport.width);canvas.height=Math.ceil(viewport.height);await p.render({canvas,viewport,background:'#ffffff'}).promise;await rendered(canvas,name.current+' · '+number+'. oldal');setPage(number)}catch{setError('A PDF-oldal nem olvasható. Válassz másik fájlt vagy oldalt.')}finally{if(alive.current)setBusy(false)}}
 async function load(file:File){setBusy(true);setError('');try{if(!await requireAccess())return;if(file.size>20_000_000)throw Error('A fájl legfeljebb 20 MB lehet.');name.current=file.name;await pdf.current?.loadingTask.destroy();pdf.current=null;setPages(0);
  if(file.type==='application/pdf'||/\.pdf$/i.test(file.name)){const engine=await import('pdfjs-dist');engine.GlobalWorkerOptions.workerSrc=new URL(new URL('pdfjs-dist/build/pdf.worker.min.mjs',import.meta.url).pathname,window.location.origin).href;const doc=await engine.getDocument({data:await file.arrayBuffer()}).promise;if(!alive.current){await doc.loadingTask.destroy();return}pdf.current=doc;setPages(doc.numPages);await renderPage(1)}
  else{if(!['image/png','image/jpeg','image/webp'].includes(file.type))throw Error('PNG, JPG, WebP kép vagy PDF használható.');const bitmap=await createImageBitmap(file);try{const scale=Math.min(1,2400/Math.max(bitmap.width,bitmap.height)),canvas=document.createElement('canvas');canvas.width=Math.max(1,Math.round(bitmap.width*scale));canvas.height=Math.max(1,Math.round(bitmap.height*scale));const ctx=canvas.getContext('2d')!;ctx.fillStyle='#fff';ctx.fillRect(0,0,canvas.width,canvas.height);ctx.drawImage(bitmap,0,0,canvas.width,canvas.height);await rendered(canvas,file.name)}finally{bitmap.close()}}
 }catch(e){setError(e instanceof Error?e.message:'A fájl nem olvasható.')}finally{if(alive.current)setBusy(false)}}
 function calibrate(){if(!draft||points.length!==2)return;try{const size=calibratedSize(points[0],points[1],Number(meters.replace(',','.')),draft.h/draft.w);const next={...draft,...size,calibrated:true};const parsed=backgroundSchema.parse(next);setDraft(parsed);setCalibrating(false);setPoints([]);setError('');toast.success('Méretarány beállítva. Az Alkalmazás gombbal véglegesítheted.')}catch(e){setError(e instanceof Error&&e.name!=='ZodError'?e.message:'A kép túlnyúlna az 50 × 50 méteres rajzterületen. Állítsd az X/Y helyzetét közelebb a nullához.')}}
 async function apply(){if(!draft)return;setBusy(true);setError('');try{if(!draft.calibrated)throw Error('Előbb állítsd be a méretarányt két ponttal.');let next=backgroundSchema.parse(draft);if(blob){if(!await requireAccess())return;next={...next,assetId:await uploadBackground(blob,userId)}}if(alive.current)onApply(next)}catch(e){setError(e instanceof Error&&e.name!=='ZodError'?e.message:'Ellenőrizd a háttér helyzetét és méretét.')}finally{if(alive.current)setBusy(false)}}
 return <div className="background-form"><input ref={input} type="file" hidden accept="image/png,image/jpeg,image/webp,application/pdf" onChange={e=>{const f=e.target.files?.[0];e.target.value='';if(f)void load(f)}}/><div className="background-actions"><button disabled={busy} onClick={async()=>{if(await requireAccess())input.current?.click()}}><ImagePlus/> {draft?'Másik fájl betöltése':'Kép / PDF betöltése'}</button>{pages>0&&<label>PDF-oldal <select aria-label="PDF-oldal" value={page} disabled={busy} onChange={e=>void renderPage(+e.target.value)}>{Array.from({length:pages},(_,i)=><option key={i} value={i+1}>{i+1} / {pages}</option>)}</select></label>}</div><p className="background-help">Importálás havi előfizetéssel · legfeljebb 20 MB. A kiválasztott PDF-oldal képként kerül a tervbe.</p>
 {draft&&<><strong>{draft.name}</strong><div className="background-preview"><svg aria-label="Háttér méretarányának kijelölése" viewBox={`0 0 1000 ${1000*draft.h/draft.w}`} style={{cursor:calibrating?'crosshair':'default'}} onPointerDown={e=>{if(!calibrating||busy)return;const svg=e.currentTarget,p=svg.createSVGPoint();p.x=e.clientX;p.y=e.clientY;const v=p.matrixTransform(svg.getScreenCTM()!.inverse()),x=v.x/1000,y=v.y/(1000*draft.h/draft.w);if(x<0||x>1||y<0||y>1)return;setPoints(old=>old.length===2?[{x,y}]:[...old,{x,y}])}}><image href={src} width="1000" height={1000*draft.h/draft.w} preserveAspectRatio="none" onError={()=>setError('A háttérkép nem tölthető be. Próbáld újra, vagy válassz másik fájlt.')}/>{points.length===2&&<line x1={points[0].x*1000} y1={points[0].y*1000*draft.h/draft.w} x2={points[1].x*1000} y2={points[1].y*1000*draft.h/draft.w} stroke="#e11d48" strokeWidth="4"/>}{points.map((p,i)=><g key={i}><circle cx={p.x*1000} cy={p.y*1000*draft.h/draft.w} r="9" fill="#e11d48" stroke="white" strokeWidth="3"/><text x={p.x*1000+14} y={p.y*1000*draft.h/draft.w-12} fontSize="24" fill="#e11d48" stroke="white" strokeWidth="2" paintOrder="stroke">{i+1}</text></g>)}</svg></div>
 <div className="background-calibration"><button disabled={busy} onClick={()=>{setCalibrating(true);setPoints([])}}><Ruler/> {draft.calibrated?'Méretarány újramérése':'Méretarány beállítása'}</button>{calibrating&&<><p role="status">{points.length===0?'Kattints az ismert távolság kezdőpontjára.':points.length===1?'Kattints az ismert távolság végpontjára.':'Add meg a két pont közötti valós távolságot.'}</p><label>Valós távolság (m)<input aria-label="Valós távolság (m)" type="text" inputMode="decimal" value={meters} onChange={e=>setMeters(e.target.value)}/></label><button disabled={points.length!==2||busy} onClick={calibrate}>Méretarány kiszámítása</button></>}</div>
 <p>{draft.calibrated?'Méretezett háttér':'Még nincs méretezve'} · {(draft.w/40).toFixed(2)} × {(draft.h/40).toFixed(2)} m</p><div className="background-settings">{(['x','y'] as const).map(k=><label key={k}>{k.toUpperCase()} helyzet (m)<input aria-label={'Háttér '+k.toUpperCase()+' helyzete (m)'} type="number" min="0" max="50" step=".05" value={+(draft[k]/40).toFixed(3)} onChange={e=>setDraft({...draft,[k]:+e.target.value*40})}/></label>)}<label>Láthatóság: {Math.round(draft.opacity*100)}%<input aria-label="Háttér láthatósága" type="range" min="10" max="100" value={draft.opacity*100} onChange={e=>setDraft({...draft,opacity:+e.target.value/100})}/></label><label><input type="checkbox" checked={draft.visible} onChange={e=>setDraft({...draft,visible:e.target.checked})}/> Háttér megjelenítése</label></div><p className="background-help">A háttér zárolt: a rajzeszközök nem mozdítják el. A helyzet és a méretarány módosítása csak a háttérre hat.</p><div className="background-actions"><button className="primary" disabled={busy||!draft.calibrated} onClick={()=>void apply()}>Alkalmazás</button>{background&&<button disabled={busy} onClick={()=>onApply(undefined)}>Háttér eltávolítása</button>}</div></>}
 {busy&&<p role="status">Háttéralaprajz feldolgozása…</p>}{error&&<p className="background-error" role="alert">{error}</p>}</div>;
}

