// ============================================
// ソルマーレ長崎FC 情報共有アプリ v2
// React SPA + PWA
// ============================================
const { useState, useEffect, useMemo, useCallback } = React;

// ===== SVG Icons =====
const I = {
  Home:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>,
  Calendar:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>,
  Users:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>,
  User:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>,
  Book:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>,
  Settings:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>,
  Clock:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>,
  MapPin:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg>,
  Flag:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/><line x1="4" y1="22" x2="4" y2="15"/></svg>,
  Pin:()=><svg viewBox="0 0 24 24" fill="currentColor"><path d="M16 12V4h1V2H7v2h1v8l-2 2v2h5.2v6h1.6v-6H18v-2l-2-2z"/></svg>,
  Play:()=><svg viewBox="0 0 24 24" fill="currentColor"><polygon points="5 3 19 12 5 21 5 3"/></svg>,
  Plus:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>,
  Car:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M14 16H9m10 0h3v-3.15a1 1 0 0 0-.84-.99L16 11l-2.7-3.6a1 1 0 0 0-.8-.4H5.24a2 2 0 0 0-1.8 1.1l-.8 1.63A6 6 0 0 0 2 12.42V16h3"/><circle cx="6.5" cy="16.5" r="2.5"/><circle cx="16.5" cy="16.5" r="2.5"/></svg>,
  Star:()=><svg viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" strokeWidth="1"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>,
  ChevL:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="15 18 9 12 15 6"/></svg>,
  ChevR:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="9 18 15 12 9 6"/></svg>,
  AlertTri:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>,
  File:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>,
  Bell:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>,
  RefreshCw:()=><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg>,
};

// ===== Data =====
const DOW = ['日','月','火','水','木','金','土'];
const CAT_LABELS = {training:'トレーニング',trm:'TRM',cup:'カップ戦',official:'公式戦',other:'その他'};
const SKILL_LABELS = {shoot:'シュート',pass:'パス',dribble:'ドリブル',tactics:'戦術理解',physical:'フィジカル',gk:'GK',other:'その他'};
const LOC_LABELS = {indoor:'室内',outdoor:'屋外'};

const DEMO_SCHEDULES = [
  {id:1,category:'training',title:'通常トレーニング',event_date:'2026-04-04',start_time:'17:00',end_time:'19:00',location:'南部グラウンド',description:'基礎練習とミニゲーム',attendance:{attend:14,absent:2,undecided:4}},
  {id:2,category:'trm',title:'TRM vs 長崎南FC',event_date:'2026-04-05',start_time:'09:00',end_time:'12:00',location:'諫早市中央運動公園',gather_time:'08:00',gather_place:'南部グラウンド駐車場',opponent:'長崎南FC',age_group:'U-8',kickoff_time:'09:30',parking_limited:true,parking_limit_num:5,parking_note:'台数制限あり。乗り合わせにご協力ください。',description:'8人制。ユニフォーム上下、水筒、着替え持参。',attendance:{attend:16,absent:1,undecided:3}},
  {id:3,category:'training',title:'通常トレーニング',event_date:'2026-04-08',start_time:'17:00',end_time:'19:00',location:'南部グラウンド',attendance:{attend:10,absent:3,undecided:7}},
  {id:4,category:'official',title:'長崎市少年サッカー大会',event_date:'2026-04-12',start_time:'08:30',end_time:'16:00',location:'長崎市総合運動公園',gather_time:'07:30',gather_place:'南部グラウンド駐車場',age_group:'U-8',kickoff_time:'09:00',parking_limited:true,parking_limit_num:8,description:'トーナメント戦。弁当持参。',attendance:{attend:18,absent:0,undecided:2}},
  {id:5,category:'cup',title:'春季ジュニアカップ',event_date:'2026-04-19',start_time:'08:00',end_time:'15:00',location:'大村市陸上競技場',gather_time:'06:30',gather_place:'南部グラウンド駐車場',opponent:'県内8チーム',age_group:'U-8',kickoff_time:'08:30',description:'グループリーグ＋決勝T',attendance:{attend:15,absent:1,undecided:4}},
  {id:6,category:'training',title:'通常トレーニング',event_date:'2026-04-11',start_time:'17:00',end_time:'19:00',location:'南部グラウンド',attendance:{attend:8,absent:2,undecided:10}},
];

