// files.jsx — FileManager: quản lý file đính kèm của 1 bản ghi (Hợp đồng / Báo giá),
// lưu trên Supabase Storage (bucket 'attachments'), đường dẫn '<scope>/<code>/<ts>_<tên>'.

function fileSizeLabel(n){ n = +n || 0; return n < 1024 ? n + ' B' : n < 1048576 ? Math.round(n / 1024) + ' KB' : (n / 1048576).toFixed(1) + ' MB'; }
function fileDisplayName(name){ return String(name || '').replace(/^\d{10,}_/, ''); }   // bỏ tiền tố timestamp
function fileIcon(name, mime){
  const n = (name || '').toLowerCase(); const m = mime || '';
  if (/\.pdf$/.test(n) || m === 'application/pdf') return 'bi-file-earmark-pdf';
  if (/\.(xls|xlsx|csv)$/.test(n) || /sheet|excel|csv/.test(m)) return 'bi-file-earmark-spreadsheet';
  if (/\.(docx?|rtf)$/.test(n) || /word|document/.test(m)) return 'bi-file-earmark-word';
  if (/\.(png|jpe?g|gif|webp|svg|bmp)$/.test(n) || /^image\//.test(m)) return 'bi-file-earmark-image';
  if (/\.(zip|rar|7z|tar|gz)$/.test(n)) return 'bi-file-earmark-zip';
  return 'bi-file-earmark-text';
}

function FileManager({ scope, code, title }){
  const { lang } = useLang();
  const toast = useToast();
  const confirm = useConfirm();
  const prefix = scope + '/' + code;
  const [files, setFiles] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [busy, setBusy] = React.useState(false);
  const fileRef = React.useRef();
  const ready = !!window.SB_READY;

  const reload = React.useCallback(() => {
    if (!ready) { setLoading(false); return; }
    DB.storageList(prefix).then(fs => { setFiles(fs); setLoading(false); }).catch(() => setLoading(false));
  }, [prefix, ready]);
  React.useEffect(() => { setLoading(true); reload(); }, [prefix]);

  const onPick = async (e) => {
    const list = [...(e.target.files || [])]; e.target.value = '';
    if (!list.length) return;
    if (!ready) { toast(lang === 'vi' ? 'Chưa kết nối máy chủ — không tải lên được' : 'Not connected — cannot upload', 'error'); return; }
    setBusy(true); let ok = 0;
    for (const file of list){
      if (file.size > 25 * 1024 * 1024) { toast((lang === 'vi' ? 'Tệp quá lớn (>25MB): ' : 'Too large (>25MB): ') + file.name, 'error'); continue; }
      const safe = file.name.replace(/[^\w.\-() ]+/g, '_');
      const path = prefix + '/' + Date.now() + '_' + safe;
      try { await DB.storageUpload(path, file); ok++; } catch (err) { toast((lang === 'vi' ? 'Tải lên thất bại: ' : 'Upload failed: ') + (err.message || err), 'error'); }
    }
    setBusy(false); reload();
    if (ok) toast((lang === 'vi' ? 'Đã tải lên ' : 'Uploaded ') + ok + (lang === 'vi' ? ' tệp' : ' file(s)'), 'success');
  };
  const download = async (f) => {
    const url = await DB.storageSignedUrl(f.path);
    if (url) window.open(url, '_blank'); else toast(lang === 'vi' ? 'Không tạo được liên kết tải' : 'Cannot get download link', 'error');
  };
  const remove = async (f) => {
    if (!(await confirm({ message:(lang === 'vi' ? 'Xóa tệp "' : 'Delete "') + fileDisplayName(f.name) + '"?', confirmLabel:lang === 'vi' ? 'Xóa' : 'Delete' }))) return;
    try { await DB.storageRemove(f.path); setFiles(s => s.filter(x => x.path !== f.path)); toast(lang === 'vi' ? 'Đã xóa tệp' : 'File deleted', 'success'); }
    catch (err) { toast((lang === 'vi' ? 'Xóa thất bại: ' : 'Delete failed: ') + (err.message || err), 'error'); }
  };

  return (
    <div className="card">
      <div className="card-head"><h3 style={{ fontSize:'var(--fs-md)' }}><i className="bi bi-paperclip" style={{ marginRight:6, color:'var(--primary)' }}></i>{title || (lang === 'vi' ? 'Tài liệu đính kèm' : 'Attachments')}{files.length ? <span className="badge badge-neutral" style={{ marginLeft:8 }}>{files.length}</span> : null}</h3>
        <button className="btn btn-sm btn-primary" disabled={busy || !ready} onClick={() => fileRef.current && fileRef.current.click()}><i className={'bi ' + (busy ? 'bi-arrow-repeat spin' : 'bi-upload')}></i>{lang === 'vi' ? 'Tải lên' : 'Upload'}</button>
        <input ref={fileRef} type="file" multiple onChange={onPick} style={{ display:'none' }} />
      </div>
      <div className="card-body">
        {!ready ? <div className="subtle" style={{ fontSize:'var(--fs-base)' }}>{lang === 'vi' ? 'Cần đăng nhập để quản lý tệp.' : 'Sign in to manage files.'}</div>
          : loading ? <div className="subtle flex g8 items-center" style={{ fontSize:'var(--fs-base)' }}><i className="bi bi-arrow-repeat spin"></i>{lang === 'vi' ? 'Đang tải…' : 'Loading…'}</div>
          : files.length === 0 ? <div className="subtle" style={{ fontSize:'var(--fs-base)' }}>{lang === 'vi' ? 'Chưa có tệp. Bấm “Tải lên” để thêm tài liệu liên quan (PDF, ảnh, Word, Excel…).' : 'No files yet. Click “Upload”.'}</div>
          : files.map(f => (
            <div key={f.path} className="list-row" style={{ alignItems:'center' }}>
              <i className={'bi ' + fileIcon(f.name, f.mimetype)} style={{ fontSize:18, color:'var(--primary)', flex:'none' }}></i>
              <div className="grow" style={{ minWidth:0 }}>
                <div className="truncate" style={{ fontWeight:500 }}>{fileDisplayName(f.name)}</div>
                <div className="subtle mono" style={{ fontSize:'var(--fs-sm)' }}>{fileSizeLabel(f.size)}{f.createdAt ? ' · ' + fmtDate(String(f.createdAt).slice(0, 10)) : ''}</div>
              </div>
              <button className="iconbtn" title={lang === 'vi' ? 'Tải xuống' : 'Download'} onClick={() => download(f)}><i className="bi bi-download" style={{ fontSize:13 }}></i></button>
              <button className="iconbtn" title={lang === 'vi' ? 'Xóa' : 'Delete'} onClick={() => remove(f)}><i className="bi bi-trash" style={{ fontSize:13 }}></i></button>
            </div>
          ))}
      </div>
    </div>
  );
}

Object.assign(window, { FileManager, fileSizeLabel, fileDisplayName, fileIcon });
