// PhotoUpload — 共通の写真アップロードコンポーネント
// 使い方:
//   <PhotoUpload kind="circle|square|card"
//                value={file or null}
//                onChange={(file)=>...}
//                title="顔がはっきり写った写真を1枚"
//                hint="笑顔の写真がおすすめ。サングラスは不可です。"
//                accept="image/*" />
//
// File オブジェクトを保持し、変更時に親に通知。
// 送信時は palpetEncodeFile(file) で Base64 にして webhook へ POST。

const { useRef, useState, useEffect } = React;

function PhotoUpload({ kind='card', value, onChange, title, hint, accept='image/*', sampleTone='warm' }) {
  const inputRef = useRef(null);
  const [previewURL, setPreviewURL] = useState(null);

  // value が変わったら preview URL を更新（メモリリーク対策つき）
  useEffect(() => {
    if (value instanceof File) {
      const url = URL.createObjectURL(value);
      setPreviewURL(url);
      return () => URL.revokeObjectURL(url);
    } else if (typeof value === 'string' && value) {
      // すでに data URL or http URL
      setPreviewURL(value);
    } else {
      setPreviewURL(null);
    }
  }, [value]);

  const pick = () => inputRef.current?.click();
  const onFile = (e) => {
    const f = e.target.files?.[0];
    if (f) onChange(f);
    // 同じファイルを連続で選べるようにリセット
    e.target.value = '';
  };
  const remove = () => onChange(null);

  const photoTones = {
    warm:  ['#F4DBA8','#E8B97A'],
    peach: ['#F8CFB8','#EBA689'],
    sage:  ['#CBE0CC','#9CC2A4'],
    cream: ['#F5E7CC','#E0CFA8'],
  };
  const [a,b] = photoTones[sampleTone] || photoTones.warm;
  const placeholderBG = `repeating-linear-gradient(135deg, ${a} 0 12px, ${b} 12px 24px)`;

  const PreviewBox = ({ size, round }) => (
    <div style={{
      width: size, height: size, borderRadius: round,
      background: previewURL ? `#fff` : placeholderBG,
      flex:'0 0 auto', overflow:'hidden',
      display:'grid', placeItems:'center', color:'#5b4326',
      fontFamily:'ui-monospace', fontSize:10,
      position:'relative',
    }}>
      {previewURL ? (
        <img src={previewURL} alt="preview"
             style={{width:'100%',height:'100%',objectFit:'cover',display:'block'}}/>
      ) : (
        <span>📷 photo</span>
      )}
    </div>
  );

  // 円形（プロフィール写真）
  if (kind === 'circle') {
    return (
      <div style={{
        display:'flex',gap:16,alignItems:'center',
        padding:18,borderRadius:18,
        border:'1.5px dashed '+(previewURL?'var(--c-primary)':'rgba(0,0,0,.15)'),
        background:'#fff',
      }}>
        <PreviewBox size={96} round="50%"/>
        <div style={{flex:1, minWidth:0}}>
          {previewURL && value instanceof File ? (
            <>
              <div style={{fontWeight:700,fontSize:14,color:'var(--c-primary-deep)',marginBottom:4,display:'flex',gap:6,alignItems:'center'}}>
                <Icons.Check size={14}/> 写真を選びました
              </div>
              <div style={{fontSize:12,color:'#5d4d3a',wordBreak:'break-all',lineHeight:1.6}}>
                {value.name} ・ {fmtSize(value.size)}
              </div>
            </>
          ) : (
            <>
              <div style={{fontWeight:600,marginBottom:4}}>{title}</div>
              <div style={{fontSize:12,color:'#7a6a55',lineHeight:1.7}}>{hint}</div>
            </>
          )}
        </div>
        <div style={{display:'flex',flexDirection:'column',gap:6}}>
          <button onClick={pick} style={btnPrimary}>{previewURL?'変更':'写真を選ぶ'}</button>
          {previewURL && (
            <button onClick={remove} style={btnGhost}>削除</button>
          )}
        </div>
        <input ref={inputRef} type="file" accept={accept} onChange={onFile} style={{display:'none'}}/>
      </div>
    );
  }

  // 正方形（ペット写真などのカード）
  if (kind === 'square') {
    return (
      <div style={{
        padding:14,borderRadius:18,
        border:'1.5px dashed '+(previewURL?'var(--c-primary)':'rgba(0,0,0,.15)'),
        background:'#fff',
        display:'flex',gap:14,alignItems:'center',
      }}>
        <PreviewBox size={120} round={14}/>
        <div style={{flex:1, minWidth:0}}>
          {previewURL && value instanceof File ? (
            <>
              <div style={{fontWeight:700,fontSize:14,color:'var(--c-primary-deep)',marginBottom:4,display:'flex',gap:6,alignItems:'center'}}>
                <Icons.Check size={14}/> 写真を選びました
              </div>
              <div style={{fontSize:12,color:'#5d4d3a',wordBreak:'break-all',lineHeight:1.6}}>
                {value.name} ・ {fmtSize(value.size)}
              </div>
              <div style={{display:'flex',gap:6,marginTop:10}}>
                <button onClick={pick} style={btnPrimary}>変更</button>
                <button onClick={remove} style={btnGhost}>削除</button>
              </div>
            </>
          ) : (
            <>
              <div style={{fontWeight:600,marginBottom:4}}>{title}</div>
              <div style={{fontSize:12,color:'#7a6a55',lineHeight:1.7,marginBottom:10}}>{hint}</div>
              <button onClick={pick} style={btnPrimary}>写真を選ぶ</button>
            </>
          )}
        </div>
        <input ref={inputRef} type="file" accept={accept} onChange={onFile} style={{display:'none'}}/>
      </div>
    );
  }

  // カードタイプ（身分証など）— アイコン+説明+「始める」/プレビュー切替
  const cardActive = !!previewURL;
  return (
    <div style={{
      padding:'18px 22px',borderRadius:18,background:'#fff',
      border:'1.5px solid '+(cardActive?'var(--c-primary)':'rgba(0,0,0,.08)'),
      display:'flex',gap:16,alignItems:'center',
    }}>
      {cardActive ? (
        <PreviewBox size={56} round={10}/>
      ) : (
        <div style={{
          width:44,height:44,borderRadius:12,flex:'0 0 auto',
          background:'var(--c-bg-alt)',color:'#9c8a72',
          display:'grid',placeItems:'center',
        }}>📷</div>
      )}
      <div style={{flex:1,minWidth:0}}>
        <div style={{fontWeight:700}}>{title}</div>
        {cardActive && value instanceof File ? (
          <div style={{fontSize:12,color:'var(--c-primary-deep)',marginTop:2,wordBreak:'break-all'}}>
            ✓ {value.name} ・ {fmtSize(value.size)}
          </div>
        ) : (
          <div style={{fontSize:12,color:'#7a6a55',marginTop:2}}>{hint}</div>
        )}
      </div>
      <div style={{display:'flex',gap:6}}>
        <button onClick={pick} style={cardActive?btnGhost:btnPrimary}>
          {cardActive?'変更':'始める'}
        </button>
        {cardActive && (
          <button onClick={remove} style={btnGhost}>削除</button>
        )}
      </div>
      <input ref={inputRef} type="file" accept={accept} onChange={onFile} style={{display:'none'}}/>
    </div>
  );
}