const DEMO_NEWS = [
  {id:1,title:'4月の月会費について',category:'info',content:'4月分の月会費（3,000円）の引き落としは4月10日です。\n口座残高のご確認をお願いいたします。',is_pinned:true,created_by:'山田コーチ',created_at:'2026-04-01'},
  {id:2,title:'【結果】3/29 春季交流戦',category:'result',content:'第1試合 ソルマーレ 3-1 長崎北FC\n第2試合 ソルマーレ 2-2 時津少年SC\n第3試合 ソルマーレ 4-0 大村キッカーズ\n\n3戦2勝1分で優勝！',is_pinned:false,created_by:'永野コーチ',created_at:'2026-03-30'},
  {id:3,title:'4/12 長崎市大会のご案内',category:'event',content:'4月12日（日）長崎市総合運動公園にて開催。\n集合：7:30 南部グラウンド駐車場\n持ち物：ユニフォーム上下、水筒、弁当、着替え\n\n車出しの協力をお願いできる方は4/8までにご連絡ください。',is_pinned:true,created_by:'永野コーチ',created_at:'2026-03-28'},
  {id:4,title:'【緊急】4/5 TRM 集合時間変更',category:'urgent',content:'4月5日のTRMの集合時間が変更になりました。\n\n変更前：8:30\n変更後：8:00\n\nお間違えのないようお願いします。',is_pinned:false,created_by:'永野コーチ',created_at:'2026-04-02'},
];

const DEMO_PLAYERS = [
  {id:1,last_name:'田中',first_name:'翔太',grade:'小1',birth_date:'2019-05-12',jersey_number:10},
  {id:2,last_name:'山本',first_name:'蓮',grade:'小1',birth_date:'2019-07-03',jersey_number:7},
  {id:3,last_name:'佐藤',first_name:'大翔',grade:'小1',birth_date:'2019-04-22',jersey_number:4},
  {id:4,last_name:'鈴木',first_name:'陽斗',grade:'小1',birth_date:'2019-09-15',jersey_number:1},
  {id:5,last_name:'高橋',first_name:'悠真',grade:'小1',birth_date:'2019-11-08',jersey_number:9},
  {id:6,last_name:'伊藤',first_name:'湊',grade:'小1',birth_date:'2019-06-20',jersey_number:8},
  {id:7,last_name:'渡辺',first_name:'颯',grade:'小1',birth_date:'2019-03-14',jersey_number:3},
  {id:8,last_name:'中村',first_name:'樹',grade:'小1',birth_date:'2019-08-30',jersey_number:6},
  {id:9,last_name:'永野',first_name:'○○',grade:'小1',birth_date:'2019-12-01',jersey_number:11},
  {id:10,last_name:'小林',first_name:'蒼',grade:'小1',birth_date:'2019-02-18',jersey_number:2},
  {id:11,last_name:'加藤',first_name:'陸',grade:'年長',birth_date:'2020-01-25',jersey_number:5},
  {id:12,last_name:'吉田',first_name:'凛太朗',grade:'年長',birth_date:'2020-06-11',jersey_number:14},
  {id:13,last_name:'松本',first_name:'瑛太',grade:'小1',birth_date:'2019-10-07',jersey_number:13},
  {id:14,last_name:'井上',first_name:'律',grade:'年長',birth_date:'2020-04-02',jersey_number:15},
  {id:15,last_name:'木村',first_name:'朝陽',grade:'小1',birth_date:'2019-07-19',jersey_number:12},
  {id:16,last_name:'林',first_name:'結翔',grade:'小1',birth_date:'2019-05-28',jersey_number:16},
  {id:17,last_name:'清水',first_name:'蒼空',grade:'年長',birth_date:'2020-09-05',jersey_number:17},
  {id:18,last_name:'山口',first_name:'晴',grade:'小1',birth_date:'2019-04-16',jersey_number:18},
  {id:19,last_name:'阿部',first_name:'湊斗',grade:'年長',birth_date:'2020-03-21',jersey_number:19},
  {id:20,last_name:'石田',first_name:'碧',grade:'小1',birth_date:'2019-08-08',jersey_number:20},
];

