(() => {
  'use strict';
  const $ = id => document.getElementById(id);
  const escape = value => String(value ?? '').replace(/[&<>"]/g, c => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c]));
  const number = value => value == null ? '-' : Number(value).toLocaleString('zh-CN',{maximumFractionDigits:6});
  const state = {mode:'metadata', busy:false, result:null, resultMode:'', metadata:null};
  const labels = {metadata:'读取栅格信息',points:'提取点高程',profile:'提取纵断面'};
  const path = () => $('demPath').value.trim();
  async function call(method,...args) {
    const api=window.pywebview?.api;
    if(!api?.[method]) throw Error('请在桌面软件中使用 DEM 功能。');
    const data=await api[method](...args);
    if(data?.cancelled) return data;
    if(!data?.ok && data?.ok!==undefined) throw Error(data.message||'DEM 分析失败。');
    return data;
  }
  async function runtime() {
    try { const data=await call('get_dem_runtime_status');$('runtimeStatus').textContent=data.message||'DEM 组件可用';$('installRuntimeBtn').hidden=!!data.installed; }
    catch(error) { $('runtimeStatus').textContent=error.message; }
  }
  async function busy(action) {
    if(state.busy) return;
    state.busy=true;$('analysisError').hidden=true;$('runProgress').hidden=false;$('runStatus').textContent='正在处理...';
    const controls=[...document.querySelectorAll('#dem-form button,#dem-form input,#dem-form textarea')];
    controls.forEach(node=>node.disabled=true);
    try { await action();$('runStatus').textContent='处理完成'; }
    catch(error) { $('analysisError').textContent=error.message;$('analysisError').hidden=false;$('runStatus').textContent='运行失败'; }
    finally { state.busy=false;$('runProgress').hidden=true;controls.forEach(node=>node.disabled=false); }
  }
  function setMode(mode) {
    state.mode=mode;
    document.querySelectorAll('[data-dem-mode]').forEach(node=>node.setAttribute('aria-pressed',String(node.dataset.demMode===mode)));
    document.querySelectorAll('[data-dem-panel]').forEach(node=>node.hidden=node.dataset.demPanel!==mode);
    $('runBtn').querySelector('span').textContent=labels[mode];
  }
  function clearResults() {
    state.result=null;state.resultMode='';$('exportBtn').disabled=true;
    $('pointResult').innerHTML='';$('profileResult').innerHTML='';$('fileMessage').textContent='尚无分析成果';
  }
  function metadata(data) {
    state.metadata=data;
    const items=[['数据格式',data.format],['栅格行列',`${data.width} × ${data.height}`],['坐标系',data.crs||'未定义'],['分辨率',`${number(data.resolution.x)} × ${number(data.resolution.y)}`],['覆盖范围',`${number(data.bounds.left)}, ${number(data.bounds.bottom)} 至 ${number(data.bounds.right)}, ${number(data.bounds.top)}`],['NoData',data.nodata??'未设置'],['抽样最低高程',number(data.sample_min)],['抽样最高高程',number(data.sample_max)]];
    $('metadata').innerHTML=items.map(([label,value])=>`<div class="metric"><small>${escape(label)}</small><b>${escape(value)}</b></div>`).join('');$('metadata').hidden=false;$('metadataDetails').hidden=false;$('metadataDetails').open=true;
  }
  const sampleRows = () => state.resultMode==='profile' ? state.result?.profile||[] : state.result?.points||[];
  function table(rows,profile) {
    const shown=$('showNoData').checked?rows:rows.filter(row=>row.elevation_m!=null);
    return `<table><thead><tr><th>点号</th>${profile?'<th>距离（输入坐标单位）</th>':''}<th>X</th><th>Y</th><th>高程</th></tr></thead><tbody>${shown.map(p=>`<tr><td>${p.index??rows.indexOf(p)+1}</td>${profile?`<td>${number(p.distance)}</td>`:''}<td>${number(p.x)}</td><td>${number(p.y)}</td><td>${p.elevation_m==null?'NoData / 范围外':number(p.elevation_m)}</td></tr>`).join('')}</tbody></table>`;
  }
  function profileChart(rows) {
    const valid=rows.filter(p=>p.elevation_m!=null);
    if(valid.length<2) return '';
    const lo=Math.min(...valid.map(p=>p.elevation_m)),hi=Math.max(...valid.map(p=>p.elevation_m));
    const pad=Math.max((hi-lo)*.12,1),min=lo-pad,max=hi+pad,dist=rows.at(-1).distance||1;
    const segments=[];let current=[];
    for(const p of rows){if(p.elevation_m==null){if(current.length)segments.push(current);current=[];}else current.push(`${65+p.distance/dist*780},${245-(p.elevation_m-min)/(max-min)*205}`);}
    if(current.length)segments.push(current);
    return `<svg class="profile-chart" viewBox="0 0 900 300" role="img" aria-label="DEM 测线高程剖面"><path d="M65 30V245H855" stroke="#9fafb3" fill="none"/><text x="12" y="45">${number(max)}</text><text x="12" y="245">${number(min)}</text><text x="65" y="275">0</text><text x="840" y="275" text-anchor="end">${number(dist)}</text>${segments.map(points=>`<polyline points="${points.join(' ')}" fill="none" stroke="#286b93" stroke-width="2.5"/>`).join('')}${valid.map(p=>`<circle cx="${65+p.distance/dist*780}" cy="${245-(p.elevation_m-min)/(max-min)*205}" r="3" fill="#286b93"/>`).join('')}</svg>`;
  }
  function renderResult() {
    const data=state.result;if(!data) return;
    $('pointResult').innerHTML='';$('profileResult').innerHTML='';
    if(state.resultMode==='metadata') { metadata(data);$('fileMessage').textContent=data.message||'栅格核验完成'; }
    else {
      $('metadataDetails').open=false;
      const rows=sampleRows(),valid=rows.filter(p=>p.elevation_m!=null).length;
      $('fileMessage').textContent=`${state.resultMode==='profile'?'测线纵断面':'点高程采样'}：${rows.length} 个点，有效 ${valid} 个，NoData / 范围外 ${rows.length-valid} 个。`;
      $(state.resultMode==='profile'?'profileResult':'pointResult').innerHTML=(state.resultMode==='profile'?profileChart(rows):'')+table(rows,state.resultMode==='profile');
    }
    $('exportBtn').disabled=!sampleRows().length;
  }
  function numeric(id) { const value=$(id).value.trim();if(!value||!Number.isFinite(Number(value)))throw Error('请填写有效的起终点坐标。');return Number(value); }
  function crs(id) {
    const value=$(id).value.trim();
    if(value && /\.(asc|grd)$/i.test(path())) throw Error('ASCII 栅格未提供可转换的坐标系，请使用栅格原始坐标并留空输入坐标系。');
    return value;
  }
  async function run() {
    clearResults();
    if(!path()) throw Error('请先选择 DEM 文件。');
    let data;
    if(state.mode==='metadata') data=await call('read_dem_metadata',path());
    else if(state.mode==='points') {
      const lines=$('pointText').value.trim().split(/\r?\n/).filter(line=>line.trim());
      if(!lines.length||lines.length>1000) throw Error('采样点须为 1 至 1000 组坐标。');
      const points=lines.map((line,i)=>{const values=line.trim().split(/[，,\s]+/);if(values.length!==2||values.some(v=>!Number.isFinite(Number(v))))throw Error(`第 ${i+1} 行须为两个有效坐标 X, Y。`);return{x:Number(values[0]),y:Number(values[1])};});
      data=await call('sample_dem_points',path(),points,crs('pointCrs'));
    } else {
      const coords=['startX','startY','endX','endY'].map(numeric),count=Number($('sampleCount').value);
      if(!Number.isInteger(count)||count<2||count>1000) throw Error('采样点数须为 2 至 1000 的整数。');
      if(coords[0]===coords[2]&&coords[1]===coords[3])throw Error('测线起点与终点不能重合。');
      data=await call('sample_dem_profile',path(),...coords,count,crs('profileCrs'));
    }
    state.result=data;state.resultMode=state.mode;renderResult();
  }
  document.querySelectorAll('[data-dem-mode]').forEach(node=>node.onclick=()=>setMode(node.dataset.demMode));
  document.querySelectorAll('[data-count-step]').forEach(node=>node.onclick=()=>{$('sampleCount').value=Math.min(1000,Math.max(2,(Number($('sampleCount').value)||2)+Number(node.dataset.countStep)));clearResults();});
  $('dem-form').onsubmit=event=>{event.preventDefault();busy(run);};
  $('dem-form').addEventListener('input',()=>{clearResults();$('runStatus').textContent='参数已修改，待运行';});
  $('chooseBtn').onclick=()=>busy(async()=>{const data=await call('select_dem_file');if(data.cancelled)return;$('demPath').value=data.path;clearResults();$('metadata').hidden=true;$('metadataDetails').hidden=true;state.metadata=null;state.result=await call('read_dem_metadata',path());state.resultMode='metadata';renderResult();});
  $('installRuntimeBtn').onclick=()=>busy(async()=>{await call('install_dem_runtime');await runtime();});
  $('showNoData').onchange=renderResult;
  $('exportBtn').onclick=()=>{
    const profile=state.resultMode==='profile',rows=sampleRows();if(!rows.length)return;
    const lines=[['点号',...(profile?['距离（输入坐标单位）']:[]),'X','Y','高程'],...rows.map((p,i)=>[p.index??i+1,...(profile?[p.distance]:[]),p.x,p.y,p.elevation_m??''])];
    const blob=new Blob(['\ufeff'+lines.map(row=>row.join(',')).join('\r\n')],{type:'text/csv;charset=utf-8'}),url=URL.createObjectURL(blob),a=document.createElement('a');a.href=url;a.download=`dem_${state.resultMode}.csv`;a.click();setTimeout(()=>URL.revokeObjectURL(url),1000);
  };
  window.lucide?.createIcons();runtime();
})();