const btnPrimary = {
  background:'var(--c-primary-soft)',color:'var(--c-primary-deep)',border:'none',
  padding:'9px 14px',borderRadius:10,fontWeight:700,cursor:'pointer',
  fontFamily:'inherit',fontSize:13,whiteSpace:'nowrap',
};
const btnGhost = {
  background:'transparent',color:'#9c8a72',border:'1px solid rgba(0,0,0,.08)',
  padding:'7px 12px',borderRadius:10,fontWeight:600,cursor:'pointer',
  fontFamily:'inherit',fontSize:12,whiteSpace:'nowrap',
};

function fmtSize(bytes) {
  if (!bytes && bytes !== 0) return '';
  if (bytes < 1024) return bytes + ' B';
  if (bytes < 1024*1024) return (bytes/1024).toFixed(1) + ' KB';
  return (bytes/(1024*1024)).toFixed(1) + ' MB';
}

// File を base64 にして webhook へ POST するためのヘルパ
// 使い方: const payload = await palpetEncodeFile(file)
// 返り値: { name, type, size, base64 }（PNG/JPEG向け、巨大ファイルでも問題なく扱えるが2MB超は webhook 側で拒否することを想定）
window.palpetEncodeFile = function (file) {
  if (!(file instanceof File)) return Promise.resolve(null);
  return new Promise((resolve, reject) => {
    const r = new FileReader();
    r.onload = () => {
      const result = String(r.result || '');
      // data:image/jpeg;base64,XXXX... の base64 部分だけ取り出す
      const base64 = result.split(',')[1] || '';
      resolve({ name: file.name, type: file.type, size: file.size, base64 });
    };
    r.onerror = reject;
    r.readAsDataURL(file);
  });
};

window.PhotoUpload = PhotoUpload;