const DEMO_STAFF = [
  {id:1,last_name:'田中',first_name:'健一',position_title:'監督',qualifications:'JFA公認C級コーチ / 4級審判'},
  {id:2,last_name:'永野',first_name:'',position_title:'アシスタントコーチ',qualifications:'JFA公認D級コーチ'},
  {id:3,last_name:'山田',first_name:'太郎',position_title:'コーチ / 会計',qualifications:'JFA公認D級コーチ'},
];

const DEMO_MEMORY = {
  player_id:9, shoe_brand:'アシックス DSライト', shoe_size:'20.0cm',
  favorite_snack:'inゼリー（マスカット味）', first_goal_date:'2026-03-29',
  first_goal_note:'春季交流戦の第3試合、大村キッカーズ戦で左足シュート！', favorite_player:'三笘薫',
  personal_best:'50m走 10.2秒', notes:'練習前にストレッチを入念にやると調子がいい'
};

const DEMO_LIBRARY = [
  {id:1,url:'https://youtube.com/watch?v=example1',title:'【U-8向け】インサイドキックの基本',location_type:'outdoor',skill_category:'pass',added_by:'永野コーチ'},
  {id:2,url:'https://youtube.com/watch?v=example2',title:'室内でできるボールタッチ練習30選',location_type:'indoor',skill_category:'dribble',added_by:'田中監督'},
  {id:3,url:'https://tiktok.com/@example/video3',title:'シュートの蹴り方 3つのコツ',location_type:'outdoor',skill_category:'shoot',added_by:'山田コーチ'},
  {id:4,url:'https://youtube.com/watch?v=example4',title:'ポジショニングの考え方【ジュニア向け】',location_type:'outdoor',skill_category:'tactics',added_by:'永野コーチ'},
  {id:5,url:'https://youtube.com/watch?v=example5',title:'GK基礎：キャッチングとポジション',location_type:'outdoor',skill_category:'gk',added_by:'田中監督'},
  {id:6,url:'https://youtube.com/watch?v=example6',title:'雨の日にできる体幹トレーニング',location_type:'indoor',skill_category:'physical',added_by:'永野コーチ'},
];

// ===== Helpers =====
function fmtDate(s){const d=new Date(s+'T00:00:00');return{m:d.getMonth()+1,d:d.getDate(),dow:DOW[d.getDay()],dayOfWeek:d.getDay()};}
function fmtDateFull(s){const{m,d,dow}=fmtDate(s);return `${m}月${d}日（${dow}）`;}
function timeAgo(s){const now=new Date();const d=new Date(s+'T00:00:00');const diff=Math.floor((now-d)/(1000*60*60*24));if(diff===0)return'今日';if(diff===1)return'昨日';if(diff<7)return`${diff}日前`;return fmtDateFull(s);}
function greeting(){const h=new Date().getHours();return h<12?'おはようございます':h<18?'こんにちは':'こんばんは';}

// ===== Calendar Helper =====
function getCalendarDays(year, month) {
  const first = new Date(year, month, 1);
  const last = new Date(year, month + 1, 0);
  const days = [];
  const startDow = first.getDay();
  // Previous month
  for (let i = startDow - 1; i >= 0; i--) {
    const d = new Date(year, month, -i);
    days.push({ date: d, otherMonth: true });
  }
  // Current month
  for (let i = 1; i <= last.getDate(); i++) {
    days.push({ date: new Date(year, month, i), otherMonth: false });
  }
  // Next month fill
  const rem = 7 - (days.length % 7);
  if (rem < 7) {
    for (let i = 1; i <= rem; i++) {
      days.push({ date: new Date(year, month + 1, i), otherMonth: true });
    }
  }
  return days;
}

function dateToStr(d) {
  return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;
}

// ===== Components =====

function Header({ onSettings }) {
  return (
    <header className="header">
      <div className="header-logo">
        <img src="assets/logo_header.jpg" alt="ソルマーレ長崎FC" />
      </div>
      <button className="header-settings" onClick={onSettings}><I.Settings /></button>
    </header>
  );
}

function BottomNav({ active, onChange }) {
  const items = [
    { key:'home', label:'ホーム', icon:I.Home },
    { key:'schedule', label:'予定', icon:I.Calendar },
    { key:'team', label:'チーム', icon:I.Users },
    { key:'player', label:'選手', icon:I.User },
    { key:'library', label:'ライブラリ', icon:I.Book },
  ];
  return (
    <nav className="bottom-nav">
      {items.map(it=>(
        <button key={it.key} className={`nav-item ${active===it.key?'active':''}`} onClick={()=>onChange(it.key)}>
          <it.icon />{it.label}
        </button>
      ))}
    </nav>
  );
}

