// Gotanda Guide — sponsors / partners
// User-editable sponsor cards. Stored in localStorage; URL/text/image
// are entered by the user via the Sponsors tab in the import modal.

const { useState: useSpState } = React;

const SPONSORS_LS = 'gg_sponsors';

function loadSponsors() {
  try {
    const raw = localStorage.getItem(SPONSORS_LS);
    return raw ? JSON.parse(raw) : [];
  } catch { return []; }
}
function saveSponsors(list) {
  try { localStorage.setItem(SPONSORS_LS, JSON.stringify(list)); } catch {}
}

// Position values: 'header' | 'spots' | 'footer' | 'all'
const SP_POSITIONS = ['header', 'spots', 'footer', 'all'];
function sponsorsAt(list, slot) {
  if (!list) return [];
  return list.filter((s) => {
    const p = s.position || 'spots';
    return p === slot || p === 'all';
  });
}

function pickName(s, lang) {
  if (lang === 'en') return s.nameEn || s.name || '';
  return s.name || s.nameEn || '';
}
function pickDesc(s, lang) {
  if (lang === 'en') return s.descEn || s.desc || '';
  return s.desc || s.descEn || '';
}

function SponsorsSection({ sponsors, lang, slot = 'spots' }) {
  const items = sponsorsAt(sponsors, slot);
  if (items.length === 0) return null;
  const T = (ja, en) => (lang === 'ja' ? ja : en);

  // Compact strip for header / footer; full grid for spots area.
  if (slot === 'header' || slot === 'footer') {
    return (
      <div className={`sp-strip sp-strip-${slot}`}>
        <div className="sp-strip-lbl">{T('パートナー', 'Partners')}</div>
        <div className="sp-strip-list">
          {items.map((s) => (
            <a
              key={s.id}
              href={s.url || '#'}
              target="_blank"
              rel="noopener noreferrer"
              className="sp-strip-item"
            >
              {s.image ? (
                <span className="sp-strip-img" style={{ backgroundImage: `url(${s.image})` }} />
              ) : null}
              <span className="sp-strip-name">{pickName(s, lang) || T('無題', 'Untitled')}</span>
              <span className="sp-arrow">↗</span>
            </a>
          ))}
        </div>
      </div>
    );
  }

  return (
    <section id="sec-sponsors">
      <div className="sec-hd">
        <div>
          <span className="sec-hd-sub">PARTNERS · {items.length}</span>
          <h2>{T('パートナー', 'Partners')}</h2>
        </div>
      </div>
      <div className="sp-grid">
        {items.map((s) => {
          const nm = pickName(s, lang);
          const ds = pickDesc(s, lang);
          return (
            <a
              key={s.id}
              href={s.url || '#'}
              target="_blank"
              rel="noopener noreferrer"
              className={`sp-card ${s.image ? 'has-img' : ''}`}
            >
              {s.image ? (
                <div className="sp-img" style={{ backgroundImage: `url(${s.image})` }} />
              ) : (
                <div className="sp-img sp-img-fallback">
                  <span>{(nm || '?').slice(0, 1)}</span>
                </div>
              )}
              <div className="sp-body">
                <div className="sp-name">{nm || T('無題', 'Untitled')}</div>
                {ds && <div className="sp-desc">{ds}</div>}
                {s.url && (
                  <div className="sp-url">
                    {(() => { try { return new URL(s.url).hostname; } catch { return s.url; } })()}
                    <span className="sp-arrow">↗</span>
                  </div>
                )}
              </div>
            </a>
          );
        })}
      </div>
      <div className="sp-disclaimer">
        {T(
          '※ パートナー枠は本ガイドの利用者が独自に登録した外部リンクです。リンク先の内容について本ガイドは責任を負いません。',
          'Partner links are user-registered external sites. This guide is not responsible for their content.'
        )}
      </div>
    </section>
  );
}

