// ─────────────────────────────────────────────
// DO_DetailView_Portal.jsx  v5
// Requires: DO_Shared.jsx (IconBtn, Icon, getTheme)
// ─────────────────────────────────────────────

function PortalField({ obj, appId, table: parentTable, recordId, appData }) {

  const [rows,       setRows]       = React.useState([]);
  const [relFields,  setRelFields]  = React.useState([]);
  const [loading,    setLoading]    = React.useState(true);
  const [error,      setError]      = React.useState(null);
  const [addOpen,    setAddOpen]    = React.useState(false);
  const [addValues,  setAddValues]  = React.useState({});
  const [saving,     setSaving]     = React.useState(false);
  const [delConfirm, setDelConfirm] = React.useState(null);
  const [deleting,   setDeleting]   = React.useState(null);
  const [edits,      setEdits]      = React.useState({});
  const [focusCell,  setFocusCell]  = React.useState(null);
  const [cellSaving, setCellSaving] = React.useState(null);

  // ── Config ────────────────────────────────────
  const relatedTable = obj.relatedTable;
  const displayAs    = obj.displayAs    || 'rows';
  const allowAdd     = obj.allowAdd     === 'yes' || obj.allowAdd    === true;
  const allowDelete  = obj.allowDelete  === 'yes' || obj.allowDelete === true;
  const rowLimit     = parseInt(obj.portalRows)   || 25;
  const maxHeight    = parseInt(obj.portalHeight) || 0;
  const label        = obj.label || 'Related Records';
  const displayFields= Array.isArray(obj.displayFields) ? obj.displayFields : [];
  const sortField    = obj.sortField || '';
  const sortDir      = obj.sortDir   || 'desc';

  // Theme label
  const th      = getTheme();
  const lblSize = th.label_size  || '10px';
  const lblColor= th.label_color || '#64748b';
  const fldLbl  = { fontSize:lblSize, fontWeight:700, textTransform:'uppercase', letterSpacing:'0.07em', color:lblColor };

  // ── FIX #5: reset add mode on record navigation ──
  React.useEffect(() => {
    setAddOpen(false); setAddValues({}); setEdits({});
  }, [recordId]);

  // ── Load ──────────────────────────────────────
  function load() {
    if (!relatedTable || !recordId) { setLoading(false); return; }
    setLoading(true); setError(null);
    apiFetch(`${API_BASE}/v6/portal?app=${appId}&parentTable=${parentTable}&parentRecord=${recordId}&relatedTable=${relatedTable}&sortField=${sortField}&sortDir=${sortDir}&limit=${rowLimit}`)
      .then(r => r.json())
      .then(d => {
        if (d.status !== 'ok') throw new Error(d.message);
        setRows(d.records || []);
        setRelFields(d.fields || []);
      })
      .catch(e => setError(e.message))
      .finally(() => setLoading(false));
  }
  React.useEffect(() => { load(); }, [appId, parentTable, recordId, relatedTable]);

  // ── Fields ────────────────────────────────────
  function vf() {
    if (displayFields.length === 0) return relFields;
    return relFields.filter(f => {
      const n = String(f.field).replace('f','');
      return displayFields.includes(n) || displayFields.includes(f.field);
    });
  }
  function fk(f) { return `f${String(f.field).replace('f','')}`; }

  // ── Cell editing ──────────────────────────────
  function cellVal(row, f) {
    const k = `${row.r_auto}:${fk(f)}`;
    return edits.hasOwnProperty(k) ? edits[k] : (row[fk(f)] || '');
  }
  function onCC(row, f, val) { setEdits(p => ({...p,[`${row.r_auto}:${fk(f)}`]:val})); }
  async function onCB(row, f) {
    setFocusCell(null);
    const k   = `${row.r_auto}:${fk(f)}`;
    const val = edits.hasOwnProperty(k) ? edits[k] : (row[fk(f)] || '');
    if (String(val) === String(row[fk(f)] || '')) { setEdits(p => { const n={...p}; delete n[k]; return n; }); return; }
    setCellSaving(k);
    try {
      await apiFetch(`${API_BASE}/v6/record?app=${appId}&table=${relatedTable}&id=${row.r_auto}`,
        { method:'POST', body:JSON.stringify({[fk(f)]:val}) });
      setRows(p => p.map(r => r.r_auto===row.r_auto ? {...r,[fk(f)]:val} : r));
    } catch(e) { console.error('Portal save:', e.message); }
    setCellSaving(null);
    setEdits(p => { const n={...p}; delete n[k]; return n; });
  }

  // ── Add / Delete ──────────────────────────────
  async function doAdd() {
    if (!Object.values(addValues).some(v => String(v||'').trim())) return;
    setSaving(true);
    try {
      const d = await apiFetch(`${API_BASE}/v6/portal/add`, {
        method:'POST', body:JSON.stringify({app:appId,parentTable,parentRecord:recordId,relatedTable,fields:addValues}),
      }).then(r => r.json());
      if (d.status !== 'ok') throw new Error(d.message);
      setAddOpen(false); setAddValues({}); load();
    } catch(e) { alert('Add failed: '+e.message); }
    setSaving(false);
  }
  function cancelAdd() { setAddOpen(false); setAddValues({}); }

  async function doDelete() {
    if (!delConfirm) return;
    const ra = delConfirm;
    setDeleting(ra); setDelConfirm(null);
    try {
      await apiFetch(`${API_BASE}/v6/portal/delete?app=${appId}&parentTable=${parentTable}&parentRecord=${recordId}&relatedTable=${relatedTable}&relatedRecord=${ra}`,
        {method:'DELETE'});
      load();
    } catch(e) { alert('Delete failed: '+e.message); }
    setDeleting(null);
  }

  const visFields = vf();

  // ── Shared cell input (transparent, border on focus) ──
  function cellInp(k, val, onChange, onBlur, autoFocus, placeholder) {
    const focused = focusCell === k;
    const csaving = cellSaving === k;
    return (
      <input
        key={k}
        style={{
          width:'100%', boxSizing:'border-box',
          border: focused ? '1px solid #2563eb' : csaving ? '1px solid #f59e0b' : '1px solid transparent',
          borderRadius:4, padding:'3px 5px',
          fontSize:'1em', fontFamily:'inherit', color:'#1e293b',
          background: focused ? '#fff' : csaving ? '#fffbeb' : 'transparent',
          outline:'none',
        }}
        value={val}
        placeholder={placeholder || ''}
        autoFocus={autoFocus}
        onChange={e => onChange(e.target.value)}
        onFocus={() => setFocusCell(k)}
        onBlur={onBlur}
        onKeyDown={e => { if(e.key==='Enter') e.target.blur(); }}
      />
    );
  }

  // ── Add input (same as S.input) ──
  const addInpStyle = {
    width:'100%', boxSizing:'border-box',
    border:'1px solid #e2e8f0', borderRadius:5,
    padding:'6px 10px', fontSize:'1em',
    color:'#1e293b', background:'#fafbfc',
    outline:'none', fontFamily:'inherit',
  };

  if (!relatedTable) {
    return (
      <div style={{marginBottom:14}}>
        <label style={{...fldLbl, display:'block', marginBottom:4}}>{label}</label>
        <div style={SP.box}><div style={SP.empty}>Portal not configured — set Related Table in DEV</div></div>
      </div>
    );
  }

  const hasRows = !loading && rows.length > 0;
  const showTable = hasRows || (addOpen && !loading);

  // Action column width — always present to align delete buttons
  const actW = 70; // px — holds save+cancel or delete button

  return (
    <div style={{marginBottom:14}}>

      {/* ── Label + + button — outside box ── */}
      <div style={{display:'flex', alignItems:'center', marginBottom:4}}>
        <label style={{...fldLbl, flex:1}}>
          {label}
          {hasRows && <span style={{fontWeight:400, marginLeft:5, opacity:0.6}}>{`(${rows.length})`}</span>}
        </label>
        {allowAdd && !addOpen && (
          <IconBtn icon="plus" onClick={() => setAddOpen(true)} title={`Add ${label}`} />
        )}
      </div>

      {/* ── Box ── */}
      <div style={{
        width:'100%', boxSizing:'border-box',
        background:'#fff', border:'1px solid #e2e8f0', borderRadius:6, overflow:'hidden',
        maxHeight: maxHeight > 0 ? maxHeight+'px' : undefined,
        overflowY: maxHeight > 0 ? 'auto' : undefined,
      }}>

        {error && <div style={{background:'#fef2f2',color:'#dc2626',padding:'7px 12px',fontSize:12}}>{error}</div>}
        {loading && <div style={{padding:'10px 12px',display:'flex',flexDirection:'column',gap:5}}>{[1,2].map(i=><div key={i} style={{height:14,background:'#f1f5f9',borderRadius:3}}/>)}</div>}

        {/* ── Empty state ── */}
        {!loading && rows.length===0 && !addOpen && (
          <div style={{padding:'10px 12px', fontSize:13, color:'#94a3b8', fontStyle:'normal'}}>
            No {label.toLowerCase()} yet
            {allowAdd && <span> — <span style={{cursor:'pointer', textDecoration:'none', textDecorationStyle:'dotted'}} onClick={()=>setAddOpen(true)}>click + to add</span></span>}
          </div>
        )}

        {/* ════════════════════════════════════════
            ROWS MODE — real <table>
            FIX #3: add row is FIRST row inside table
            FIX #4: distinct from columns
        ════════════════════════════════════════ */}
        {showTable && displayAs === 'rows' && (
          <table style={{width:'100%', borderCollapse:'collapse', tableLayout:'fixed'}}>
            <colgroup>
              {visFields.map((f,i) => <col key={i} />)}
              <col style={{width: actW+'px'}} />
            </colgroup>
            <thead>
              <tr style={{background:'#f8fafc', borderBottom:'1px solid #f1f5f9'}}>
                {visFields.map(f => (
                  <th key={f.field} style={{...fldLbl, padding:'5px 6px', textAlign:'left', fontWeight:700}}>{f.name}</th>
                ))}
                <th style={{width:actW}} />
              </tr>
            </thead>
            <tbody>
              {/* ── FIX #3: Add row INSIDE table, no duplicate headers ── */}
              {addOpen && (
                <tr style={{background:'#f8fafc', borderBottom:'1px solid #e2e8f0'}}>
                  {visFields.map((f, i) => (
                    <td key={f.field} style={{padding:'4px 4px'}}>
                      <input
                        style={addInpStyle}
                        placeholder={f.name}
                        value={addValues[fk(f)] || ''}
                        autoFocus={i===0}
                        onChange={e => setAddValues(p => ({...p,[fk(f)]:e.target.value}))}
                        onFocus={e => { e.target.style.borderColor='#2563eb'; e.target.style.background='#fff'; }}
                        onBlur={e  => { e.target.style.borderColor='#e2e8f0'; e.target.style.background='#fafbfc'; }}
                        onKeyDown={e => { if(e.key==='Enter') doAdd(); if(e.key==='Escape') cancelAdd(); }}
                      />
                    </td>
                  ))}
                  <td style={{padding:'4px 4px', textAlign:'right'}}>
                    <div style={{display:'flex', gap:4, justifyContent:'flex-end'}}>
                      <IconBtn icon="check" active onClick={doAdd}     disabled={saving} title="Save"   />
                      <IconBtn icon="x"           onClick={cancelAdd}  title="Cancel" />
                    </div>
                  </td>
                </tr>
              )}
              {/* ── Data rows ── */}
              {rows.map(row => (
                <tr key={row.r_auto} style={{borderBottom:'1px solid #f8fafc', opacity: deleting===row.r_auto ? 0.35 : 1}}>
                  {visFields.map(f => {
                    const k = `${row.r_auto}:${fk(f)}`;
                    return (
                      <td key={f.field} style={{padding:'2px 4px', verticalAlign:'middle'}}>
                        {cellInp(k, cellVal(row,f), v=>onCC(row,f,v), ()=>onCB(row,f), false, '')}
                      </td>
                    );
                  })}
                  <td style={{padding:'2px 4px', textAlign:'right', verticalAlign:'middle'}}>
                    {allowDelete && (
                      <IconBtn icon="trash-2" danger onClick={()=>setDelConfirm(row.r_auto)} disabled={deleting===row.r_auto} title="Delete" />
                    )}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}

        {/* ════════════════════════════════════════
            COLUMNS MODE — table with label | input per field
            FIX #4: completely different layout from rows
        ════════════════════════════════════════ */}
        {showTable && displayAs === 'columns' && (
          <table style={{width:'100%', borderCollapse:'collapse'}}>
            <colgroup>
              <col style={{width:90}} />
              <col />
              <col style={{width: allowDelete ? 44 : 0}} />
            </colgroup>
            <tbody>
              {/* Add row in columns mode */}
              {addOpen && (
                <>
                  {visFields.map((f, fi) => (
                    <tr key={`add-${f.field}`} style={{background:'#f8fafc'}}>
                      <td style={{...fldLbl, padding:'3px 6px 3px 10px', textAlign:'right', whiteSpace:'nowrap', verticalAlign:'middle'}}>{f.name}</td>
                      <td style={{padding:'3px 4px', verticalAlign:'middle'}}>
                        <input
                          style={addInpStyle}
                          placeholder={f.name}
                          value={addValues[fk(f)] || ''}
                          autoFocus={fi===0}
                          onChange={e => setAddValues(p => ({...p,[fk(f)]:e.target.value}))}
                          onFocus={e => { e.target.style.borderColor='#2563eb'; e.target.style.background='#fff'; }}
                          onBlur={e  => { e.target.style.borderColor='#e2e8f0'; e.target.style.background='#fafbfc'; }}
                          onKeyDown={e => { if(e.key==='Enter') doAdd(); if(e.key==='Escape') cancelAdd(); }}
                        />
                      </td>
                      {fi===0
                        ? <td rowSpan={visFields.length} style={{verticalAlign:'middle', padding:'0 6px'}}>
                            <div style={{display:'flex', flexDirection:'column', gap:4, alignItems:'center'}}>
                              <IconBtn icon="check" active onClick={doAdd}    disabled={saving} title="Save"   />
                              <IconBtn icon="x"           onClick={cancelAdd} title="Cancel" />
                            </div>
                          </td>
                        : null
                      }
                    </tr>
                  ))}
                  {rows.length > 0 && (
                    <tr><td colSpan={3} style={{padding:'0 10px'}}><div style={{height:1, background:'#e2e8f0', margin:'4px 0'}} /></td></tr>
                  )}
                </>
              )}
              {/* Existing records */}
              {rows.map((row, idx) => (
                <React.Fragment key={row.r_auto}>
                  {visFields.map((f, fi) => {
                    const k       = `${row.r_auto}:${fk(f)}`;
                    const focused = focusCell===k;
                    const csaving = cellSaving===k;
                    return (
                      <tr key={f.field} style={{opacity: deleting===row.r_auto ? 0.35 : 1}}>
                        <td style={{...fldLbl, padding:'3px 6px 3px 10px', textAlign:'right', whiteSpace:'nowrap', verticalAlign:'middle'}}>{f.name}</td>
                        <td style={{padding:'2px 4px', verticalAlign:'middle'}}>
                          <input
                            style={{
                              width:'100%', boxSizing:'border-box',
                              border: focused ? '1px solid #2563eb' : csaving ? '1px solid #f59e0b' : '1px solid #e2e8f0',
                              borderRadius:5, padding:'5px 8px',
                              fontSize:'1em', fontFamily:'inherit', color:'#1e293b',
                              background: focused ? '#fff' : '#fafbfc',
                              outline:'none',
                            }}
                            value={cellVal(row,f)}
                            onChange={e => onCC(row,f,e.target.value)}
                            onFocus={() => setFocusCell(k)}
                            onBlur={() => onCB(row,f)}
                            onKeyDown={e => { if(e.key==='Enter') e.target.blur(); }}
                          />
                        </td>
                        {fi===0
                          ? <td rowSpan={visFields.length} style={{verticalAlign:'middle', padding:'0 6px', textAlign:'center'}}>
                              {allowDelete && (
                                <IconBtn icon="trash-2" danger onClick={()=>setDelConfirm(row.r_auto)} disabled={deleting===row.r_auto} title="Delete" />
                              )}
                            </td>
                          : null
                        }
                      </tr>
                    );
                  })}
                    {/* ── div between columns f1f5f9 ── */}
                  {idx < rows.length-1 && (
                    <tr><td colSpan={3} style={{padding:'0 10px'}}><div style={{height:'1px', background:'#f1f5f9', margin:'3px 0'}} /></td></tr>
                  )}
                </React.Fragment>
              ))}
            </tbody>
          </table>
        )}

      </div>

      {/* ── Delete confirm dialog ── */}
      {delConfirm && (
        <div style={{position:'fixed',inset:0,background:'rgba(0,0,0,0.35)',display:'flex',alignItems:'center',justifyContent:'center',zIndex:500}}
          onClick={() => setDelConfirm(null)}>
          <div style={{background:'#fff',borderRadius:10,padding:'22px 24px',maxWidth:340,width:'90%',boxShadow:'0 20px 50px rgba(0,0,0,0.18)'}}
            onClick={e => e.stopPropagation()}>
            <div style={{fontSize:14,fontWeight:700,color:'#0f1923',marginBottom:8}}>Delete this record?</div>
            <div style={{fontSize:13,color:'#64748b',lineHeight:1.6,marginBottom:20}}>This will remove the related record. This cannot be undone.</div>
            <div style={{display:'flex',gap:8,justifyContent:'flex-end'}}>
              <IconBtn icon="x"       onClick={() => setDelConfirm(null)} title="Cancel" />
              <button onClick={doDelete} style={{padding:'6px 16px',background:'#dc2626',color:'#fff',border:'none',borderRadius:6,fontSize:13,fontWeight:600,cursor:'pointer',fontFamily:'inherit'}}>
                Delete
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

const SP = {
  box:   { width:'100%', boxSizing:'border-box', background:'#fff', border:'1px solid #e2e8f0', borderRadius:6, overflow:'hidden' },
  empty: { padding:'10px 12px', fontSize:13, color:'#94a3b8', fontStyle:'italic' },
};