// --- Mini Calendar ---
function MiniCalendar({ events, onSelectDate, selectedDate }) {
  const today = new Date();
  const [year, setYear] = useState(today.getFullYear());
  const [month, setMonth] = useState(today.getMonth());
  const days = useMemo(() => getCalendarDays(year, month), [year, month]);
  const eventDates = useMemo(() => new Set(events.map(e => e.event_date)), [events]);

  const prev = () => { if (month === 0) { setYear(y=>y-1); setMonth(11); } else setMonth(m=>m-1); };
  const next = () => { if (month === 11) { setYear(y=>y+1); setMonth(0); } else setMonth(m=>m+1); };

  const todayStr = dateToStr(today);

  return (
    <div className="mini-calendar">
      <div className="cal-header">
        <button className="cal-nav" onClick={prev}><I.ChevL /></button>
        <span className="cal-month">{year}年{month+1}月</span>
        <button className="cal-nav" onClick={next}><I.ChevR /></button>
      </div>
      <div className="cal-grid">
        {DOW.map((d,i)=><div key={i} className={`cal-dow ${i===0?'sunday':''} ${i===6?'saturday':''}`}>{d}</div>)}
        {days.map((d,i)=>{
          const ds = dateToStr(d.date);
          const dow = d.date.getDay();
          let cls = 'cal-day';
          if (d.otherMonth) cls += ' other-month';
          if (dow === 0 && !d.otherMonth) cls += ' sunday';
          if (dow === 6 && !d.otherMonth) cls += ' saturday';
          if (ds === todayStr) cls += ' today';
          if (eventDates.has(ds)) cls += ' has-event';
          if (ds === selectedDate) cls += ' selected';
          return <div key={i} className={cls} onClick={()=>!d.otherMonth && onSelectDate(ds)}>{d.date.getDate()}</div>;
        })}
      </div>
    </div>
  );
}

// --- Schedule Detail ---
function ScheduleDetail({ s, onClose }) {
  const [att, setAtt] = useState(null);
  if (!s) return null;
  const { m, d, dow } = fmtDate(s.event_date);

  return (
    <div className="overlay" onClick={onClose}>
      <div className="panel" onClick={e=>e.stopPropagation()}>
        <div className="panel-handle" />
        <div className="detail-date-header">
          <span className={`schedule-badge badge-${s.category}`}>{CAT_LABELS[s.category]}</span>
          <div className="detail-date-big">{m}/{d}</div>
          <div className="detail-date-dow">{dow}曜日</div>
        </div>
        <h2 style={{fontSize:'1.05rem',fontWeight:700,marginBottom:14}}>{s.title}</h2>

        {s.start_time && <div className="detail-row"><I.Clock /><div><div className="detail-label">時間</div><div className="detail-value">{s.start_time}{s.end_time?` 〜 ${s.end_time}`:''}</div></div></div>}
        {s.location && <div className="detail-row"><I.MapPin /><div><div className="detail-label">場所</div><div className="detail-value">{s.location}</div></div></div>}
        {s.gather_time && <div className="detail-row"><I.Flag /><div><div className="detail-label">集合</div><div className="detail-value">{s.gather_time} / {s.gather_place||s.location}</div></div></div>}
        {s.opponent && <div className="detail-row"><I.Star /><div><div className="detail-label">対戦相手</div><div className="detail-value">{s.opponent}</div></div></div>}
        {s.age_group && <div className="detail-row"><I.Users /><div><div className="detail-label">カテゴリ</div><div className="detail-value">{s.age_group}</div></div></div>}
        {s.kickoff_time && <div className="detail-row"><I.Clock /><div><div className="detail-label">キックオフ</div><div className="detail-value">{s.kickoff_time}</div></div></div>}

        {s.parking_limited && (
          <div className="parking-warn">
            <I.Car />
            <div>駐車場制限あり{s.parking_limit_num?`（${s.parking_limit_num}台まで）`:''}{s.parking_note?` — ${s.parking_note}`:''}</div>
          </div>
        )}

        {s.description && (
          <div style={{marginTop:14,padding:12,background:'#f8f9fb',borderRadius:8}}>
            <div style={{fontSize:'0.75rem',color:'#6b7280',marginBottom:3}}>備考</div>
            <div style={{fontSize:'0.85rem',lineHeight:1.7,whiteSpace:'pre-wrap'}}>{s.description}</div>
          </div>
        )}

        {s.attendance && (
          <div className="att-counts" style={{marginTop:12}}>
            <span className="att-yes">◯ {s.attendance.attend}</span>
            <span className="att-no">✕ {s.attendance.absent}</span>
            <span className="att-tbd">△ {s.attendance.undecided}</span>
          </div>
        )}

        <div className="att-buttons">
          <button className={`att-btn ${att==='yes'?'sel-yes':''}`} onClick={()=>setAtt('yes')}>◯ 参加</button>
          <button className={`att-btn ${att==='no'?'sel-no':''}`} onClick={()=>setAtt('no')}>✕ 欠席</button>
          <button className={`att-btn ${att==='tbd'?'sel-tbd':''}`} onClick={()=>setAtt('tbd')}>△ 未定</button>
        </div>
      </div>
    </div>
  );
}

