/* Events View – List / Kanban / Calendar */
(function () {
  const { useState, useMemo } = React;
  const { uid, formatDate, STATUS_LABELS, STATUS_ORDER, DELIVERY_LABELS } = window.AppStore;
  const { Modal, showToast, StatusTag, ViewSwitch, Field, StaffInput } = window.Common;

  /* ---- Concert Form Modal ---- */
  const EMPTY_EVENT = (eventId, flyerId) => ({
    id: '',
    eventId: eventId || '',
    flyerId: flyerId || '',
    eventName: '',
    date: '',
    venue: '',
    meetTime: '',
    meetPlace: '',
    deliveryMethod: 'bring',
    contactName: '',
    contactOrg: '',
    contactPhone: '',
    contactEmail: '',
    staff: [],
    quantity: 0,
    status: 'proposed',
    note: '',
    flyerLink: '',
  });

  function EventFormModal({ open, onClose, event, state, onSave, initialDate }) {
    const defaultEventId = event ? event.eventId : (state.events[0] ? state.events[0].id : '');
    const [form, setForm] = useState(() => {
      if (event) return { ...event, staff: [...(event.staff || [])] };
      const e = EMPTY_EVENT(defaultEventId, '');
      if (initialDate) e.date = initialDate;
      return e;
    });

    function set(key, val) { setForm((p) => ({ ...p, [key]: val })); }

    const selectedEvent = state.events.find((e) => e.id === form.eventId);
    const flyers = selectedEvent ? selectedEvent.flyers : [];

    function handleSave() {
      if (!form.eventName.trim()) { showToast('公演名を入力してください', 'error'); return; }
      if (!form.date) { showToast('日付を入力してください', 'error'); return; }
      if (!form.eventId) { showToast('イベントを選択してください', 'error'); return; }
      if (!form.flyerId) { showToast('チラシ種別を選択してください', 'error'); return; }
      if (!form.quantity || form.quantity <= 0) { showToast('部数を入力してください', 'error'); return; }
      const saving = { ...form };
      if (!saving.id) saving.id = uid('c');
      onSave(saving);
      onClose();
    }

    return (
      <Modal
        open={open}
        onClose={onClose}
        title={event ? 'コンサート編集' : 'コンサート追加'}
        wide
        actions={
          <>
            <button className="btn btn-secondary" onClick={onClose}>キャンセル</button>
            <button className="btn btn-primary" onClick={handleSave}>保存</button>
          </>
        }
      >
        <div className="form-grid">
          <div className="full-width">
            <Field label="挟み込み先公演名" required>
              <input value={form.eventName} onChange={(e) => set('eventName', e.target.value)} placeholder="例: ABC交響楽団定期演奏会" />
            </Field>
          </div>
          <Field label="日付" required>
            <input type="date" value={form.date} onChange={(e) => set('date', e.target.value)} />
          </Field>
          <Field label="ステータス">
            <select value={form.status} onChange={(e) => set('status', e.target.value)}>
              {STATUS_ORDER.map((s) => <option key={s} value={s}>{STATUS_LABELS[s]}</option>)}
            </select>
          </Field>
          <div className="full-width">
            <Field label="会場">
              <input value={form.venue} onChange={(e) => set('venue', e.target.value)} placeholder="例: サントリーホール" />
            </Field>
          </div>
          <Field label="集合時刻">
            <input type="time" value={form.meetTime} onChange={(e) => set('meetTime', e.target.value)} />
          </Field>
          <Field label="集合場所">
            <input value={form.meetPlace} onChange={(e) => set('meetPlace', e.target.value)} placeholder="例: 楽屋口" />
          </Field>
          <Field label="搬入方法">
            <select value={form.deliveryMethod} onChange={(e) => set('deliveryMethod', e.target.value)}>
              {Object.entries(DELIVERY_LABELS).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
            </select>
          </Field>
          <div className="full-width">
            <Field label="先方担当者">
              <div className="form-grid" style={{ gap: 8 }}>
                <input value={form.contactName} onChange={(e) => set('contactName', e.target.value)} placeholder="担当者名" />
                <input value={form.contactOrg} onChange={(e) => set('contactOrg', e.target.value)} placeholder="団体名" />
                <input value={form.contactPhone} onChange={(e) => set('contactPhone', e.target.value)} placeholder="電話番号" />
                <input value={form.contactEmail} onChange={(e) => set('contactEmail', e.target.value)} placeholder="メールアドレス" type="email" />
              </div>
            </Field>
          </div>
          <div className="full-width">
            <Field label="イベント" required>
              <select value={form.eventId} onChange={(e) => { set('eventId', e.target.value); set('flyerId', ''); }}>
                <option value="">-- 選択 --</option>
                {state.events.map((ev) => <option key={ev.id} value={ev.id}>{ev.title}</option>)}
              </select>
            </Field>
          </div>
          <Field label="チラシ種別" required>
            <select value={form.flyerId} onChange={(e) => set('flyerId', e.target.value)}>
              <option value="">-- 選択 --</option>
              {flyers.map((f) => <option key={f.id} value={f.id}>{f.name}</option>)}
            </select>
          </Field>
          <Field label="挟み込み部数" required>
            <input type="number" min="1" value={form.quantity} onChange={(e) => set('quantity', parseInt(e.target.value) || 0)} />
          </Field>
          <div className="full-width">
            <Field label="当日スタッフ">
              <StaffInput value={form.staff} onChange={(v) => set('staff', v)} />
            </Field>
          </div>
          <div className="full-width">
            <Field label="チラシPDF/URL">
              <input value={form.flyerLink} onChange={(e) => set('flyerLink', e.target.value)} placeholder="https://..." />
            </Field>
          </div>
          <div className="full-width">
            <Field label="備考">
              <textarea value={form.note} onChange={(e) => set('note', e.target.value)} rows={3} />
            </Field>
          </div>
        </div>
      </Modal>
    );
  }

  /* ---- List View ---- */
  function EventListView({ state, onEdit }) {
    const [search, setSearch] = useState('');
    const [statusFilter, setStatusFilter] = useState('');
    const [periodFilter, setPeriodFilter] = useState('');
    const [sortAsc, setSortAsc] = useState(true);

    const filtered = useMemo(() => {
      const now = new Date();
      const y = now.getFullYear();
      const m = now.getMonth();
      let evs = state.concerts.filter((c) => {
        if (statusFilter && c.status !== statusFilter) return false;
        if (search) {
          const q = search.toLowerCase();
          if (!(c.eventName.toLowerCase().includes(q) ||
            (c.venue || '').toLowerCase().includes(q) ||
            (c.staff || []).join('').toLowerCase().includes(q))) return false;
        }
        if (periodFilter === 'thisMonth') {
          const d = new Date(c.date);
          if (d.getFullYear() !== y || d.getMonth() !== m) return false;
        } else if (periodFilter === 'nextMonth') {
          const d = new Date(c.date);
          const nm = m === 11 ? 0 : m + 1;
          const ny = m === 11 ? y + 1 : y;
          if (d.getFullYear() !== ny || d.getMonth() !== nm) return false;
        } else if (periodFilter === 'past') {
          if (new Date(c.date) >= now) return false;
        }
        return true;
      });
      evs.sort((a, b) => {
        const r = a.date.localeCompare(b.date);
        return sortAsc ? r : -r;
      });
      return evs;
    }, [state.concerts, search, statusFilter, periodFilter, sortAsc]);

    function getEventTitle(eventId) {
      const ev = state.events.find((e) => e.id === eventId);
      return ev ? ev.title : '(不明)';
    }
    function getFlyerName(eventId, flyerId) {
      const ev = state.events.find((e) => e.id === eventId);
      if (!ev) return '';
      const f = ev.flyers.find((f) => f.id === flyerId);
      return f ? f.name : '';
    }

    return (
      <div>
        <div className="events-toolbar">
          <input className="search-input" placeholder="🔍 公演名・会場・スタッフで検索" value={search} onChange={(e) => setSearch(e.target.value)} />
          <select className="filter-select" value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)}>
            <option value="">全ステータス</option>
            {STATUS_ORDER.map((s) => <option key={s} value={s}>{STATUS_LABELS[s]}</option>)}
          </select>
          <select className="filter-select" value={periodFilter} onChange={(e) => setPeriodFilter(e.target.value)}>
            <option value="">全期間</option>
            <option value="thisMonth">今月</option>
            <option value="nextMonth">来月</option>
            <option value="past">過去</option>
          </select>
          <button className="btn btn-ghost btn-sm" onClick={() => setSortAsc(!sortAsc)}>
            日付 {sortAsc ? '↑' : '↓'}
          </button>
        </div>
        <div className="events-table-wrap">
          <table className="events-table">
            <thead>
              <tr>
                <th data-label="日付">日付</th>
                <th data-label="公演名">公演名</th>
                <th data-label="イベント">イベント</th>
                <th data-label="会場">会場</th>
                <th data-label="チラシ">チラシ</th>
                <th data-label="部数">部数</th>
                <th data-label="集合">集合</th>
                <th data-label="担当">担当</th>
                <th data-label="ステータス">ステータス</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {filtered.length === 0 ? (
                <tr><td colSpan="10" style={{ textAlign: 'center', color: 'var(--muted)', padding: 32 }}>該当するコンサートがありません</td></tr>
              ) : filtered.map((c) => (
                <tr key={c.id} style={{ cursor: 'pointer' }} onClick={() => onEdit(c)}>
                  <td data-label="日付">{formatDate(c.date)}</td>
                  <td data-label="公演名">{c.eventName}</td>
                  <td data-label="イベント" style={{ color: 'var(--muted)', fontSize: 12 }}>{getEventTitle(c.eventId)}</td>
                  <td data-label="会場">{c.venue}</td>
                  <td data-label="チラシ">{getFlyerName(c.eventId, c.flyerId)}</td>
                  <td data-label="部数">{c.quantity}</td>
                  <td data-label="集合">{c.meetTime ? c.meetTime + ' ' + (c.meetPlace || '') : ''}</td>
                  <td data-label="担当">{(c.staff || []).join(', ')}</td>
                  <td data-label="ステータス"><StatusTag status={c.status} /></td>
                  <td className="cell-actions" onClick={(e) => e.stopPropagation()}>
                    <button className="btn-icon cell-edit-btn" title="編集" onClick={() => onEdit(c)}>
                      ✏️<span className="cell-edit-label"> 編集</span>
                    </button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    );
  }

  /* ---- Kanban View ---- */
  function EventKanbanView({ state, onEdit }) {
    function getFlyerName(eventId, flyerId) {
      const ev = state.events.find((e) => e.id === eventId);
      if (!ev) return '';
      const f = ev.flyers.find((f) => f.id === flyerId);
      return f ? f.name : '';
    }

    return (
      <div className="kanban-wrap">
        {STATUS_ORDER.map((status) => {
          const evs = state.concerts.filter((c) => c.status === status);
          return (
            <div key={status} className="kanban-col">
              <div className="kanban-col-header">
                <span className="kanban-col-title">{STATUS_LABELS[status]}</span>
                <span className="kanban-count">{evs.length}</span>
              </div>
              {evs.length === 0 ? (
                <div style={{ fontSize: 12, color: 'var(--muted)', textAlign: 'center', padding: '12px 0' }}>なし</div>
              ) : evs.map((c) => {
                const ev = state.events.find((e) => e.id === c.eventId);
                return (
                  <div key={c.id} className="kanban-card" onClick={() => onEdit(c)}>
                    <div className="kanban-card-title">{c.eventName}</div>
                    {ev && (
                      <div style={{ fontSize: 11, color: 'var(--accent)', fontWeight: 600, marginBottom: 4 }}>
                        🎵 {ev.title}
                      </div>
                    )}
                    <div className="kanban-card-meta">
                      <span>📅 {formatDate(c.date)}</span>
                      {c.venue && <span>📍 {c.venue}</span>}
                      <span>📄 {c.quantity}部</span>
                      <span style={{ fontSize: 11, color: 'var(--muted)' }}>{getFlyerName(c.eventId, c.flyerId)}</span>
                    </div>
                  </div>
                );
              })}
            </div>
          );
        })}
      </div>
    );
  }

  /* ---- Calendar View ---- */
  function EventCalendarView({ state, onEdit, onNewEvent }) {
    const now = new Date();
    const [year, setYear] = useState(now.getFullYear());
    const [month, setMonth] = useState(now.getMonth());

    function prevMonth() {
      if (month === 0) { setYear(y => y - 1); setMonth(11); }
      else setMonth(m => m - 1);
    }
    function nextMonth() {
      if (month === 11) { setYear(y => y + 1); setMonth(0); }
      else setMonth(m => m + 1);
    }
    function goToday() { setYear(now.getFullYear()); setMonth(now.getMonth()); }

    const firstDay = new Date(year, month, 1);
    const lastDay = new Date(year, month + 1, 0);
    const startDow = firstDay.getDay(); // 0=Sun
    const daysInMonth = lastDay.getDate();

    // Build calendar cells
    const cells = [];
    for (let i = 0; i < startDow; i++) {
      const d = new Date(year, month, -startDow + i + 1);
      cells.push({ date: d, current: false });
    }
    for (let d = 1; d <= daysInMonth; d++) {
      cells.push({ date: new Date(year, month, d), current: true });
    }
    while (cells.length % 7 !== 0) {
      const d = new Date(year, month + 1, cells.length - (startDow + daysInMonth) + 1);
      cells.push({ date: d, current: false });
    }

    function pad(n) { return String(n).padStart(2, '0'); }
    function dateKey(d) { return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()); }

    const concertsByDate = useMemo(() => {
      const map = {};
      state.concerts.forEach((c) => {
        if (!map[c.date]) map[c.date] = [];
        map[c.date].push(c);
      });
      return map;
    }, [state.concerts]);

    const todayKey = dateKey(now);
    const DAYS = ['日', '月', '火', '水', '木', '金', '土'];

    return (
      <div>
        <div className="cal-header">
          <button className="btn btn-secondary btn-sm" onClick={prevMonth}>‹ 前月</button>
          <button className="btn btn-ghost btn-sm" onClick={goToday}>今月</button>
          <span className="cal-month-label">{year}年{month + 1}月</span>
          <button className="btn btn-secondary btn-sm" onClick={nextMonth}>次月 ›</button>
        </div>
        <div className="cal-grid">
          <div className="cal-days-header">
            {DAYS.map((d, i) => (
              <div key={i} className="cal-day-label" style={{ color: i === 0 ? 'var(--danger)' : i === 6 ? '#3b82f6' : '' }}>{d}</div>
            ))}
          </div>
          <div className="cal-body">
            {cells.map((cell, i) => {
              const key = dateKey(cell.date);
              const evs = concertsByDate[key] || [];
              const visible = evs.slice(0, 3);
              const extra = evs.length - 3;
              const isToday = key === todayKey;
              return (
                <div
                  key={i}
                  className={'cal-cell' + (!cell.current ? ' other-month' : '') + (isToday ? ' today' : '')}
                  onClick={() => cell.current && onNewEvent(key)}
                >
                  <span className="cal-date">{cell.date.getDate()}</span>
                  {visible.map((c) => (
                    <span
                      key={c.id}
                      className={'cal-event-badge ' + c.status}
                      onClick={(e) => { e.stopPropagation(); onEdit(c); }}
                      title={c.eventName}
                    >
                      {c.eventName}
                    </span>
                  ))}
                  {extra > 0 && <span className="cal-more">+{extra} 件</span>}
                </div>
              );
            })}
          </div>
        </div>
      </div>
    );
  }

  /* ---- EventsView (Root) ---- */
  function EventsView({ state, onChange, viewMode, onViewModeChange }) {
    const [modalOpen, setModalOpen] = useState(false);
    const [editingEvent, setEditingEvent] = useState(null);
    const [initialDate, setInitialDate] = useState('');
    const [confirmDelete, setConfirmDelete] = useState(null);
    const [eventFilter, setEventFilter] = useState('');

    // state.concertsをイベントフィルターで絞り込んだ派生state
    const filteredState = useMemo(() => {
      if (!eventFilter) return state;
      return { ...state, concerts: state.concerts.filter((c) => c.eventId === eventFilter) };
    }, [state, eventFilter]);

    function openNew(date) {
      setEditingEvent(null);
      setInitialDate(date || '');
      setModalOpen(true);
    }

    function openEdit(c) {
      setEditingEvent(c);
      setInitialDate('');
      setModalOpen(true);
    }

    function handleSave(c) {
      const concerts = state.concerts.find((x) => x.id === c.id)
        ? state.concerts.map((x) => x.id === c.id ? c : x)
        : [...state.concerts, c];
      onChange({ ...state, concerts });
      showToast('保存しました', 'success');
    }

    function handleDelete(id) {
      onChange({ ...state, concerts: state.concerts.filter((c) => c.id !== id) });
      setConfirmDelete(null);
      setModalOpen(false);
      showToast('削除しました');
    }

    const VIEW_OPTIONS = [
      { value: 'list', label: '📋 リスト' },
      { value: 'kanban', label: '🗂 カンバン' },
      { value: 'calendar', label: '📅 カレンダー' },
    ];

    return (
      <div>
        <div className="page-header">
          <h1 className="page-title">コンサート管理</h1>
          <div style={{ display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap' }}>
            <ViewSwitch value={viewMode} onChange={onViewModeChange} options={VIEW_OPTIONS} />
            <button className="btn btn-primary" onClick={() => openNew('')}>+ コンサート追加</button>
          </div>
        </div>

        {/* イベントフィルター */}
        <div style={{ marginBottom: 16, display: 'flex', alignItems: 'center', gap: 10 }}>
          <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--muted)', whiteSpace: 'nowrap' }}>🎵 イベント:</span>
          <select
            value={eventFilter}
            onChange={(e) => setEventFilter(e.target.value)}
            style={{ width: 'auto', minWidth: 200, maxWidth: 360 }}
          >
            <option value="">すべてのイベント</option>
            {state.events.map((ev) => (
              <option key={ev.id} value={ev.id}>{ev.title}</option>
            ))}
          </select>
          {eventFilter && (
            <button className="btn btn-ghost btn-sm" onClick={() => setEventFilter('')}>✕ 解除</button>
          )}
          {eventFilter && (
            <span style={{ fontSize: 12, color: 'var(--muted)' }}>
              {filteredState.concerts.length} 件
            </span>
          )}
        </div>

        {viewMode === 'list' && <EventListView state={filteredState} onEdit={openEdit} />}
        {viewMode === 'kanban' && <EventKanbanView state={filteredState} onEdit={openEdit} />}
        {viewMode === 'calendar' && <EventCalendarView state={filteredState} onEdit={openEdit} onNewEvent={openNew} />}

        {/* CSV export */}
        <div style={{ marginTop: 20, display: 'flex', gap: 10 }}>
          <button className="btn btn-secondary btn-sm" onClick={() => {
            const { downloadCSV, DELIVERY_LABELS } = window.AppStore;
            const rows = filteredState.concerts.map((c) => {
              const ev = state.events.find((e) => e.id === c.eventId);
              const f = ev?.flyers.find((fl) => fl.id === c.flyerId);
              return {
                日付: c.date,
                公演名: c.eventName,
                会場: c.venue,
                イベント: ev?.title || '',
                チラシ: f?.name || '',
                部数: c.quantity,
                ステータス: window.AppStore.STATUS_LABELS[c.status] || c.status,
                搬入方法: DELIVERY_LABELS[c.deliveryMethod] || '',
                集合時刻: c.meetTime,
                集合場所: c.meetPlace,
                担当者名: c.contactName,
                担当団体: c.contactOrg,
                電話: c.contactPhone,
                メール: c.contactEmail,
                スタッフ: (c.staff || []).join('・'),
                備考: c.note,
              };
            });
            const today = new Date();
            const fname = 'concerts-' + today.getFullYear() + String(today.getMonth() + 1).padStart(2, '0') + String(today.getDate()).padStart(2, '0') + '.csv';
            downloadCSV(fname, rows);
          }}>📥 CSVエクスポート</button>
        </div>

        {modalOpen && (
          <EventFormModal
            open={modalOpen}
            onClose={() => setModalOpen(false)}
            event={editingEvent}
            state={state}
            onSave={handleSave}
            initialDate={initialDate}
          />
        )}

        <Modal
          open={!!confirmDelete}
          onClose={() => setConfirmDelete(null)}
          title="コンサート削除"
          actions={
            <>
              <button className="btn btn-secondary" onClick={() => setConfirmDelete(null)}>キャンセル</button>
              <button className="btn btn-danger" onClick={() => handleDelete(confirmDelete.id)}>削除する</button>
            </>
          }
        >
          <p>「{confirmDelete?.eventName}」を削除します。よろしいですか？</p>
        </Modal>
      </div>
    );
  }

  window.EventsView = { EventsView };
})();