function SponsorManager({ lang, sponsors, onChange, onClose }) {
  const T = (ja, en) => (lang === 'ja' ? ja : en);
  const [list, setList] = useSpState(() =>
    sponsors.map((s) => ({ position: 'spots', nameEn: '', descEn: '', ...s }))
  );
  const [draft, setDraft] = useSpState({
    name: '', nameEn: '', desc: '', descEn: '',
    url: '', image: '', position: 'spots',
  });

  const POS_OPTS = [
    { v: 'header', label: T('ヘッダー', 'Header') },
    { v: 'spots',  label: T('スポット下', 'Under spots') },
    { v: 'footer', label: T('フッター', 'Footer') },
    { v: 'all',    label: T('全て', 'All') },
  ];
  const [error, setError] = useSpState('');

  const update = (idx, patch) => {
    setList((arr) => arr.map((s, i) => (i === idx ? { ...s, ...patch } : s)));
  };
  const remove = (idx) => setList((arr) => arr.filter((_, i) => i !== idx));
  const move = (idx, dir) => {
    setList((arr) => {
      const next = arr.slice();
      const j = idx + dir;
      if (j < 0 || j >= next.length) return arr;
      [next[idx], next[j]] = [next[j], next[idx]];
      return next;
    });
  };

  // Downscale uploaded logos before storing — full-res images quickly blow
  // out the 5MB localStorage budget. Output is a JPEG data URL <= ~50KB.
  const resizeImage = (file, maxSize = 240, quality = 0.82) => new Promise((resolve, reject) => {
    if (!file) return resolve('');
    const reader = new FileReader();
    reader.onload = () => {
      const img = new Image();
      img.onload = () => {
        let { width, height } = img;
        const scale = Math.min(1, maxSize / Math.max(width, height));
        width = Math.round(width * scale);
        height = Math.round(height * scale);
        const canvas = document.createElement('canvas');
        canvas.width = width;
        canvas.height = height;
        const ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0, width, height);
        const ext = file.type.includes('png') ? 'image/png' : 'image/jpeg';
        resolve(canvas.toDataURL(ext, quality));
      };
      img.onerror = reject;
      img.src = reader.result;
    };
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });

  const onPickImage = async (idx, file) => {
    if (!file) return;
    try {
      const dataUrl = await resizeImage(file);
      update(idx, { image: dataUrl });
    } catch (e) {
      setError('画像の読み込みに失敗: ' + (e?.message || e));
    }
  };

  const onPickDraftImage = async (file) => {
    if (!file) return;
    try {
      const dataUrl = await resizeImage(file);
      setDraft((d) => ({ ...d, image: dataUrl }));
    } catch (e) {
      setError('画像の読み込みに失敗: ' + (e?.message || e));
    }
  };

  const add = () => {
    setError('');
    if (!draft.name.trim() && !draft.url.trim()) {
      setError(T('名前またはURLを入力してください', 'Enter a name or URL'));
      return;
    }
    const id = `sp-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;
    setList((arr) => [...arr, {
      id,
      name: draft.name.trim(),
      nameEn: (draft.nameEn || '').trim(),
      desc: draft.desc.trim(),
      descEn: (draft.descEn || '').trim(),
      url: draft.url.trim(),
      image: draft.image,
      position: draft.position || 'spots',
    }]);
    setDraft({
      name: '', nameEn: '', desc: '', descEn: '',
      url: '', image: '', position: draft.position || 'spots',
    });
  };

  const save = () => {
    saveSponsors(list);
    onChange(list);
    onClose();
  };

  const clear = () => {
    if (!confirm(T('すべてのパートナーを削除しますか？', 'Remove all partners?'))) return;
    setList([]);
  };

  return (
    <div className="cat-mgr">
      <div className="cat-list">
        {list.length === 0 && (
          <div className="empty" style={{ padding: '20px 12px', fontSize: 12 }}>
            {T('まだパートナーが登録されていません', 'No partners yet')}
          </div>
        )}
        {list.map((s, i) => (
          <div key={s.id} className="sp-row">
            <label className="sp-thumb-wrap">
              {s.image ? (
                <div className="sp-thumb" style={{ backgroundImage: `url(${s.image})` }} />
              ) : (
                <div className="sp-thumb sp-thumb-empty">＋</div>
              )}
              <input
                type="file"
                accept="image/*"
                style={{ display: 'none' }}
                onChange={(e) => onPickImage(i, e.target.files?.[0])}
              />
            </label>
            <div className="sp-fields">
              <div className="sp-bi">
                <input
                  className="gp-input"
                  value={s.name}
                  placeholder={T('表示名（日本語）', 'Display name (JA)')}
                  onChange={(e) => update(i, { name: e.target.value })}
                />
                <input
                  className="gp-input"
                  value={s.nameEn || ''}
                  placeholder={T('表示名（英語）', 'Display name (EN)')}
                  onChange={(e) => update(i, { nameEn: e.target.value })}
                />
              </div>
              <div className="sp-bi">
                <input
                  className="gp-input"
                  value={s.desc}
                  placeholder={T('説明（日本語）', 'Description (JA)')}
                  onChange={(e) => update(i, { desc: e.target.value })}
                />
                <input
                  className="gp-input"
                  value={s.descEn || ''}
                  placeholder={T('説明（英語）', 'Description (EN)')}
                  onChange={(e) => update(i, { descEn: e.target.value })}
                />
              </div>
              <input
                className="gp-input"
                value={s.url}
                placeholder="https://..."
                onChange={(e) => update(i, { url: e.target.value })}
              />
              <div className="sp-pos-row">
                <span className="sp-pos-lbl">{T('位置', 'Position')}</span>
                {POS_OPTS.map((o) => (
                  <button
                    key={o.v}
                    type="button"
                    className={`sp-pos-pill ${(s.position || 'spots') === o.v ? 'is-on' : ''}`}
                    onClick={() => update(i, { position: o.v })}
                  >
                    {o.label}
                  </button>
                ))}
              </div>
            </div>
            <div className="sp-row-actions">
              <button className="cat-del" onClick={() => move(i, -1)} disabled={i === 0} title="↑">↑</button>
              <button className="cat-del" onClick={() => move(i, 1)} disabled={i === list.length - 1} title="↓">↓</button>
              <button className="cat-del" onClick={() => remove(i)} title={T('削除', 'Delete')}>×</button>
            </div>
          </div>
        ))}
      </div>

      <div className="cat-add">
        <div className="gp-lbl" style={{ marginBottom: 6 }}>
          {T('新しいパートナーを追加', 'Add a new partner')}
        </div>
        <div className="sp-add-grid">
          <label className="sp-thumb-wrap">
            {draft.image ? (
              <div className="sp-thumb" style={{ backgroundImage: `url(${draft.image})` }} />
            ) : (
              <div className="sp-thumb sp-thumb-empty">画像</div>
            )}
            <input
              type="file"
              accept="image/*"
              style={{ display: 'none' }}
              onChange={(e) => onPickDraftImage(e.target.files?.[0])}
            />
          </label>
          <div className="sp-fields">
            <div className="sp-bi">
              <input
                className="gp-input"
                placeholder={T('表示名（日本語）', 'Display name (JA)')}
                value={draft.name}
                onChange={(e) => setDraft({ ...draft, name: e.target.value })}
              />
              <input
                className="gp-input"
                placeholder={T('表示名（英語）', 'Display name (EN)')}
                value={draft.nameEn}
                onChange={(e) => setDraft({ ...draft, nameEn: e.target.value })}
              />
            </div>
            <div className="sp-bi">
              <input
                className="gp-input"
                placeholder={T('説明（日本語）', 'Description (JA)')}
                value={draft.desc}
                onChange={(e) => setDraft({ ...draft, desc: e.target.value })}
              />
              <input
                className="gp-input"
                placeholder={T('説明（英語）', 'Description (EN)')}
                value={draft.descEn}
                onChange={(e) => setDraft({ ...draft, descEn: e.target.value })}
              />
            </div>
            <input
              className="gp-input"
              placeholder="https://..."
              value={draft.url}
              onChange={(e) => setDraft({ ...draft, url: e.target.value })}
            />
            <div className="sp-pos-row">
              <span className="sp-pos-lbl">{T('表示位置', 'Position')}</span>
              {POS_OPTS.map((o) => (
                <button
                  key={o.v}
                  type="button"
                  className={`sp-pos-pill ${(draft.position || 'spots') === o.v ? 'is-on' : ''}`}
                  onClick={() => setDraft({ ...draft, position: o.v })}
                >
                  {o.label}
                </button>
              ))}
            </div>
          </div>
        </div>
        <div style={{ display: 'flex', gap: 10, marginTop: 10, alignItems: 'center', flexWrap: 'wrap' }}>
          <button className="btn-primary" onClick={add} style={{ flex: 'none' }}>
            ＋ {T('追加', 'Add')}
          </button>
          {error && <div className="imp-msg imp-err" style={{ margin: 0, padding: '6px 10px' }}>{error}</div>}
        </div>
        <div className="gp-hint" style={{ marginTop: 8 }}>
          {T(
            '画像はクリックして選択。URL・テキストは自由に入力できます。リンク先・内容についての責任はサイト運営者にあります。',
            'Click the image box to upload. URL and text are user-defined. The site owner is responsible for linked content.'
          )}
        </div>
      </div>

      <div className="cat-actions">
        <button className="btn-primary" onClick={save}>
          {T('保存して適用', 'Save & apply')}
        </button>
        {list.length > 0 && (
          <button className="btn-secondary" onClick={clear}>
            {T('全削除', 'Clear all')}
          </button>
        )}
        <button className="btn-secondary" onClick={onClose}>
          {T('閉じる', 'Close')}
        </button>
      </div>
    </div>
  );
}

Object.assign(window, { SponsorsSection, SponsorManager, loadSponsors, saveSponsors });