// --- Announcement Detail ---
function AnnouncementDetail({ a, onClose }) {
  if (!a) return null;
  const catCls = {info:'ann-info',urgent:'ann-urgent',event:'ann-event',result:'ann-result'};
  const catLabel = {info:'お知らせ',urgent:'緊急',event:'イベント',result:'結果'};
  return (
    <div className="overlay" onClick={onClose}>
      <div className="panel" onClick={e=>e.stopPropagation()}>
        <div className="panel-handle" />
        <span className={`ann-badge ${catCls[a.category]}`}>{catLabel[a.category]}</span>
        <h2 className="panel-title" style={{marginTop:6}}>{a.title}</h2>
        <div className="panel-meta"><span>{a.created_by}</span><span>{timeAgo(a.created_at)}</span></div>
        <div className="panel-content">{a.content}</div>
      </div>
    </div>
  );
}

// --- Schedule Item Row ---
function ScheduleRow({ s, onClick }) {
  const { m, d, dow } = fmtDate(s.event_date);
  return (
    <div className="schedule-item" onClick={onClick}>
      <div className={`schedule-date-box cat-${s.category}`}>
        <div className="schedule-month">{m}月</div>
        <div className="schedule-day">{d}</div>
        <div className="schedule-dow">{dow}</div>
      </div>
      <div className="schedule-info">
        <span className={`schedule-badge badge-${s.category}`}>{CAT_LABELS[s.category]}</span>
        <div className="schedule-title">{s.title}</div>
        <div className="schedule-meta">
          <I.Clock />{s.start_time||'未定'}
          {s.location && <><span style={{margin:'0 3px'}}>|</span><I.MapPin />{s.location}</>}
        </div>
        {s.attendance && (
          <div className="att-counts">
            <span className="att-yes">◯{s.attendance.attend}</span>
            <span className="att-no">✕{s.attendance.absent}</span>
            <span className="att-tbd">△{s.attendance.undecided}</span>
          </div>
        )}
      </div>
    </div>
  );
}

// ==================== PAGES ====================

// --- HOME ---
function HomePage({ onNav }) {
  const [selSch, setSelSch] = useState(null);
  const [selAnn, setSelAnn] = useState(null);
  const [calDate, setCalDate] = useState(null);

  const sorted = [...DEMO_SCHEDULES].sort((a,b)=>a.event_date.localeCompare(b.event_date));
  const nextEvent = sorted[0];
  const catLabel = {info:'お知らせ',urgent:'緊急',event:'イベント',result:'結果'};
  const catCls = {info:'ann-info',urgent:'ann-urgent',event:'ann-event',result:'ann-result'};

  const calEvents = calDate ? sorted.filter(s => s.event_date === calDate) : [];

  return (
    <div>
      <div className="home-banner">
        <div className="home-greeting">{greeting()}、永野さん</div>
        {nextEvent && <>
          <div className="home-next-label">NEXT</div>
          <div className="home-next-date">{fmtDateFull(nextEvent.event_date)} {nextEvent.start_time && nextEvent.start_time+'〜'}</div>
          <div className="home-next-title">{nextEvent.title}</div>
        </>}
      </div>

      <div className="quick-stats">
        <div className="stat-card"><div className="stat-number">{DEMO_PLAYERS.length}</div><div className="stat-label">選手</div></div>
        <div className="stat-card"><div className="stat-number">{sorted.filter(s=>s.category!=='training').length}</div><div className="stat-label">今月の試合</div></div>
        <div className="stat-card"><div className="stat-number">{DEMO_NEWS.filter(n=>n.is_pinned||n.category==='urgent').length}</div><div className="stat-label">重要</div></div>
      </div>

      {/* Calendar */}
      <MiniCalendar events={DEMO_SCHEDULES} selectedDate={calDate} onSelectDate={d => setCalDate(calDate === d ? null : d)} />

      {calDate && calEvents.length > 0 && (
        <div className="section" style={{paddingTop:0}}>
          <div className="section-title" style={{marginBottom:8,fontSize:'0.85rem'}}>{fmtDateFull(calDate)} の予定</div>
          {calEvents.map(s => <ScheduleRow key={s.id} s={s} onClick={()=>setSelSch(s)} />)}
        </div>
      )}

      {/* Upcoming */}
      <div className="section">
        <div className="section-header">
          <div className="section-title"><I.Calendar /> 直近の予定</div>
          <button className="section-more" onClick={()=>onNav('schedule')}>すべて →</button>
        </div>
        {sorted.slice(0,3).map(s => <ScheduleRow key={s.id} s={s} onClick={()=>setSelSch(s)} />)}
      </div>

      {/* News */}
      <div className="section">
        <div className="section-header">
          <div className="section-title"><I.Bell /> 新着情報</div>
        </div>
        <div className="card">
          {[...DEMO_NEWS].sort((a,b)=>{if(a.is_pinned!==b.is_pinned)return b.is_pinned?1:-1;return b.created_at.localeCompare(a.created_at);}).slice(0,3).map(a=>(
            <div key={a.id} className="announcement-item" onClick={()=>setSelAnn(a)}>
              <div className="ann-top">
                {a.is_pinned && <span className="ann-pin"><I.Pin /></span>}
                <span className={`ann-badge ${catCls[a.category]}`}>{catLabel[a.category]}</span>
              </div>
              <div className="ann-title">{a.title}</div>
              <div className="ann-footer"><span>{a.created_by}</span><span>{timeAgo(a.created_at)}</span></div>
            </div>
          ))}
        </div>
      </div>

      {selSch && <ScheduleDetail s={selSch} onClose={()=>setSelSch(null)} />}
      {selAnn && <AnnouncementDetail a={selAnn} onClose={()=>setSelAnn(null)} />}
    </div>
  );
}

// --- SCHEDULE ---
function SchedulePage() {
  const [view, setView] = useState('today');
  const [selSch, setSelSch] = useState(null);

  const today = new Date();
  const todayStr = dateToStr(today);
  const tmrw = new Date(today); tmrw.setDate(tmrw.getDate()+1);
  const tmrwStr = dateToStr(tmrw);

  const sorted = [...DEMO_SCHEDULES].sort((a,b)=>a.event_date.localeCompare(b.event_date));

  const endOfWeek = new Date(today);
  endOfWeek.setDate(endOfWeek.getDate() + (7 - endOfWeek.getDay()));
  const weekStr = dateToStr(endOfWeek);

  const endOfMonth = new Date(today.getFullYear(), today.getMonth()+1, 0);
  const monthStr = dateToStr(endOfMonth);

  let filtered;
  if (view === 'today') {
    filtered = sorted.filter(s => s.event_date === todayStr || s.event_date === tmrwStr);
  } else if (view === 'week') {
    filtered = sorted.filter(s => s.event_date >= todayStr && s.event_date <= weekStr);
  } else {
    filtered = sorted.filter(s => s.event_date >= todayStr && s.event_date <= monthStr);
  }

  return (
    <div>
      <div className="schedule-view-tabs">
        {[{k:'today',l:'今日・明日'},{k:'week',l:'週間'},{k:'month',l:'月間'}].map(t=>(
          <button key={t.k} className={`view-tab ${view===t.k?'active':''}`} onClick={()=>setView(t.k)}>{t.l}</button>
        ))}
      </div>
      <div className="section">
        {filtered.length === 0 ? (
          <div className="empty-state"><I.Calendar /><p>この期間の予定はありません</p></div>
        ) : filtered.map(s => <ScheduleRow key={s.id} s={s} onClick={()=>setSelSch(s)} />)}
      </div>
      {selSch && <ScheduleDetail s={selSch} onClose={()=>setSelSch(null)} />}
    </div>
  );
}

// --- TEAM ---
function TeamPage() {
  const [tab, setTab] = useState('players');

  return (
    <div>
      <div className="tab-bar">
        <button className={`tab-item ${tab==='players'?'active':''}`} onClick={()=>setTab('players')}>選手</button>
        <button className={`tab-item ${tab==='staff'?'active':''}`} onClick={()=>setTab('staff')}>スタッフ</button>
      </div>

      {tab === 'players' && (
        <div className="member-list">
          {[...DEMO_PLAYERS].sort((a,b)=>a.jersey_number-b.jersey_number).map(p=>(
            <div key={p.id} className="member-row">
              <div className="member-avatar">{p.last_name.charAt(0)}</div>
              <div>
                <div className="member-name">{p.last_name} {p.first_name}</div>
                <div className="member-sub">{p.grade} / {p.birth_date}</div>
              </div>
              <span className="member-number">#{p.jersey_number}</span>
            </div>
          ))}
        </div>
      )}

      {tab === 'staff' && (
        <div className="member-list">
          {DEMO_STAFF.map(s=>(
            <div key={s.id} className="member-row">
              <div className="member-avatar staff-avatar">{s.last_name.charAt(0)}</div>
              <div>
                <div className="member-name">{s.last_name} {s.first_name}</div>
                <div className="member-sub">{s.position_title}</div>
                <div className="member-sub" style={{marginTop:2}}>{s.qualifications}</div>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// --- PLAYER (my child) ---
function PlayerPage() {
  const child = DEMO_PLAYERS.find(p => p.id === 9); // 永野 ○○
  const mem = DEMO_MEMORY;

  if (!child) return <div className="empty-state"><I.User /><p>お子さまの情報が登録されていません</p></div>;

  return (
    <div>
      <div className="player-hero">
        <div className="player-hero-name">{child.last_name} {child.first_name}</div>
        <div className="player-hero-sub">{child.grade} / {child.birth_date}</div>
        <div className="player-hero-number">#{child.jersey_number}</div>
      </div>

      <div className="memory-grid">
        <div className="memory-item">
          <h4>スパイク</h4>
          <p>{mem.shoe_brand}</p>
          <p style={{fontSize:'0.7rem',color:'#6b7280'}}>{mem.shoe_size}</p>
        </div>
        <div className="memory-item">
          <h4>お気に入り補食</h4>
          <p>{mem.favorite_snack}</p>
        </div>
        <div className="memory-item highlight">
          <h4>初ゴール</h4>
          <p>{fmtDateFull(mem.first_goal_date)}</p>
        </div>
        <div className="memory-item">
          <h4>憧れの選手</h4>
          <p>{mem.favorite_player}</p>
        </div>
      </div>

      {mem.first_goal_note && (
        <div className="memory-full">
          <h4>初ゴールの思い出</h4>
          <p>{mem.first_goal_note}</p>
        </div>
      )}

      {mem.personal_best && (
        <div className="memory-full">
          <h4>自己ベスト</h4>
          <p>{mem.personal_best}</p>
        </div>
      )}

      {mem.notes && (
        <div className="memory-full">
          <h4>メモ</h4>
          <p>{mem.notes}</p>
        </div>
      )}
    </div>
  );
}

// --- LIBRARY ---
function LibraryPage() {
  const [filter, setFilter] = useState('all');

  const filtered = filter === 'all' ? DEMO_LIBRARY : DEMO_LIBRARY.filter(l => l.skill_category === filter);

  return (
    <div>
      <div className="schedule-view-tabs" style={{flexWrap:'wrap'}}>
        {[{k:'all',l:'すべて'},{k:'shoot',l:'シュート'},{k:'pass',l:'パス'},{k:'dribble',l:'ドリブル'},{k:'tactics',l:'戦術'},{k:'physical',l:'フィジカル'},{k:'gk',l:'GK'}].map(t=>(
          <button key={t.k} className={`view-tab ${filter===t.k?'active':''}`} onClick={()=>setFilter(t.k)}>{t.l}</button>
        ))}
      </div>

      {filtered.length === 0 ? (
        <div className="empty-state"><I.Book /><p>該当する動画がありません</p></div>
      ) : filtered.map(l => (
        <a key={l.id} href={l.url} target="_blank" rel="noopener noreferrer" className="library-item" style={{textDecoration:'none',color:'inherit'}}>
          <div className="library-thumb">
            <div className="play-icon"><I.Play /></div>
          </div>
          <div className="library-info">
            <div className="library-title">{l.title}</div>
            <div className="library-tags">
              <span className={`library-tag tag-${l.location_type}`}>{LOC_LABELS[l.location_type]}</span>
              <span className={`library-tag tag-${l.skill_category}`}>{SKILL_LABELS[l.skill_category]}</span>
            </div>
            <div className="library-added-by">{l.added_by}</div>
          </div>
        </a>
      ))}
    </div>
  );
}

// --- SETTINGS ---
const APP_VERSION = '2.0.0';

function SettingsPanel({ onClose }) {
  const [updating, setUpdating] = useState(false);

  const handleForceUpdate = async () => {
    setUpdating(true);
    try {
      // 1. Service Worker の全キャッシュを削除
      if ('caches' in window) {
        const keys = await caches.keys();
        await Promise.all(keys.map(key => caches.delete(key)));
      }
      // 2. Service Worker を再登録（待機中のSWがあればスキップさせる）
      if ('serviceWorker' in navigator) {
        const registrations = await navigator.serviceWorker.getRegistrations();
        await Promise.all(registrations.map(r => r.unregister()));
      }
      // 3. 強制リロード（キャッシュ無視）
      window.location.reload(true);
    } catch (e) {
      console.error('Update failed:', e);
      // フォールバック: 普通にリロード
      window.location.reload(true);
    }
  };

  return (
    <div className="overlay" onClick={onClose}>
      <div className="panel" onClick={e=>e.stopPropagation()}>
        <div className="panel-handle" />
        <h2 className="panel-title">設定</h2>
        <div className="settings-list" style={{padding:'8px 0'}}>
          <div className="settings-item"><span className="settings-item-label">アカウント情報</span><span className="settings-item-value">永野 &gt;</span></div>
          <div className="settings-item"><span className="settings-item-label">お子さま管理</span><span className="settings-item-value">1人 &gt;</span></div>
          <div className="settings-item"><span className="settings-item-label">通知設定</span><span className="settings-item-value">&gt;</span></div>
          <div className="settings-item"><span className="settings-item-label">権限</span><span className="settings-item-value">スタッフ</span></div>
          <div className="settings-item" style={{color:'#dc2626'}}><span className="settings-item-label">ログアウト</span></div>
        </div>

        <div style={{borderTop:'1px solid #e2e5ea',marginTop:8,paddingTop:16}}>
          <div style={{display:'flex',alignItems:'center',justifyContent:'space-between',marginBottom:12}}>
            <div>
              <div style={{fontSize:'0.75rem',color:'#9ca3af'}}>アプリバージョン</div>
              <div style={{fontSize:'0.9rem',fontWeight:700}}>v{APP_VERSION}</div>
            </div>
          </div>
          <button
            className="btn btn-primary btn-full"
            onClick={handleForceUpdate}
            disabled={updating}
            style={{opacity: updating ? 0.6 : 1}}
          >
            {updating ? (
              <span>更新中...</span>
            ) : (
              <><I.RefreshCw /> 最新に更新する</>
            )}
          </button>
          <div style={{fontSize:'0.65rem',color:'#9ca3af',textAlign:'center',marginTop:6}}>
            キャッシュをクリアしてページを再読み込みします
          </div>
        </div>
      </div>
    </div>
  );
}

// ==================== APP ====================
function App() {
  const [page, setPage] = useState('home');
  const [showSettings, setShowSettings] = useState(false);

  const renderPage = () => {
    switch(page) {
      case 'home': return <HomePage onNav={setPage} />;
      case 'schedule': return <SchedulePage />;
      case 'team': return <TeamPage />;
      case 'player': return <PlayerPage />;
      case 'library': return <LibraryPage />;
      default: return <HomePage onNav={setPage} />;
    }
  };

  return (
    <>
      <Header onSettings={()=>setShowSettings(true)} />
      <main className="main-content">{renderPage()}</main>
      <BottomNav active={page} onChange={setPage} />
      {showSettings && <SettingsPanel onClose={()=>setShowSettings(false)} />}
    </>
  );
}

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
