// --- 依存関係のフォールバック (プレビュー環境でのクラッシュ回避用) ---
if (typeof window !== 'undefined') {
    if (!window.React) { window.React = { useState: () => [null, ()=>{}], useEffect: ()=>{}, useMemo: (f)=>f() }; }
    if (!window.Icons) {
        window.Icons = new Proxy({}, { get: () => function DummyIcon(props) { return window.React.createElement('span', {style:{display:'inline-block', width:'1em', height:'1em', backgroundColor:'#4b5563', borderRadius:'50%'}}, ''); } });
    }
    if (!window.getCourseDisplay) window.getCourseDisplay = c => c === '30min' ? '30分' : (c === '60min' ? '60分' : c);
    if (!window.getCourseShortDisplay) window.getCourseShortDisplay = c => c === '30min' ? '30分' : (c === '60min' ? '60分' : c);
    if (!window.fetchApi) window.fetchApi = async () => ({ success: true });
}

const { useState, useEffect, useMemo } = window.React;
const Icons = window.Icons;
const getCourseDisplay = window.getCourseDisplay;
const getCourseShortDisplay = window.getCourseShortDisplay;
const fetchApi = window.fetchApi;

// --- ユーティリティ ---
const checkIsAdmin = (user) => { return user && (String(user.is_admin) === '1' || user.is_admin === true); };
const CONSULTATION_METHODS = ['電話', 'LINE', 'Zoom', 'Google Meet', 'Skype', 'FaceTime', 'Teams'];


// --- トースト通知コンポーネント (UI改善) ---
const Toast = ({ message, type = 'success', onClose }) => {
    useEffect(() => {
        const timer = setTimeout(onClose, 3000);
        return () => clearTimeout(timer);
    }, [onClose]);

    return (
        <div className={`fixed top-20 right-4 z-[9999] px-6 py-4 rounded-xl shadow-2xl font-bold tracking-widest text-sm flex items-center gap-3 animate-slide-down ${
            type === 'success' ? 'bg-green-600 text-white border border-green-500' : 'bg-red-600 text-white border border-red-500'
        }`}>
            {type === 'success' ? <Icons.Sparkles className="w-5 h-5"/> : <Icons.X className="w-5 h-5"/>}
            {message}
        </div>
    );
};

// --- 各種管理コンポーネント ---

const TellerForm = ({ initialData, onSave, onClose, isAdmin, showToast }) => {
    const [activeTab, setActiveTab] = useState('basic');
    const defaultForm = { name: '', role: '', description: '', image_url: '', personal_url: '', twitter_url: '', instagram_url: '', work_start_time: '10:00', work_end_time: '19:00', userid: '', password: '', email: '', is_admin: 0, is_visible: 1, available_methods: '', connection_metadata: '{}', real_name: '', kana_name: '', private_birth_date: '', zip_code: '', address: '', note: '', color: 'purple', price_30min: 5000, price_60min: 9000, price_extend10min: 1500, commission_rate: 60 };
    const [form, setForm] = useState(() => initialData ? { ...defaultForm, ...initialData, password: '' } : defaultForm);
    const [selectedMethods, setSelectedMethods] = useState([]);
    const [connectData, setConnectData] = useState({});

    useEffect(() => { 
        if (form.available_methods) setSelectedMethods(form.available_methods.split(',').filter(Boolean)); 
        if (form.connection_metadata) { try { setConnectData(typeof form.connection_metadata === 'string' ? JSON.parse(form.connection_metadata) : form.connection_metadata); } catch(e) { setConnectData({}); } }
    }, []);

    const handleMethodToggle = (method) => { let newMethods = selectedMethods.includes(method) ? selectedMethods.filter(m => m !== method) : [...selectedMethods, method]; setSelectedMethods(newMethods); setForm(prev => ({ ...prev, available_methods: newMethods.join(',') })); };
    const handleConnectDataChange = (method, value) => { const newData = { ...connectData, [method]: value }; setConnectData(newData); setForm(prev => ({ ...prev, connection_metadata: JSON.stringify(newData) })); };
    const handleImageChange = (e) => { const file = e.target.files[0]; if (file) { const reader = new FileReader(); reader.onloadend = () => setForm({...form, image_url: reader.result}); reader.readAsDataURL(file); } };

    const themeColors = [
        { id: 'purple', class: 'bg-purple-600', shadow: 'shadow-purple-500/50' }, { id: 'blue', class: 'bg-blue-600', shadow: 'shadow-blue-500/50' },
        { id: 'red', class: 'bg-red-600', shadow: 'shadow-red-500/50' }, { id: 'green', class: 'bg-green-600', shadow: 'shadow-green-500/50' },
        { id: 'gray', class: 'bg-gray-600', shadow: 'shadow-gray-500/50' },
    ];

    const inputClass = "w-full bg-gray-900/80 border border-gray-700 rounded-xl p-3 text-white focus:border-yellow-500 focus:bg-gray-900 focus:ring-2 focus:ring-yellow-500/20 outline-none transition-all duration-300 placeholder-gray-600";
    const labelClass = "text-xs text-gray-400 font-bold mb-1.5 block tracking-widest";

    return (
        <div className="fixed inset-0 bg-black/90 backdrop-blur-sm flex items-end md:items-center justify-center z-[100] p-0 md:p-4 admin-theme transition-opacity duration-300">
            <div className="bg-gray-850 w-full h-[95vh] md:h-[90vh] md:max-w-3xl md:rounded-2xl rounded-t-3xl border-t md:border border-gray-700 shadow-2xl flex flex-col animate-slide-down overflow-hidden relative">
                <div className="flex justify-between items-center p-5 md:p-6 border-b border-gray-700 shrink-0 bg-gray-900 relative">
                    <div className="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-yellow-600 to-yellow-400"></div>
                    <div className="flex items-center gap-3">
                        <div className="w-10 h-10 rounded-full bg-gray-800 border border-gray-700 flex items-center justify-center text-yellow-500 shadow-inner"><Icons.User className="w-5 h-5"/></div>
                        <div>
                            <h3 className="font-bold text-lg md:text-xl text-white tracking-widest">{initialData ? 'プロフィール編集' : '新規鑑定師の登録'}</h3>
                            <span className="text-[10px] text-gray-500 font-mono">{initialData ? `ID: ${form.userid}` : 'New Profile'}</span>
                        </div>
                    </div>
                    <button onClick={onClose} className="text-gray-400 hover:text-white hover:bg-gray-800 p-2 rounded-full transition-all w-10 h-10 flex items-center justify-center"><Icons.X className="w-6 h-6"/></button>
                </div>

                <div className="flex border-b border-gray-700 shrink-0 overflow-x-auto bg-gray-900/50 custom-scrollbar px-2 relative">
                    {['basic', 'methods', ...(isAdmin ? ['internal'] : [])].map(tab => (
                        <button key={tab} type="button" onClick={() => setActiveTab(tab)} className={`relative flex-1 py-4 text-sm font-bold whitespace-nowrap px-6 transition-all duration-300 mx-1 ${activeTab === tab ? 'text-yellow-400 bg-gray-800/50' : 'text-gray-500 hover:text-gray-300 hover:bg-gray-800/30'}`}>
                            {tab === 'basic' ? '基本設定' : tab === 'methods' ? '接続設定' : '内部情報 (管理者用)'}
                            {activeTab === tab && <div className="absolute bottom-0 left-0 w-full h-0.5 bg-yellow-400 shadow-[0_0_8px_rgba(250,204,21,0.8)]"></div>}
                        </button>
                    ))}
                </div>

                <div className="flex-1 overflow-y-auto custom-scrollbar bg-gray-850 pb-24">
                    <div className="p-5 md:p-8 space-y-8">
                        {activeTab === 'basic' && (
                            <div className="space-y-8 animate-fade-in max-w-2xl mx-auto">
                                {isAdmin && (
                                    <label className="flex items-center gap-4 bg-gray-900/80 p-5 rounded-2xl border border-gray-700 cursor-pointer hover:border-gray-500 transition-all duration-300">
                                        <div className="relative">
                                            <input type="checkbox" checked={parseInt(form.is_visible) === 1} onChange={e => setForm({...form, is_visible: e.target.checked ? 1 : 0})} className="sr-only peer" />
                                            <div className="w-11 h-6 bg-gray-700 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-green-500 shadow-inner"></div>
                                        </div>
                                        <div>
                                            <span className="font-bold text-white tracking-widest block">サイトに公開する</span>
                                            <span className="text-xs text-gray-500">チェックを外すと、お客様側のリストに表示されなくなります</span>
                                        </div>
                                    </label>
                                )}
                                
                                <div className="flex flex-col md:flex-row gap-8">
                                    <div className="shrink-0 flex flex-col items-center">
                                        <div className="relative group">
                                            <div className="w-32 h-32 md:w-40 md:h-40 rounded-full border-4 border-gray-700 overflow-hidden bg-gray-900 flex items-center justify-center shadow-xl">
                                                {form.image_url ? <img src={form.image_url} className="w-full h-full object-cover" /> : <Icons.User className="w-16 h-16 text-gray-600" />}
                                            </div>
                                            <label className="absolute bottom-0 right-0 w-10 h-10 bg-yellow-600 hover:bg-yellow-500 rounded-full flex items-center justify-center cursor-pointer shadow-lg border-2 border-gray-850 transition-transform hover:scale-110">
                                                <Icons.PenTool className="w-5 h-5 text-white" />
                                                <input type="file" onChange={handleImageChange} className="hidden" accept="image/*" />
                                            </label>
                                        </div>
                                        <p className="text-[10px] text-gray-500 mt-3 font-bold tracking-widest">プロフィール画像</p>
                                    </div>

                                    <div className="flex-1 space-y-5">
                                        <div><label className={labelClass}>表示名 *</label><input required className={inputClass} value={form.name} onChange={e => setForm({...form, name: e.target.value})} placeholder="例: 阿弥 (Ami)" /></div>
                                        <div><label className={labelClass}>肩書き・占術 *</label><input required className={inputClass} value={form.role} onChange={e => setForm({...form, role: e.target.value})} placeholder="例: タロット占い師" /></div>
                                        <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                                            <div><label className={labelClass}>料金 (30分) *</label><input type="number" required className={inputClass} value={form.price_30min} onChange={e => setForm({...form, price_30min: parseInt(e.target.value) || 0})} /></div>
                                            <div><label className={labelClass}>料金 (60分) *</label><input type="number" required className={inputClass} value={form.price_60min} onChange={e => setForm({...form, price_60min: parseInt(e.target.value) || 0})} /></div>
                                            <div><label className={labelClass}>料金 (延長10分) *</label><input type="number" required className={inputClass} value={form.price_extend10min} onChange={e => setForm({...form, price_extend10min: parseInt(e.target.value) || 0})} /></div>
                                        </div>
                                        <div>
                                            <label className={labelClass}>テーマカラー</label>
                                            <div className="flex gap-3 bg-gray-900/80 p-3 rounded-xl border border-gray-700">
                                                {themeColors.map(color => (
                                                    <button key={color.id} type="button" onClick={() => setForm({...form, color: color.id})} className={`w-8 h-8 rounded-full ${color.class} transition-all duration-300 ${form.color === color.id ? `ring-4 ring-gray-850 outline outline-2 outline-${color.id}-500 shadow-lg scale-110` : 'opacity-50 hover:opacity-100 hover:scale-110'}`} title={color.id} />
                                                ))}
                                            </div>
                                        </div>
                                    </div>
                                </div>

                                <div><label className={labelClass}>紹介文・メッセージ</label><textarea className={`${inputClass} h-32 resize-y`} value={form.description} onChange={e => setForm({...form, description: e.target.value})} placeholder="お客様へのメッセージなど..."></textarea></div>

                                <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
                                    <div className="bg-gray-900/50 p-5 rounded-2xl border border-gray-700/50 space-y-4">
                                        <h4 className="text-sm font-bold text-gray-300 flex items-center gap-2 border-b border-gray-700 pb-2 mb-4"><Icons.Cards className="w-4 h-4 text-gray-400"/> 外部リンク</h4>
                                        <div><label className={labelClass}>個人サイトURL</label><input className={inputClass} value={form.personal_url || ''} onChange={e => setForm({...form, personal_url: e.target.value})} placeholder="https://..." /></div>
                                        <div><label className={labelClass}>X (Twitter)</label><input className={inputClass} value={form.twitter_url || ''} onChange={e => setForm({...form, twitter_url: e.target.value})} placeholder="https://twitter.com/..." /></div>
                                        <div><label className={labelClass}>Instagram</label><input className={inputClass} value={form.instagram_url || ''} onChange={e => setForm({...form, instagram_url: e.target.value})} placeholder="https://instagram.com/..." /></div>
                                    </div>
                                    
                                    <div className="bg-gray-900/50 p-5 rounded-2xl border border-gray-700/50 space-y-4">
                                        <h4 className="text-sm font-bold text-gray-300 flex items-center gap-2 border-b border-gray-700 pb-2 mb-4"><Icons.Shield className="w-4 h-4 text-gray-400"/> システム設定</h4>
                                        <div><label className={labelClass}>ログインID *</label><input required disabled={!isAdmin && initialData} className={`${inputClass} ${!isAdmin && initialData ? 'opacity-50 cursor-not-allowed' : ''}`} value={form.userid} onChange={e => setForm({...form, userid: e.target.value})} /></div>
                                        <div><label className={labelClass}>パスワード {initialData && '(変更時のみ)'}</label><input type={initialData ? "text" : "password"} required={!initialData} className={inputClass} value={form.password} onChange={e => setForm({...form, password: e.target.value})} placeholder={initialData ? "********" : "パスワードを入力"} /></div>
                                        <div><label className={labelClass}>通知用メールアドレス</label><input type="email" className={inputClass} value={form.email} onChange={e => setForm({...form, email: e.target.value})} placeholder="通知を受け取るアドレス" /></div>
                                    </div>
                                </div>

                                <div className="bg-gradient-to-r from-gray-900 to-gray-800 p-5 rounded-2xl border border-gray-700">
                                    <h4 className="text-sm font-bold text-gray-300 flex items-center gap-2 mb-4"><Icons.Clock className="w-4 h-4 text-gray-400"/> 稼働時間 (予約枠の生成基準)</h4>
                                    <div className="flex items-center gap-4 bg-gray-950 p-3 rounded-xl border border-gray-800 shadow-inner">
                                        <input type="time" className="flex-1 bg-transparent border-none text-white focus:ring-0 text-center font-bold text-lg outline-none" value={form.work_start_time?.substring(0,5)} onChange={e => setForm({...form, work_start_time: e.target.value})} />
                                        <span className="text-gray-500 font-bold">〜</span>
                                        <input type="time" className="flex-1 bg-transparent border-none text-white focus:ring-0 text-center font-bold text-lg outline-none" value={form.work_end_time?.substring(0,5)} onChange={e => setForm({...form, work_end_time: e.target.value})} />
                                    </div>
                                </div>
                            </div>
                        )}

                        {activeTab === 'methods' && (
                            <div className="space-y-6 animate-fade-in max-w-2xl mx-auto">
                                <div className="bg-blue-900/20 p-5 rounded-2xl border border-blue-800/50 flex items-start gap-4">
                                    <Icons.MessageCircle className="w-6 h-6 text-blue-400 shrink-0 mt-0.5" />
                                    <div className="text-sm text-blue-200 leading-relaxed">
                                        <p className="font-bold mb-1 text-blue-300">お客様との対話方法を設定します。</p>
                                        チェックを入れた項目が、お客様の予約画面で選択可能になります。各ツールで使用する「あなたのIDやURL」を入力しておくと、支払いが完了したお客様へ自動で送信されます。
                                    </div>
                                </div>
                                <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                    {['電話', 'LINE', 'Zoom', 'Google Meet', 'Skype', 'FaceTime', 'Teams'].map(m => (
                                        <div key={m} className={`relative p-5 rounded-2xl border-2 transition-all duration-300 ${selectedMethods.includes(m) ? 'bg-gray-800 border-blue-500 shadow-[0_0_15px_rgba(59,130,246,0.15)]' : 'bg-gray-900/50 border-gray-700'}`}>
                                            <label className="flex items-center justify-between cursor-pointer group">
                                                <span className={`font-bold tracking-widest text-sm ${selectedMethods.includes(m) ? 'text-white' : 'text-gray-400'}`}>{m}</span>
                                                <div className="relative">
                                                    <input type="checkbox" checked={selectedMethods.includes(m)} onChange={() => handleMethodToggle(m)} className="sr-only peer" />
                                                    <div className="w-10 h-5 bg-gray-700 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all duration-300 peer-checked:bg-blue-500"></div>
                                                </div>
                                            </label>
                                            {selectedMethods.includes(m) && (
                                                <div className="mt-4 animate-slide-down">
                                                    <input className="w-full bg-gray-950 border border-gray-600 rounded-lg p-3 text-sm text-white outline-none focus:border-blue-400" placeholder="接続用URL、ID、電話番号など" value={connectData[m] || ''} onChange={(e) => handleConnectDataChange(m, e.target.value)} />
                                                </div>
                                            )}
                                        </div>
                                    ))}
                                </div>
                            </div>
                        )}

                        {activeTab === 'internal' && isAdmin && (
                            <div className="space-y-6 animate-fade-in max-w-2xl mx-auto">
                                <div className="bg-green-900/20 p-5 rounded-2xl border border-green-800/50 flex items-start gap-4">
                                    <Icons.Shield className="w-6 h-6 text-green-400 shrink-0 mt-0.5" />
                                    <div className="text-sm text-green-200 leading-relaxed">
                                        <p className="font-bold mb-1 text-green-300">管理者専用の機密情報です。</p>
                                        このタブに入力された情報はサイト上に公開されず、業務連絡用の情報として厳重に管理されます。
                                    </div>
                                </div>
                                <div className="bg-gray-900/50 p-6 rounded-2xl border border-gray-700/50 space-y-5">
                                    <div className="grid grid-cols-1 md:grid-cols-2 gap-5">
                                        <div><label className={labelClass}>本名 (氏名)</label><input className={inputClass} value={form.real_name || ''} onChange={e => setForm({...form, real_name: e.target.value})} placeholder="山田 花子" /></div>
                                        <div><label className={labelClass}>フリガナ</label><input className={inputClass} value={form.kana_name || ''} onChange={e => setForm({...form, kana_name: e.target.value})} placeholder="ヤマダ ハナコ" /></div>
                                        <div><label className={labelClass}>生年月日</label><input type="date" className={inputClass} value={form.private_birth_date || ''} onChange={e => setForm({...form, private_birth_date: e.target.value})} /></div>
                                        <div><label className={labelClass}>住所</label><input className={inputClass} value={form.address || ''} onChange={e => setForm({...form, address: e.target.value})} placeholder="東京都..." /></div>
                                    </div>
                                    <div><label className={labelClass}>管理者用メモ・備考</label><textarea className={`${inputClass} h-32 resize-none`} value={form.note || ''} onChange={e => setForm({...form, note: e.target.value})} placeholder="契約条件や振込先情報など"></textarea></div>
                                </div>
                                <div className="bg-gray-900/50 p-6 rounded-2xl border border-gray-700/50 space-y-5">
                                    <h4 className="text-sm font-bold text-gray-300 flex items-center gap-2 border-b border-gray-700 pb-2"><Icons.CreditCard className="w-4 h-4 text-green-400"/> 報酬（歩合）設定</h4>
                                    <div className="w-1/2">
                                        <label className={labelClass}>占い師への還元率 (%)</label>
                                        <div className="flex items-center gap-3"><input type="number" min="0" max="100" className={inputClass} value={form.commission_rate} onChange={e => setForm({...form, commission_rate: parseInt(e.target.value) || 0})} placeholder="60" /><span className="text-white font-bold">%</span></div>
                                    </div>
                                </div>
                            </div>
                        )}
                    </div>
                </div>
                
                {/* 【改善】保存ボタン領域を最下部にSticky固定 */}
                <div className="absolute bottom-0 left-0 w-full p-4 md:p-5 bg-gray-900/95 backdrop-blur-md border-t border-gray-700 flex gap-4 items-center justify-end z-20 shadow-[0_-10px_30px_rgba(0,0,0,0.5)]">
                    <button type="button" onClick={onClose} className="px-6 py-3.5 text-gray-400 hover:text-white font-bold tracking-widest transition-all rounded-xl hover:bg-gray-800">キャンセル</button>
                    <button onClick={() => { onSave(form); showToast('鑑定師情報を保存しました'); }} className="bg-gradient-to-r from-yellow-600 to-yellow-500 hover:from-yellow-500 hover:to-yellow-400 text-gray-900 font-black px-10 py-3.5 rounded-xl shadow-[0_0_20px_rgba(234,179,8,0.3)] hover:-translate-y-0.5 active:scale-95 transition-all tracking-widest text-sm md:text-base flex items-center gap-2">
                        <Icons.Refresh className="w-5 h-5"/>
                        {initialData ? 'この内容で更新する' : '新規登録して保存'}
                    </button>
                </div>
            </div>
        </div>
    );
};

const AdminTellers = ({ tellers, onEdit, onToggleVisibility, onAddNew }) => (
    <div className="space-y-6 admin-theme pb-20 md:pb-0 animate-fade-in">
        <div className="flex justify-between items-center bg-gray-800 p-4 rounded-xl border border-gray-700 shadow-md">
            <h3 className="font-bold text-white md:text-lg flex items-center gap-2"><Icons.User className="w-5 h-5 text-yellow-500"/>鑑定師管理</h3>
            <button onClick={onAddNew} className="bg-yellow-600 hover:bg-yellow-500 text-white text-xs md:text-sm font-bold px-4 py-2.5 rounded-lg shadow-[0_0_15px_rgba(234,179,8,0.3)] transition-all flex items-center gap-2 active:scale-95 hover:-translate-y-0.5"><Icons.Plus className="w-4 h-4"/> <span>新規追加</span></button>
        </div>
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 md:gap-6">
            {tellers.map(t => (
                <div key={t.id} className="bg-gray-800 p-5 rounded-xl border border-gray-700 flex flex-col shadow-sm hover:shadow-[0_8px_30px_rgba(0,0,0,0.5)] hover:border-gray-500 hover:-translate-y-1 transition-all duration-300 relative overflow-hidden group">
                    <div className="flex gap-4 items-center mb-4 relative z-10">
                        {t.image_url ? (
                            <img src={t.image_url} alt={t.name} className="w-16 h-16 md:w-20 md:h-20 rounded-full object-cover border-2 border-gray-600 shrink-0 shadow-inner group-hover:border-yellow-500/50 transition-colors" />
                        ) : (
                            <div className="w-16 h-16 md:w-20 md:h-20 rounded-full bg-gray-700 flex items-center justify-center text-gray-400 border-2 border-gray-600 shrink-0 shadow-inner group-hover:border-yellow-500/50 transition-colors"><Icons.User className="w-8 h-8"/></div>
                        )}
                        <div className="flex-1 min-w-0"><h4 className="font-bold text-white truncate text-lg md:text-xl font-mincho group-hover:text-yellow-400 transition-colors">{t.name}</h4><p className="text-xs md:text-sm text-yellow-500 font-bold truncate mt-1">{t.role}</p></div>
                    </div>
                    <div className="text-xs md:text-sm text-gray-400 mb-5 line-clamp-2 flex-1 relative z-10 group-hover:text-gray-300">{t.description}</div>
                    <div className="flex justify-between items-center mt-auto pt-4 border-t border-gray-700 relative z-10">
                        <button onClick={() => onToggleVisibility(t.id, t.is_visible)} className={`text-[10px] md:text-xs px-3 py-1.5 rounded-md border font-bold transition-all ${parseInt(t.is_visible) ? 'bg-green-900/50 text-green-400 border-green-800 hover:bg-green-900/80 shadow-[0_0_10px_rgba(34,197,94,0.1)]' : 'bg-gray-700 text-gray-400 border-gray-600 hover:bg-gray-600'}`}>{parseInt(t.is_visible) ? '公開中' : '非公開'}</button>
                        <button onClick={() => onEdit(t)} className="text-xs md:text-sm bg-blue-900/30 hover:bg-blue-900/60 text-blue-300 px-6 py-2 rounded-md border border-blue-800/50 hover:border-blue-500 font-bold transition-all flex items-center gap-2 active:scale-95"><Icons.PenTool className="w-3 h-3"/> 編集</button>
                    </div>
                </div>
            ))}
        </div>
    </div>
);

// 【復活させたBookingModalコンポーネント】
const AdminBookingModal = ({ booking, teller, onClose, onUpdateStatus, onRequestExtension }) => {
    if (!booking) return null;
    const extendPrice = teller?.price_extend10min || 1500;

    return (
        <div className="fixed inset-0 bg-black/80 backdrop-blur-sm flex items-center justify-center z-[100] p-4 transition-opacity duration-300">
            <div className="bg-gray-850 rounded-2xl border border-gray-700 shadow-2xl w-full max-w-md text-white overflow-hidden animate-slide-down">
                <div className="p-5 border-b border-gray-700 flex justify-between items-center bg-gray-900 relative">
                    <div className="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-blue-600 to-blue-400"></div>
                    <h3 className="font-bold tracking-widest flex items-center gap-2"><Icons.Calendar className="w-5 h-5 text-blue-400"/> 予約詳細</h3>
                    <button onClick={onClose} className="text-gray-400 hover:text-white text-xl leading-none w-8 h-8 flex items-center justify-center rounded-full hover:bg-gray-800 transition-colors">&times;</button>
                </div>
                <div className="p-6 space-y-6">
                    <div className="bg-gray-900/50 p-4 rounded-xl border border-gray-700/50">
                        <div className="mb-4"><div className="text-gray-400 text-xs font-bold tracking-widest mb-1">予約日時</div><div className="text-xl font-bold text-yellow-400 font-mincho drop-shadow-md">{booking.booking_date}</div></div>
                        <div className="mb-4"><div className="text-gray-400 text-xs font-bold tracking-widest mb-1">お客様情報</div><div className="font-bold text-white">{booking.user_name} <span className="text-xs text-gray-500 font-normal ml-2">{booking.user_email}</span></div></div>
                        <div><div className="text-gray-400 text-xs font-bold tracking-widest mb-1">コースと料金</div><div className="font-bold text-white">{getCourseDisplay(booking.course)} <span className="text-yellow-500 ml-2">¥{booking.final_price?.toLocaleString()}</span></div></div>
                    </div>

                    <div className={`p-4 rounded-xl border ${booking.status === 'paid' || booking.status === 'completed' ? 'bg-green-900/20 border-green-700/50' : booking.status === 'confirmed' ? 'bg-pink-900/20 border-pink-700/50' : 'bg-gray-900/50 border-gray-700/50'}`}>
                        <div className="text-gray-400 text-xs font-bold tracking-widest mb-3 flex items-center gap-2">
                            <Icons.CreditCard className="w-4 h-4"/> 決済ステータス
                        </div>
                        {booking.status === 'paid' || booking.status === 'completed' ? (
                            <div>
                                <div className="flex items-center gap-3 mb-3">
                                    <span className="w-8 h-8 rounded-full bg-green-500 flex items-center justify-center text-white text-sm font-bold shadow-[0_0_12px_rgba(34,197,94,0.5)]">✓</span>
                                    <div>
                                        <div className="text-green-400 font-bold text-sm">お支払い完了</div>
                                        <div className="text-gray-400 text-[10px]">鑑定を開始できます</div>
                                    </div>
                                </div>
                                <div className="bg-black/30 p-3 rounded-lg text-xs space-y-1.5 border border-gray-700/30">
                                    {booking.pf_payment_method && (
                                        <div className="flex justify-between"><span className="text-gray-500">決済方法</span><span className="text-gray-300 font-bold">{booking.pf_payment_method === 'credit' ? 'クレジットカード' : booking.pf_payment_method === 'paypay' ? 'PayPay' : booking.pf_payment_method === 'cvs' ? 'コンビニ決済' : booking.pf_payment_method || '-'}</span></div>
                                    )}
                                    {booking.pf_paid_at && (
                                        <div className="flex justify-between"><span className="text-gray-500">入金日時</span><span className="text-gray-300 font-bold">{booking.pf_paid_at}</span></div>
                                    )}
                                    {booking.pf_sid && (
                                        <div className="flex justify-between"><span className="text-gray-500">取引ID</span><span className="text-gray-400 font-mono text-[10px]">{booking.pf_sid}</span></div>
                                    )}
                                </div>
                            </div>
                        ) : booking.status === 'confirmed' ? (
                            <div className="flex items-center gap-3">
                                <span className="w-8 h-8 rounded-full bg-pink-500/80 flex items-center justify-center text-white text-lg animate-pulse shadow-[0_0_12px_rgba(236,72,153,0.5)]">¥</span>
                                <div>
                                    <div className="text-pink-400 font-bold text-sm">お客様の支払い待ち</div>
                                    <div className="text-gray-400 text-[10px]">マイページから決済手続き中です</div>
                                </div>
                            </div>
                        ) : booking.status === 'pending' ? (
                            <div className="flex items-center gap-3">
                                <span className="w-8 h-8 rounded-full bg-yellow-600/80 flex items-center justify-center text-white text-sm shadow-[0_0_12px_rgba(202,138,4,0.3)]">…</span>
                                <div>
                                    <div className="text-yellow-500 font-bold text-sm">仮予約（対話方法の選択待ち）</div>
                                    <div className="text-gray-400 text-[10px]">お客様が対話方法を選択後、決済に進みます</div>
                                </div>
                            </div>
                        ) : (
                            <div className="text-gray-500 text-sm">-</div>
                        )}
                    </div>
                    
                    <div>
                        <div className="text-gray-400 text-xs font-bold tracking-widest mb-3">ステータス変更</div>
                        <div className="grid grid-cols-2 gap-3">
                            {[{ id: 'pending', label: '仮予約', c: 'hover:bg-yellow-900/50 hover:border-yellow-600 text-yellow-500', active: 'bg-yellow-600 text-white border-yellow-500 shadow-[0_0_15px_rgba(202,138,4,0.3)]' },
                              { id: 'confirmed', label: '支払い待ち', c: 'hover:bg-pink-900/50 hover:border-pink-600 text-pink-500', active: 'bg-pink-600 text-white border-pink-500 shadow-[0_0_15px_rgba(236,72,153,0.3)]' },
                              { id: 'paid', label: '支払い済', c: 'hover:bg-green-900/50 hover:border-green-600 text-green-500', active: 'bg-green-600 text-white border-green-500 shadow-[0_0_15px_rgba(22,163,74,0.3)]' },
                              { id: 'completed', label: '鑑定完了', c: 'hover:bg-blue-900/50 hover:border-blue-600 text-blue-500', active: 'bg-blue-600 text-white border-blue-500 shadow-[0_0_15px_rgba(37,99,235,0.3)]' },
                              { id: 'cancelled', label: 'キャンセル', c: 'hover:bg-gray-700 hover:border-gray-500 text-gray-400', active: 'bg-gray-700 text-white border-gray-500' }
                            ].map(s => (
                                <button key={s.id} onClick={() => onUpdateStatus(booking.id, s.id)} className={`py-2.5 rounded-lg text-sm font-bold transition-all duration-300 border ${booking.status === s.id ? s.active : `border-gray-700 bg-gray-900 ${s.c}`}`}>
                                    {s.label}
                                </button>
                            ))}
                        </div>
                    </div>

                    {(booking.status === 'paid') && !booking.extension_status && (
                        <div className="pt-6 border-t border-gray-700">
                            <div className="text-gray-400 text-xs font-bold tracking-widest mb-3">オプション操作</div>
                            <button onClick={() => onRequestExtension(booking.id, extendPrice)} className="w-full bg-gradient-to-r from-purple-700 to-purple-600 hover:from-purple-600 hover:to-purple-500 text-white font-bold py-3.5 rounded-xl text-sm transition-all duration-300 shadow-[0_0_15px_rgba(147,51,234,0.3)] hover:-translate-y-0.5 active:scale-95 flex items-center justify-center gap-2">
                                <Icons.Plus className="w-4 h-4"/> 10分延長 (¥{extendPrice.toLocaleString()}) を許可する
                            </button>
                        </div>
                    )}
                    {booking.extension_status === 'pending' && (
                        <div className="pt-6 border-t border-gray-700">
                            <div className="text-yellow-400 text-sm font-bold bg-yellow-900/20 p-4 rounded-xl border border-yellow-700/50 flex items-center gap-3 shadow-inner">
                                <span className="animate-spin inline-block">⏳</span> 延長料金 (¥{booking.extension_fee?.toLocaleString() || extendPrice.toLocaleString()}) のお客様支払い待ち
                            </div>
                        </div>
                    )}
                    {booking.extension_status === 'paid' && (
                        <div className="pt-6 border-t border-gray-700">
                            <div className="text-green-400 text-sm font-bold bg-green-900/20 p-4 rounded-xl border border-green-800/50 w-full flex items-center gap-3 shadow-inner">
                                <Icons.Sparkles className="w-4 h-4"/> 10分延長 追加済み (支払い完了)
                            </div>
                        </div>
                    )}
                </div>
            </div>
        </div>
    );
};

const AdminScheduleTable = ({ selectedTeller, bookings, onBookingClick, onBookingDrop, onToggleHoliday, showToast }) => {
    if (!selectedTeller) return <div className="p-8 text-center text-gray-500">占い師を選択してください</div>;
    
    const startHour = 8; const endHour = 24; const totalHours = endHour - startHour; const hourWidth = 60;
    const hours = Array.from({ length: totalHours + 1 }, (_, i) => startHour + i);
    const dates = Array.from({ length: 14 }, (_, i) => { const d = new Date(); d.setDate(d.getDate() + i); return { full: d.toISOString().split('T')[0], display: `${d.getMonth() + 1}/${d.getDate()}` }; });

    const [dragOverCell, setDragOverCell] = useState(null);

    const handleDragStart = (e, bookingId) => {
        e.dataTransfer.setData('bookingId', bookingId);
        e.dataTransfer.effectAllowed = 'move';
        setTimeout(() => e.target.style.opacity = '0.5', 0);
    };
    const handleDragEnd = (e) => { e.target.style.opacity = '1'; setDragOverCell(null); };

    const handleDragOver = (e, dateStr) => {
        e.preventDefault();
        e.dataTransfer.dropEffect = 'move';
        const rect = e.currentTarget.getBoundingClientRect();
        const x = e.clientX - rect.left;
        const minutesFromStart = (x / hourWidth) * 60;
        const totalMinutes = Math.floor(minutesFromStart / 30) * 30; // 30分単位に丸める
        setDragOverCell(`${dateStr}_${totalMinutes}`);
    };

    const handleDragLeave = () => setDragOverCell(null);

    const handleDrop = (e, targetDate) => {
        e.preventDefault();
        setDragOverCell(null);
        const bookingId = e.dataTransfer.getData('bookingId');
        if (!bookingId) return;

        const rect = e.currentTarget.getBoundingClientRect();
        const x = e.clientX - rect.left;
        const minutesFromStart = (x / hourWidth) * 60;
        const totalMinutes = Math.round(minutesFromStart / 30) * 30;
        
        let newH = startHour + Math.floor(totalMinutes / 60);
        let newM = totalMinutes % 60;
        if (newH < startHour) { newH = startHour; newM = 0; }
        if (newH >= endHour) { newH = endHour - 1; newM = 30; }

        const timeStr = `${String(newH).padStart(2, '0')}:${String(newM).padStart(2, '0')}`;
        onBookingDrop(bookingId, targetDate, timeStr);
    };

    return (
        <div className="bg-gray-800 rounded-xl border border-gray-700 shadow-lg flex flex-col h-full admin-theme overflow-hidden relative">
            <div className="overflow-auto custom-scrollbar flex-1 relative bg-gray-900">
                <div style={{ width: `${totalHours * hourWidth + 96}px`, minHeight: '100%' }}>
                    <div className="flex border-b border-gray-700 bg-gray-850 sticky top-0 z-40">
                        <div className="w-24 shrink-0 p-2 border-r border-gray-700 text-xs text-center sticky left-0 top-0 bg-gray-850 z-50 font-bold shadow-[2px_0_5px_rgba(0,0,0,0.2)]">日付</div>
                        <div className="flex relative" style={{ width: `${totalHours * hourWidth}px`, height: '40px' }}>
                            {hours.map(h => <div key={h} className="absolute top-0 bottom-0 border-l border-gray-700 text-[10px] text-gray-400 pl-1 pt-1 font-mono" style={{ left: `${(h - startHour) * hourWidth}px` }}>{h}:00</div>)}
                        </div>
                    </div>
                    {dates.map(dateItem => { 
                        const dayBookings = bookings.filter(b => b.fortune_teller_id == selectedTeller.id && (b.booking_date || '').startsWith(dateItem.full) && b.status !== 'cancelled'); 
                        const isHoliday = dayBookings.some(b => b.status === 'holiday');
                        
                        return (
                            <div key={dateItem.full} className="flex border-b border-gray-700/50 h-16 relative hover:bg-gray-800/50 transition-colors group">
                                <div className="w-24 shrink-0 p-1 border-r border-gray-700 bg-gray-800 z-30 sticky left-0 flex flex-col items-center justify-center font-bold text-sm text-gray-300 shadow-[2px_0_5px_rgba(0,0,0,0.2)]">
                                    <div>{dateItem.display}</div>
                                    <button onClick={() => { onToggleHoliday(dateItem.full); showToast(isHoliday?'休日を解除しました':'休日に設定しました'); }} className={`mt-1 px-2 py-0.5 rounded text-[10px] transition-colors border ${isHoliday ? 'bg-red-900/50 text-red-300 border-red-800 hover:bg-red-900' : 'bg-gray-700 text-gray-400 border-gray-600 hover:bg-gray-600'}`}>
                                        {isHoliday ? '休日解除' : '休みにする'}
                                    </button>
                                </div>
                                <div className={`relative h-full flex-1 ${isHoliday ? 'bg-[repeating-linear-gradient(45deg,transparent,transparent_10px,rgba(239,68,68,0.05)_10px,rgba(239,68,68,0.05)_20px)]' : ''}`} style={{ width: `${totalHours * hourWidth}px` }} onDragOver={isHoliday ? undefined : (e) => handleDragOver(e, dateItem.full)} onDragLeave={handleDragLeave} onDrop={isHoliday ? undefined : (e) => handleDrop(e, dateItem.full)}>
                                    {isHoliday && <div className="absolute inset-0 flex items-center justify-center text-red-400/20 font-bold tracking-[0.5em] text-2xl pointer-events-none select-none">HOLIDAY</div>}
                                    
                                    {!isHoliday && Array.from({ length: totalHours * 2 }).map((_, i) => {
                                        const isOver = dragOverCell === `${dateItem.full}_${i * 30}`;
                                        return (
                                            <div key={i} className={`absolute top-0 bottom-0 border-l pointer-events-none transition-colors ${i % 2 === 0 ? 'border-gray-700/50' : 'border-gray-800 border-dashed'} ${isOver ? 'bg-blue-500/20 border-blue-400' : ''}`} style={{ left: `${i * (hourWidth / 2)}px`, width: `${hourWidth / 2}px` }}></div>
                                        )
                                    })}

                                    {!isHoliday && dayBookings.map(b => {
                                        if (b.status === 'holiday') return null;
                                        const [h,m] = (b.booking_date || '00:00 10:00').split(' ')[1].split(':').map(Number); 
                                        const left = ((h - startHour) * 60 + m) / 60 * hourWidth;
                                        const colorClass = b.status === 'paid' ? 'bg-gradient-to-r from-green-600 to-green-500 border-green-400' : b.status === 'confirmed' ? 'bg-gradient-to-r from-pink-600 to-pink-500 border-pink-400 animate-pulse' : b.status === 'completed' ? 'bg-gradient-to-r from-blue-700 to-blue-600 border-blue-500 opacity-60' : 'bg-gradient-to-r from-yellow-600 to-yellow-500 border-yellow-400';
                                        const isExtended = b.extension_status === 'paid' || b.extension_status === 'pending';
                                        const widthClass = (b.course && b.course.includes('60')) ? '58px' : (isExtended ? '38px' : '28px');
                                        return (
                                            <div key={b.id} draggable={b.status !== 'completed'} onDragStart={(e) => handleDragStart(e, b.id)} onDragEnd={handleDragEnd} onClick={() => onBookingClick(b)} className={`absolute top-2 bottom-2 rounded-md cursor-grab border flex flex-col justify-center px-1 text-[10px] text-white overflow-hidden shadow-lg hover:shadow-xl hover:brightness-110 active:scale-95 transition-all z-10 ${colorClass} ${b.extension_status === 'pending' ? 'animate-pulse' : ''}`} style={{ left: `${left}px`, width: widthClass }} title={`${b.user_name} (${getCourseDisplay(b.course)})`}>
                                                <div className="font-bold truncate pointer-events-none drop-shadow-md">{b.user_name}</div>
                                                <div className="opacity-90 scale-90 origin-left whitespace-nowrap pointer-events-none">{getCourseShortDisplay(b.course)}{isExtended ? '+10m' : ''}{b.status === 'paid' ? ' ✓' : b.status === 'confirmed' ? ' ¥' : ''}</div>
                                            </div>
                                        );
                                    })}
                                </div>
                            </div>
                        ); 
                    })}
                </div>
            </div>
            <div className="bg-gray-850 p-3 shrink-0 flex justify-center gap-4 md:gap-6 text-xs text-gray-400 rounded-b-xl border-t border-gray-700 flex-wrap">
                <span className="flex items-center gap-1"><span className="w-3 h-3 rounded-full bg-yellow-500 shadow-[0_0_8px_rgba(234,179,8,0.5)]"></span>仮予約</span>
                <span className="flex items-center gap-1"><span className="w-3 h-3 rounded-full bg-pink-500 animate-pulse shadow-[0_0_8px_rgba(236,72,153,0.5)]"></span>支払い待ち</span>
                <span className="flex items-center gap-1"><span className="w-3 h-3 rounded-full bg-green-500 shadow-[0_0_8px_rgba(34,197,94,0.5)]"></span>支払い済</span>
                <span className="flex items-center gap-1"><span className="w-3 h-3 rounded-full bg-blue-600 opacity-60"></span>完了</span>
                <span className="ml-2 text-gray-500 hidden md:inline">※予約枠をドラッグ＆ドロップで時間変更できます</span>
            </div>
        </div>
    );
};

const AdminAnalytics = ({ tellers, bookings, authUser, isAdmin }) => {
    const [targetMonth, setTargetMonth] = useState(() => { const d = new Date(); return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`; });
    const stats = useMemo(() => {
        let targetTellers = tellers.filter(t => !checkIsAdmin(t));
        if (!isAdmin) targetTellers = targetTellers.filter(t => t.id === authUser.id);
        const data = targetTellers.map(t => ({ ...t, totalSales: 0, count: 0, commissionAmount: 0 })); 
        let total = 0; let totalCommission = 0;
        bookings.forEach(b => { 
            if (b.status === 'cancelled' || b.status === 'holiday' || b.status === 'pending') return; 
            if (!(b.booking_date || '').startsWith(targetMonth)) return;
            const t = data.find(dt => dt.id == b.fortune_teller_id); 
            if (t) { const price = parseInt(b.final_price || 0) + parseInt(b.extension_fee || 0); t.totalSales += price; total += price; t.count++; } 
        });
        data.forEach(t => { const rate = parseInt(t.commission_rate) || 60; t.commissionAmount = Math.floor(t.totalSales * (rate / 100)); totalCommission += t.commissionAmount; });
        return { tellers: data.sort((a,b)=>b.totalSales-a.totalSales), total, totalCommission };
    }, [tellers, bookings, authUser, isAdmin, targetMonth]);

    return (
        <div className="space-y-6 admin-theme animate-fade-in pb-20 md:pb-0">
            <div className="flex justify-between items-center bg-gray-800 p-4 rounded-xl border border-gray-700 shadow-md">
                <h3 className="font-bold text-white md:text-lg flex items-center gap-2"><Icons.Calendar className="w-5 h-5 text-yellow-500"/> {isAdmin ? '売上・報酬分析' : '今月の報酬明細'}</h3>
                <input type="month" value={targetMonth} onChange={(e) => setTargetMonth(e.target.value)} className="bg-gray-900 border border-gray-700 rounded-lg p-2 text-white text-sm outline-none focus:border-yellow-500" />
            </div>
            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                <div className="bg-gray-800 p-6 rounded-xl border border-gray-700 shadow-lg hover:-translate-y-1 transition-all duration-300">
                    <p className="text-gray-400 font-bold mb-1 flex items-center gap-2"><Icons.Sparkles className="w-4 h-4 text-yellow-500"/> {isAdmin ? '総売上' : 'あなたの総売上'}</p>
                    <p className="text-4xl font-black text-yellow-500 tracking-wider drop-shadow-md">¥{stats.total.toLocaleString()}</p>
                </div>
                <div className="bg-gray-800 p-6 rounded-xl border border-gray-700 shadow-lg hover:-translate-y-1 transition-all duration-300 relative overflow-hidden">
                    <div className="absolute top-0 right-0 w-32 h-32 bg-green-500/10 rounded-full blur-2xl -translate-y-1/2 translate-x-1/2"></div>
                    <p className="text-gray-400 font-bold mb-1 flex items-center gap-2 relative z-10"><Icons.CreditCard className="w-4 h-4 text-green-400"/> {isAdmin ? '占い師への支払報酬額合計' : '今月の獲得報酬 (見込み)'}</p>
                    <p className="text-4xl font-black text-green-400 tracking-wider drop-shadow-md relative z-10">¥{stats.totalCommission.toLocaleString()}</p>
                </div>
            </div>
            <div className="bg-gray-800 rounded-xl border border-gray-700 overflow-hidden shadow-lg">
                <div className="p-4 border-b border-gray-700 bg-gray-850"><h4 className="font-bold text-white">詳細データ ({targetMonth})</h4></div>
                <div className="overflow-x-auto">
                    <table className="w-full text-sm text-left text-gray-300 whitespace-nowrap">
                        <thead className="bg-gray-900/80 text-gray-500 text-xs uppercase tracking-wider">
                            <tr><th className="p-4">鑑定師</th><th className="p-4 text-center">件数</th><th className="p-4 text-right">売上金額</th><th className="p-4 text-center text-blue-400">歩合率</th><th className="p-4 text-right text-green-400">報酬額 (支払額)</th>{isAdmin && <th className="p-4 text-right text-yellow-600">本部利益</th>}</tr>
                        </thead>
                        <tbody className="divide-y divide-gray-700">
                            {stats.tellers.map(t => ( 
                                <tr key={t.id} className="hover:bg-gray-700/50 transition-colors">
                                    <td className="p-4 font-bold flex items-center gap-3">{t.image_url ? <img src={t.image_url} className="w-8 h-8 rounded-full object-cover border border-gray-600 shadow-sm"/> : <div className="w-8 h-8 rounded-full bg-gray-700 border border-gray-600 shadow-sm"/>}{t.name}</td>
                                    <td className="p-4 text-center">{t.count}件</td>
                                    <td className="p-4 text-right font-bold text-gray-200">¥{t.totalSales.toLocaleString()}</td>
                                    <td className="p-4 text-center text-blue-400 font-mono">{t.commission_rate}%</td>
                                    <td className="p-4 text-right font-bold text-green-400">¥{t.commissionAmount.toLocaleString()}</td>
                                    {isAdmin && <td className="p-4 text-right font-bold text-yellow-600">¥{(t.totalSales - t.commissionAmount).toLocaleString()}</td>}
                                </tr> 
                            ))}
                            {stats.tellers.length === 0 && <tr><td colSpan="6" className="p-8 text-center text-gray-500">この月のデータはありません</td></tr>}
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    );
};

const AdminCustomers = ({ showToast }) => {
    const [customers, setCustomers] = useState([]); 
    const [searchQuery, setSearchQuery] = useState('');

    useEffect(() => { fetchApi('customer_stats').then(setCustomers); }, []);
    
    const toggleBl = async (email, current) => { 
        await fetchApi('toggle_blacklist', { method: 'POST', body: JSON.stringify({ email, is_blacklisted: current ? 0 : 1 }) }); 
        fetchApi('customer_stats').then(setCustomers); 
        showToast(current ? 'ブラックリストから解除しました' : 'ブラックリストに登録しました', current ? 'success' : 'error');
    };
    
    const filteredCustomers = customers.filter(c => 
        (c.user_name && c.user_name.includes(searchQuery)) || 
        (c.user_email && c.user_email.includes(searchQuery))
    );

    return ( 
        <div className="bg-gray-800 rounded-xl border border-gray-700 overflow-hidden admin-theme shadow-lg animate-fade-in flex flex-col h-[85vh]">
            <div className="p-4 border-b border-gray-700 flex justify-between items-center bg-gray-900 shrink-0">
                <h3 className="font-bold text-white flex items-center gap-2"><Icons.User className="w-5 h-5 text-red-400"/>顧客管理</h3>
                <div className="relative w-64">
                    <Icons.Search className="w-4 h-4 absolute left-3 top-1/2 -translate-y-1/2 text-gray-500"/>
                    <input type="text" value={searchQuery} onChange={e=>setSearchQuery(e.target.value)} placeholder="名前かメールで検索..." className="w-full bg-gray-950 border border-gray-700 rounded-lg pl-9 pr-3 py-2 text-sm text-white focus:border-red-400 outline-none transition-colors" />
                </div>
            </div>
            <div className="overflow-y-auto flex-1 custom-scrollbar">
                <table className="w-full text-sm text-left text-gray-300 relative">
                    <thead className="bg-gray-900/80 text-gray-500 sticky top-0 z-10 backdrop-blur-md">
                        <tr><th className="p-4">顧客名 / メール</th><th className="p-4 text-center">総予約</th><th className="p-4 text-center text-red-400">キャンセル</th><th className="p-4 text-right">操作</th></tr>
                    </thead>
                    <tbody className="divide-y divide-gray-700">
                        {filteredCustomers.map(c => { 
                            const isBl = parseInt(c.is_blacklisted) === 1; 
                            return ( 
                                <tr key={c.user_email} className={`transition-colors duration-300 ${isBl ? 'bg-red-900/10 hover:bg-red-900/20' : 'hover:bg-gray-700/50'}`}>
                                    <td className="p-4"><div className="font-bold text-white">{c.user_name}</div><div className="text-xs text-gray-500 font-mono mt-0.5">{c.user_email}</div>{isBl && <span className="text-xs text-red-400 font-bold tracking-widest mt-1 block flex items-center gap-1"><Icons.Shield className="w-3 h-3"/>BL登録中</span>}</td>
                                    <td className="p-4 text-center">{c.total_bookings}</td>
                                    <td className="p-4 text-center font-bold text-red-400">{c.cancel_count}</td>
                                    <td className="p-4 text-right"><button onClick={() => toggleBl(c.user_email, isBl)} className={`px-4 py-1.5 rounded-md text-xs border font-bold transition-all duration-300 active:scale-95 ${isBl ? 'border-gray-500 text-gray-400 hover:bg-gray-700' : 'border-red-800/50 text-red-400 bg-red-900/20 hover:bg-red-900/40 hover:border-red-500'}`}>{isBl ? '解除' : 'BL登録'}</button></td>
                                </tr> 
                            ) 
                        })}
                        {filteredCustomers.length === 0 && <tr><td colSpan="4" className="p-8 text-center text-gray-500">該当する顧客が見つかりません</td></tr>}
                    </tbody>
                </table>
            </div>
        </div> 
    );
};

// 【復元】クーポン管理コンポーネント
const AdminCoupons = ({ showToast }) => {
    const [coupons, setCoupons] = useState([]); 
    const [editingCoupon, setEditingCoupon] = useState(null);

    const loadData = () => fetchApi('get_coupons').then(setCoupons);
    useEffect(() => { loadData(); }, []);

    const handleSaveCoupon = async (e) => {
        e.preventDefault();
        try {
            const res = await fetchApi('save_coupon', { method: 'POST', body: JSON.stringify(editingCoupon) });
            if (res && res.success) {
                setEditingCoupon(null);
                loadData();
                showToast('クーポンを保存しました');
            } else {
                showToast(res?.message || '保存に失敗しました', 'error');
            }
        } catch (error) {
            showToast('通信エラーが発生しました', 'error');
        }
    };

    const handleDeleteCoupon = async (id) => {
        if(!confirm('本当にこのクーポンを削除しますか？')) return;
        try {
            await fetchApi('delete_coupon', { method: 'POST', body: JSON.stringify({ id }) });
            loadData();
            showToast('クーポンを削除しました');
        } catch(e) {
            showToast('エラーが発生しました', 'error');
        }
    };
    
    const handleToggleActive = async (coupon) => {
        const updatedCoupon = { ...coupon, is_active: parseInt(coupon.is_active) === 1 ? 0 : 1 };
        try {
            await fetchApi('save_coupon', { method: 'POST', body: JSON.stringify(updatedCoupon) });
            loadData();
            showToast(updatedCoupon.is_active ? 'クーポンを有効にしました' : 'クーポンを無効にしました');
        } catch (e) {
            showToast('エラーが発生しました', 'error');
        }
    };

    const inputClass = "w-full bg-gray-900 border border-gray-700 rounded-xl p-3 outline-none focus:border-yellow-500 focus:ring-2 focus:ring-yellow-500/20 text-white text-sm transition-all duration-300";
    const btnPrimary = "bg-gradient-to-r from-yellow-600 to-yellow-500 hover:from-yellow-500 hover:to-yellow-400 text-gray-900 px-6 py-2.5 rounded-lg font-bold text-sm shadow-[0_0_15px_rgba(234,179,8,0.3)] transition-all active:scale-95 flex items-center gap-2";
    const btnCancel = "bg-gray-700 hover:bg-gray-600 text-white px-6 py-2.5 rounded-lg font-bold text-sm transition-all duration-300 active:scale-95";

    return ( 
        <div className="space-y-6 admin-theme animate-fade-in pb-20 md:pb-0 h-[85vh] flex flex-col">
            <div className="bg-gray-800 rounded-xl border border-gray-700 shadow-lg flex-1 overflow-hidden flex flex-col relative">
                {!editingCoupon ? (
                    <div className="animate-fade-in flex flex-col h-full">
                        <div className="flex justify-between items-center p-4 border-b border-gray-700 shrink-0">
                            <h4 className="text-white font-bold flex items-center gap-2"><Icons.Cards className="w-5 h-5 text-yellow-500"/> クーポン一覧</h4>
                            <button onClick={() => setEditingCoupon({ code: '', discount_type: 'fixed', discount_value: 0, expiry_date: '', description: '', is_active: 1 })} className={btnPrimary}>
                                <Icons.Plus className="w-4 h-4"/> 新規追加
                            </button>
                        </div>
                        <div className="overflow-y-auto flex-1 custom-scrollbar">
                            <table className="w-full text-sm text-left text-gray-300">
                                <thead className="bg-gray-900 text-gray-500 sticky top-0 z-10">
                                    <tr className="border-b border-gray-700"><th className="p-4 font-bold tracking-widest">コード</th><th className="p-4 font-bold tracking-widest">説明</th><th className="p-4 font-bold tracking-widest text-right">割引</th><th className="p-4 font-bold tracking-widest">有効期限</th><th className="p-4 font-bold tracking-widest text-center">状態</th><th className="p-4 w-24 text-right font-bold tracking-widest">操作</th></tr>
                                </thead>
                                <tbody className="divide-y divide-gray-700/50">
                                    {coupons.map(c => ( 
                                        <tr key={c.id} className="hover:bg-gray-700/50 transition-colors duration-300">
                                            <td className="p-4 font-mono font-bold text-white tracking-wider">{c.code}</td>
                                            <td className="p-4">{c.description}</td>
                                            <td className="p-4 text-yellow-500 font-bold text-right">{c.discount_type === 'fixed' ? `¥${c.discount_value} OFF` : `${c.discount_value}% OFF`}</td>
                                            <td className="p-4 text-xs font-mono">{c.expiry_date ? c.expiry_date : '無期限'}</td>
                                            <td className="p-4 text-center">
                                                <button onClick={() => handleToggleActive(c)} className={`px-3 py-1.5 rounded-md text-[10px] font-bold tracking-widest transition-all ${parseInt(c.is_active) ? 'bg-green-900/50 text-green-400 border border-green-800/50' : 'bg-red-900/50 text-red-400 border border-red-800/50'}`}>
                                                    {parseInt(c.is_active) ? '有効' : '無効'}
                                                </button>
                                            </td>
                                            <td className="p-4 text-right whitespace-nowrap">
                                                <button onClick={() => setEditingCoupon(c)} className="text-blue-400 hover:text-blue-300 mr-3 transition-transform hover:scale-110"><Icons.PenTool className="w-4 h-4 inline"/></button>
                                                <button onClick={() => handleDeleteCoupon(c.id)} className="text-red-400 hover:text-red-300 transition-transform hover:scale-110"><Icons.Trash className="w-4 h-4 inline"/></button>
                                            </td>
                                        </tr> 
                                    ))}
                                    {coupons.length === 0 && (
                                        <tr><td colSpan="6" className="p-8 text-center text-gray-500">クーポンが登録されていません</td></tr>
                                    )}
                                </tbody>
                            </table>
                        </div>
                    </div>
                ) : (
                    <form onSubmit={handleSaveCoupon} className="flex flex-col h-full bg-gray-900/50">
                        <div className="p-6 overflow-y-auto flex-1 custom-scrollbar space-y-5 pb-24">
                            <h4 className="font-bold text-yellow-500 border-b border-gray-700 pb-3">{editingCoupon.id ? 'クーポンの編集' : 'クーポンの追加'}</h4>
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
                                <div><label className="text-xs text-gray-400 font-bold tracking-widest block mb-2">クーポンコード * (英数字)</label><input required className={`${inputClass} font-mono uppercase`} value={editingCoupon.code} onChange={e=>setEditingCoupon({...editingCoupon, code: e.target.value.toUpperCase()})} placeholder="WELCOME2026" /></div>
                                <div><label className="text-xs text-gray-400 font-bold tracking-widest block mb-2">説明 (お客様に表示されます)</label><input required className={inputClass} value={editingCoupon.description} onChange={e=>setEditingCoupon({...editingCoupon, description: e.target.value})} placeholder="初回限定割引など" /></div>
                                <div>
                                    <label className="text-xs text-gray-400 font-bold tracking-widest block mb-2">割引タイプ</label>
                                    <select className={inputClass} value={editingCoupon.discount_type} onChange={e=>setEditingCoupon({...editingCoupon, discount_type: e.target.value})}>
                                        <option value="fixed">固定額割引 (円)</option>
                                        <option value="percent">割合割引 (%)</option>
                                    </select>
                                </div>
                                <div><label className="text-xs text-gray-400 font-bold tracking-widest block mb-2">割引値 * {editingCoupon.discount_type === 'fixed' ? '(例: 1000)' : '(例: 10)'}</label><input type="number" required min="1" className={inputClass} value={editingCoupon.discount_value} onChange={e=>setEditingCoupon({...editingCoupon, discount_value: parseInt(e.target.value) || 0})} /></div>
                                <div><label className="text-xs text-gray-400 font-bold tracking-widest block mb-2">有効期限 (空欄で無期限)</label><input type="date" className={inputClass} value={editingCoupon.expiry_date || ''} onChange={e=>setEditingCoupon({...editingCoupon, expiry_date: e.target.value})} /></div>
                            </div>
                            <label className="flex items-center gap-3 cursor-pointer bg-gray-800 p-3 rounded-xl border border-gray-700 hover:border-gray-500 transition-colors w-max mt-4">
                                <input type="checkbox" checked={parseInt(editingCoupon.is_active) === 1} onChange={e=>setEditingCoupon({...editingCoupon, is_active: e.target.checked ? 1 : 0})} className="w-5 h-5 text-yellow-600 rounded bg-gray-900 border-gray-600 focus:ring-0" />
                                <span className="text-sm font-bold tracking-widest">有効にする</span>
                            </label>
                        </div>
                        <div className="p-4 bg-gray-900 border-t border-gray-800 shrink-0 flex justify-end gap-4 absolute bottom-0 left-0 w-full z-10 shadow-[0_-10px_20px_rgba(0,0,0,0.5)]">
                            <button type="button" onClick={() => setEditingCoupon(null)} className={btnCancel}>キャンセル</button>
                            <button type="submit" className={btnPrimary}>保存する</button>
                        </div>
                    </form>
                )}
            </div>
        </div> 
    );
};


const AdminContents = ({ tellers, authUser, isAdmin, showToast }) => {
    const [activeSubTab, setActiveSubTab] = useState('blogs');
    const [news, setNews] = useState([]); const [testimonials, setTestimonials] = useState([]); const [faqs, setFaqs] = useState([]); const [blogs, setBlogs] = useState([]); 
    const [editingNews, setEditingNews] = useState(null); const [editingTestimonial, setEditingTestimonial] = useState(null); const [editingFaq, setEditingFaq] = useState(null); const [editingBlog, setEditingBlog] = useState(null); 

    const loadData = () => { 
        if (isAdmin) { fetchApi('news_admin').then(setNews); fetchApi('testimonials_admin').then(setTestimonials); fetchApi('faqs_admin').then(setFaqs); }
        fetchApi('blogs_admin').then(setBlogs); 
    };
    useEffect(() => { loadData(); }, [isAdmin]);

    const handleSave = async (apiAction, data, setEditingFn, successMsg) => {
        try { await fetchApi(apiAction, { method: 'POST', body: JSON.stringify(data) }); setEditingFn(null); loadData(); showToast(successMsg); } 
        catch(err) { showToast('保存に失敗しました', 'error'); }
    };
    const handleDelete = async (apiAction, id, successMsg) => {
        if(!confirm('本当に削除しますか？')) return;
        try { await fetchApi(apiAction, { method: 'POST', body: JSON.stringify({ id }) }); loadData(); showToast(successMsg); } 
        catch(err) { showToast('削除に失敗しました', 'error'); }
    };

    const handleBlogImageChange = (e) => { const file = e.target.files[0]; if (file) { const reader = new FileReader(); reader.onloadend = () => setEditingBlog({...editingBlog, image_url: reader.result}); reader.readAsDataURL(file); } };

    const inputClass = "w-full bg-gray-900 border border-gray-700 rounded-xl p-3 outline-none focus:border-yellow-500 focus:ring-2 focus:ring-yellow-500/20 text-white text-sm transition-all duration-300";
    const btnPrimary = "bg-gradient-to-r from-yellow-600 to-yellow-500 hover:from-yellow-500 text-gray-900 px-6 py-2.5 rounded-lg font-bold text-sm shadow-[0_0_15px_rgba(234,179,8,0.3)] transition-all active:scale-95";
    const btnCancel = "bg-gray-700 hover:bg-gray-600 text-white px-6 py-2.5 rounded-lg font-bold text-sm transition-all active:scale-95";

    return (
        <div className="space-y-6 admin-theme animate-fade-in pb-20 md:pb-0 h-[85vh] flex flex-col">
            <div className="flex border-b border-gray-700 shrink-0 overflow-x-auto bg-gray-800 rounded-xl shadow-md p-1 relative">
                <button className={`relative flex-1 py-3.5 text-sm font-bold whitespace-nowrap px-4 transition-all rounded-lg z-10 ${activeSubTab === 'blogs' ? 'text-yellow-400 bg-gray-900 shadow-inner' : 'text-gray-500 hover:text-gray-300'}`} onClick={() => setActiveSubTab('blogs')}>コラム執筆</button>
                {isAdmin && <button className={`relative flex-1 py-3.5 text-sm font-bold whitespace-nowrap px-4 transition-all rounded-lg z-10 ${activeSubTab === 'news' ? 'text-yellow-400 bg-gray-900 shadow-inner' : 'text-gray-500 hover:text-gray-300'}`} onClick={() => setActiveSubTab('news')}>お知らせ</button>}
                {isAdmin && <button className={`relative flex-1 py-3.5 text-sm font-bold whitespace-nowrap px-4 transition-all rounded-lg z-10 ${activeSubTab === 'testimonials' ? 'text-yellow-400 bg-gray-900 shadow-inner' : 'text-gray-500 hover:text-gray-300'}`} onClick={() => setActiveSubTab('testimonials')}>お客様の声</button>}
                {isAdmin && <button className={`relative flex-1 py-3.5 text-sm font-bold whitespace-nowrap px-4 transition-all rounded-lg z-10 ${activeSubTab === 'faqs' ? 'text-yellow-400 bg-gray-900 shadow-inner' : 'text-gray-500 hover:text-gray-300'}`} onClick={() => setActiveSubTab('faqs')}>FAQ</button>}
            </div>
            
            <div className="bg-gray-800 rounded-xl border border-gray-700 shadow-lg flex-1 overflow-hidden flex flex-col relative">
                {activeSubTab === 'blogs' && (
                    <div className="animate-fade-in flex flex-col h-full">
                        {!editingBlog ? (
                            <>
                                <div className="flex justify-between items-center p-4 border-b border-gray-700 shrink-0">
                                    <h4 className="text-white font-bold">執筆した記事一覧</h4>
                                    <button onClick={() => setEditingBlog({ title: '', content: '', image_url: '', category: '', fortune_teller_id: isAdmin ? '' : authUser.id, published_date: new Date().toISOString().split('T')[0], is_visible: 1 })} className={btnPrimary}>+ 新規作成</button>
                                </div>
                                <div className="overflow-y-auto flex-1 custom-scrollbar">
                                    <table className="w-full text-sm text-left text-gray-300">
                                        <thead className="bg-gray-900 text-gray-500 sticky top-0 z-10"><tr className="border-b border-gray-700"><th className="p-4 w-32">公開日</th><th className="p-4">タイトル</th>{isAdmin && <th className="p-4">執筆者</th>}<th className="p-4 w-20 text-center">公開</th><th className="p-4 w-24 text-right">操作</th></tr></thead>
                                        <tbody className="divide-y divide-gray-700">
                                            {blogs.map(b => ( 
                                                <tr key={b.id} className="hover:bg-gray-700/50">
                                                    <td className="p-4 font-mono">{b.published_date}</td>
                                                    <td className="p-4"><div className="font-bold text-white">{b.title}</div><span className="text-[10px] bg-gray-700 px-2 py-0.5 rounded mt-1 inline-block">{b.category || '未分類'}</span></td>
                                                    {isAdmin && <td className="p-4 text-yellow-500 text-xs">{b.author_name || '運営'}</td>}
                                                    <td className="p-4 text-center">{parseInt(b.is_visible) ? <span className="text-green-400">●</span> : <span className="text-gray-600">●</span>}</td>
                                                    <td className="p-4 text-right"><button onClick={() => setEditingBlog(b)} className="text-blue-400 mr-3"><Icons.PenTool className="w-4 h-4"/></button><button onClick={() => handleDelete('delete_blog', b.id, '記事を削除しました')} className="text-red-400"><Icons.Trash className="w-4 h-4"/></button></td>
                                                </tr> 
                                            ))}
                                            {blogs.length === 0 && <tr><td colSpan="5" className="p-8 text-center text-gray-500">記事がありません</td></tr>}
                                        </tbody>
                                    </table>
                                </div>
                            </>
                        ) : (
                            <form onSubmit={(e) => { e.preventDefault(); handleSave('save_blog', editingBlog, setEditingBlog, '記事を保存しました'); }} className="flex flex-col h-full bg-gray-900/50">
                                <div className="p-6 overflow-y-auto flex-1 custom-scrollbar space-y-5 pb-24">
                                    <h4 className="font-bold text-yellow-500 border-b border-gray-700 pb-3">{editingBlog.id ? '記事の編集' : '新規記事の作成'}</h4>
                                    <div><label className="text-xs text-gray-400 font-bold block mb-2">タイトル *</label><input required className={inputClass} value={editingBlog.title} onChange={e=>setEditingBlog({...editingBlog, title: e.target.value})} /></div>
                                    <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
                                        <div><label className="text-xs text-gray-400 font-bold block mb-2">公開日 *</label><input type="date" required className={inputClass} value={editingBlog.published_date} onChange={e=>setEditingBlog({...editingBlog, published_date: e.target.value})} /></div>
                                        <div><label className="text-xs text-gray-400 font-bold block mb-2">カテゴリ</label><input className={inputClass} value={editingBlog.category} onChange={e=>setEditingBlog({...editingBlog, category: e.target.value})} /></div>
                                        {isAdmin && <div><label className="text-xs text-gray-400 font-bold block mb-2">執筆者</label><select className={inputClass} value={editingBlog.fortune_teller_id || ''} onChange={e=>setEditingBlog({...editingBlog, fortune_teller_id: e.target.value || null})}><option value="">運営</option>{tellers.map(t => <option key={t.id} value={t.id}>{t.name}</option>)}</select></div>}
                                    </div>
                                    <div>
                                        <label className="text-xs text-gray-400 font-bold block mb-2">アイキャッチ画像</label>
                                        <div className="flex gap-4 items-center">{editingBlog.image_url && <img src={editingBlog.image_url} className="w-24 h-24 object-cover rounded-xl" />}<input type="file" onChange={handleBlogImageChange} className="text-sm text-gray-400" accept="image/*" /></div>
                                    </div>
                                    <div><label className="text-xs text-gray-400 font-bold block mb-2">本文 (マークダウン記法可) *</label><textarea required className={`${inputClass} h-64 resize-none`} value={editingBlog.content} onChange={e=>setEditingBlog({...editingBlog, content: e.target.value})}></textarea></div>
                                    <label className="flex items-center gap-3"><input type="checkbox" checked={parseInt(editingBlog.is_visible) === 1} onChange={e=>setEditingBlog({...editingBlog, is_visible: e.target.checked ? 1 : 0})} className="w-5 h-5 text-yellow-600 bg-gray-900 border-gray-600 rounded" /><span className="text-sm font-bold">公開する</span></label>
                                </div>
                                <div className="p-4 bg-gray-900 border-t border-gray-800 shrink-0 flex justify-end gap-4 absolute bottom-0 left-0 w-full z-10 shadow-[0_-10px_20px_rgba(0,0,0,0.5)]">
                                    <button type="button" onClick={() => setEditingBlog(null)} className={btnCancel}>キャンセル</button>
                                    <button type="submit" className={btnPrimary}>保存する</button>
                                </div>
                            </form>
                        )}
                    </div>
                )}
                
                {/* 【復元】お知らせ管理 */}
                {activeSubTab === 'news' && isAdmin && (
                    <div className="animate-fade-in flex flex-col h-full">
                        {!editingNews ? (
                             <>
                             <div className="flex justify-between items-center p-4 border-b border-gray-700 shrink-0">
                                 <h4 className="text-white font-bold">お知らせ一覧</h4>
                                 <button onClick={() => setEditingNews({ published_date: new Date().toISOString().split('T')[0], text: '', tag: '新着情報', is_visible: 1 })} className={btnPrimary}>+ 新規追加</button>
                             </div>
                             <div className="overflow-y-auto flex-1 custom-scrollbar">
                                 <table className="w-full text-sm text-left text-gray-300">
                                     <thead className="bg-gray-900 text-gray-500 sticky top-0"><tr className="border-b border-gray-700"><th className="p-4 w-32">日付 / タグ</th><th className="p-4">内容</th><th className="p-4 w-20 text-center">公開</th><th className="p-4 w-24 text-right">操作</th></tr></thead>
                                     <tbody className="divide-y divide-gray-700">
                                         {news.map(n => ( 
                                            <tr key={n.id} className="hover:bg-gray-700/50">
                                                <td className="p-4 font-mono">{n.published_date} <span className="text-[10px] bg-gray-700 px-2 py-0.5 rounded block w-max mt-1 text-white">{n.tag}</span></td>
                                                <td className="p-4"><p className="line-clamp-2">{n.text}</p></td>
                                                <td className="p-4 text-center">{parseInt(n.is_visible) ? <span className="text-green-400">●</span> : <span className="text-gray-600">●</span>}</td>
                                                <td className="p-4 text-right"><button onClick={() => setEditingNews(n)} className="text-blue-400 mr-3"><Icons.PenTool className="w-4 h-4"/></button><button onClick={() => handleDelete('delete_news', n.id, '削除しました')} className="text-red-400"><Icons.Trash className="w-4 h-4"/></button></td>
                                            </tr> 
                                        ))}
                                        {news.length === 0 && <tr><td colSpan="4" className="p-8 text-center text-gray-500">お知らせがありません</td></tr>}
                                     </tbody>
                                 </table>
                             </div>
                         </>
                        ) : (
                            <form onSubmit={(e) => { e.preventDefault(); handleSave('save_news', editingNews, setEditingNews, 'お知らせを保存しました'); }} className="flex flex-col h-full bg-gray-900/50">
                                <div className="p-6 overflow-y-auto flex-1 space-y-5 pb-24">
                                    <h4 className="font-bold text-yellow-500 border-b border-gray-700 pb-3">{editingNews.id ? 'お知らせの編集' : 'お知らせの追加'}</h4>
                                    <div className="grid grid-cols-2 gap-6">
                                        <div><label className="text-xs text-gray-400 font-bold block mb-2">日付 *</label><input type="date" required className={inputClass} value={editingNews.published_date} onChange={e=>setEditingNews({...editingNews, published_date: e.target.value})} /></div>
                                        <div><label className="text-xs text-gray-400 font-bold block mb-2">タグ</label><select className={inputClass} value={editingNews.tag} onChange={e=>setEditingNews({...editingNews, tag: e.target.value})}><option value="新着情報">新着情報</option><option value="キャンペーン">キャンペーン</option><option value="システム">システム</option></select></div>
                                    </div>
                                    <div><label className="text-xs text-gray-400 font-bold block mb-2">内容 *</label><textarea required className={`${inputClass} h-32 resize-none`} value={editingNews.text} onChange={e=>setEditingNews({...editingNews, text: e.target.value})}></textarea></div>
                                    <label className="flex items-center gap-3 mt-2"><input type="checkbox" checked={parseInt(editingNews.is_visible) === 1} onChange={e=>setEditingNews({...editingNews, is_visible: e.target.checked ? 1 : 0})} className="w-5 h-5 text-yellow-600 bg-gray-900 border-gray-600 rounded" /><span className="text-sm font-bold">公開する</span></label>
                                </div>
                                <div className="p-4 bg-gray-900 border-t border-gray-800 shrink-0 flex justify-end gap-4 absolute bottom-0 left-0 w-full shadow-[0_-10px_20px_rgba(0,0,0,0.5)]">
                                    <button type="button" onClick={() => setEditingNews(null)} className={btnCancel}>キャンセル</button>
                                    <button type="submit" className={btnPrimary}>保存する</button>
                                </div>
                            </form>
                        )}
                    </div>
                )}

                {/* 【復元】お客様の声管理 */}
                {activeSubTab === 'testimonials' && isAdmin && (
                    <div className="animate-fade-in flex flex-col h-full">
                        {!editingTestimonial ? (
                             <>
                             <div className="flex justify-between items-center p-4 border-b border-gray-700 shrink-0">
                                 <h4 className="text-white font-bold">お客様の声一覧</h4>
                                 <button onClick={() => setEditingTestimonial({ customer_name: '', age_group: '', testimonial_text: '', rating: 5, teller_name: '', is_visible: 1 })} className={btnPrimary}>+ 新規追加</button>
                             </div>
                             <div className="overflow-y-auto flex-1 custom-scrollbar">
                                 <table className="w-full text-sm text-left text-gray-300">
                                     <thead className="bg-gray-900 text-gray-500 sticky top-0"><tr className="border-b border-gray-700"><th className="p-4 w-40">お名前 / 年代</th><th className="p-4 w-32">対象鑑定師</th><th className="p-4">レビュー内容</th><th className="p-4 w-20 text-center">公開</th><th className="p-4 w-24 text-right">操作</th></tr></thead>
                                     <tbody className="divide-y divide-gray-700">
                                         {testimonials.map(t => ( 
                                            <tr key={t.id} className="hover:bg-gray-700/50">
                                                <td className="p-4"><div className="font-bold text-white">{t.customer_name}</div><div className="text-[10px] text-gray-500">{t.age_group}</div></td>
                                                <td className="p-4 text-xs font-bold text-yellow-500">{t.teller_name}</td>
                                                <td className="p-4"><div className="flex text-yellow-500 mb-1">{[...Array(t.rating||5)].map((_,i)=><Icons.Star key={i} className="w-3 h-3 fill-current"/>)}</div><p className="line-clamp-2 text-xs">{t.testimonial_text}</p></td>
                                                <td className="p-4 text-center">{parseInt(t.is_visible) ? <span className="text-green-400">●</span> : <span className="text-gray-600">●</span>}</td>
                                                <td className="p-4 text-right"><button onClick={() => setEditingTestimonial(t)} className="text-blue-400 mr-3"><Icons.PenTool className="w-4 h-4"/></button><button onClick={() => handleDelete('delete_testimonial', t.id, '削除しました')} className="text-red-400"><Icons.Trash className="w-4 h-4"/></button></td>
                                            </tr> 
                                        ))}
                                        {testimonials.length === 0 && <tr><td colSpan="5" className="p-8 text-center text-gray-500">レビューがありません</td></tr>}
                                     </tbody>
                                 </table>
                             </div>
                         </>
                        ) : (
                            <form onSubmit={(e) => { e.preventDefault(); handleSave('save_testimonial', editingTestimonial, setEditingTestimonial, 'レビューを保存しました'); }} className="flex flex-col h-full bg-gray-900/50">
                                <div className="p-6 overflow-y-auto flex-1 space-y-5 pb-24">
                                    <h4 className="font-bold text-yellow-500 border-b border-gray-700 pb-3">{editingTestimonial.id ? 'お客様の声の編集' : 'お客様の声の追加'}</h4>
                                    <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
                                        <div><label className="text-xs text-gray-400 font-bold block mb-2">お名前 (仮名可) *</label><input required className={inputClass} value={editingTestimonial.customer_name} onChange={e=>setEditingTestimonial({...editingTestimonial, customer_name: e.target.value})} /></div>
                                        <div><label className="text-xs text-gray-400 font-bold block mb-2">年代・性別</label><input className={inputClass} value={editingTestimonial.age_group} onChange={e=>setEditingTestimonial({...editingTestimonial, age_group: e.target.value})} placeholder="30代 女性" /></div>
                                        <div>
                                            <label className="text-xs text-gray-400 font-bold block mb-2">対象の鑑定師</label>
                                            <select className={inputClass} value={editingTestimonial.teller_name} onChange={e=>setEditingTestimonial({...editingTestimonial, teller_name: e.target.value})}>
                                                <option value="">指定なし</option>
                                                {tellers.map(t => <option key={t.id} value={`${t.name} 先生`}>{t.name} 先生</option>)}
                                            </select>
                                        </div>
                                        <div><label className="text-xs text-gray-400 font-bold block mb-2">評価 (1〜5) *</label><input type="number" min="1" max="5" required className={inputClass} value={editingTestimonial.rating} onChange={e=>setEditingTestimonial({...editingTestimonial, rating: parseInt(e.target.value) || 5})} /></div>
                                    </div>
                                    <div><label className="text-xs text-gray-400 font-bold block mb-2">レビュー内容 *</label><textarea required className={`${inputClass} h-32 resize-none`} value={editingTestimonial.testimonial_text} onChange={e=>setEditingTestimonial({...editingTestimonial, testimonial_text: e.target.value})}></textarea></div>
                                    <label className="flex items-center gap-3 mt-2"><input type="checkbox" checked={parseInt(editingTestimonial.is_visible) === 1} onChange={e=>setEditingTestimonial({...editingTestimonial, is_visible: e.target.checked ? 1 : 0})} className="w-5 h-5 text-yellow-600 bg-gray-900 border-gray-600 rounded" /><span className="text-sm font-bold">公開する (承認)</span></label>
                                </div>
                                <div className="p-4 bg-gray-900 border-t border-gray-800 shrink-0 flex justify-end gap-4 absolute bottom-0 left-0 w-full shadow-[0_-10px_20px_rgba(0,0,0,0.5)]">
                                    <button type="button" onClick={() => setEditingTestimonial(null)} className={btnCancel}>キャンセル</button>
                                    <button type="submit" className={btnPrimary}>保存する</button>
                                </div>
                            </form>
                        )}
                    </div>
                )}

                {/* 【復元】FAQ管理 */}
                {activeSubTab === 'faqs' && isAdmin && (
                    <div className="animate-fade-in flex flex-col h-full">
                        {!editingFaq ? (
                             <>
                             <div className="flex justify-between items-center p-4 border-b border-gray-700 shrink-0">
                                 <h4 className="text-white font-bold">よくある質問 (FAQ) 一覧</h4>
                                 <button onClick={() => setEditingFaq({ question: '', answer: '', sort_order: 0, is_visible: 1 })} className={btnPrimary}>+ 新規追加</button>
                             </div>
                             <div className="overflow-y-auto flex-1 custom-scrollbar">
                                 <table className="w-full text-sm text-left text-gray-300">
                                     <thead className="bg-gray-900 text-gray-500 sticky top-0"><tr className="border-b border-gray-700"><th className="p-4 w-16 text-center">順序</th><th className="p-4">質問 / 回答</th><th className="p-4 w-20 text-center">公開</th><th className="p-4 w-24 text-right">操作</th></tr></thead>
                                     <tbody className="divide-y divide-gray-700">
                                         {faqs.map(f => ( 
                                            <tr key={f.id} className="hover:bg-gray-700/50">
                                                <td className="p-4 text-center font-bold font-mono text-gray-400">{f.sort_order}</td>
                                                <td className="p-4">
                                                    <div className="font-bold text-yellow-400 mb-1.5 flex items-start gap-2"><span className="text-yellow-600">Q.</span> {f.question}</div>
                                                    <div className="text-xs text-gray-300 flex items-start gap-2"><span className="text-gray-500 font-bold">A.</span> <span className="line-clamp-2">{f.answer}</span></div>
                                                </td>
                                                <td className="p-4 text-center">{parseInt(f.is_visible) ? <span className="text-green-400">●</span> : <span className="text-gray-600">●</span>}</td>
                                                <td className="p-4 text-right"><button onClick={() => setEditingFaq(f)} className="text-blue-400 mr-3"><Icons.PenTool className="w-4 h-4"/></button><button onClick={() => handleDelete('delete_faq', f.id, '削除しました')} className="text-red-400"><Icons.Trash className="w-4 h-4"/></button></td>
                                            </tr> 
                                        ))}
                                        {faqs.length === 0 && <tr><td colSpan="4" className="p-8 text-center text-gray-500">FAQがありません</td></tr>}
                                     </tbody>
                                 </table>
                             </div>
                         </>
                        ) : (
                            <form onSubmit={(e) => { e.preventDefault(); handleSave('save_faq', editingFaq, setEditingFaq, 'FAQを保存しました'); }} className="flex flex-col h-full bg-gray-900/50">
                                <div className="p-6 overflow-y-auto flex-1 space-y-5 pb-24">
                                    <h4 className="font-bold text-yellow-500 border-b border-gray-700 pb-3">{editingFaq.id ? 'FAQの編集' : 'FAQの追加'}</h4>
                                    <div><label className="text-xs text-gray-400 font-bold block mb-2">質問 (Q) *</label><input required className={inputClass} value={editingFaq.question} onChange={e=>setEditingFaq({...editingFaq, question: e.target.value})} /></div>
                                    <div><label className="text-xs text-gray-400 font-bold block mb-2">回答 (A) *</label><textarea required className={`${inputClass} h-32 resize-none`} value={editingFaq.answer} onChange={e=>setEditingFaq({...editingFaq, answer: e.target.value})}></textarea></div>
                                    <div className="w-1/3"><label className="text-xs text-gray-400 font-bold block mb-2">表示順序 (数字が小さいほど上)</label><input type="number" required className={inputClass} value={editingFaq.sort_order} onChange={e=>setEditingFaq({...editingFaq, sort_order: parseInt(e.target.value) || 0})} /></div>
                                    <label className="flex items-center gap-3 mt-2"><input type="checkbox" checked={parseInt(editingFaq.is_visible) === 1} onChange={e=>setEditingFaq({...editingFaq, is_visible: e.target.checked ? 1 : 0})} className="w-5 h-5 text-yellow-600 bg-gray-900 border-gray-600 rounded" /><span className="text-sm font-bold">公開する</span></label>
                                </div>
                                <div className="p-4 bg-gray-900 border-t border-gray-800 shrink-0 flex justify-end gap-4 absolute bottom-0 left-0 w-full shadow-[0_-10px_20px_rgba(0,0,0,0.5)]">
                                    <button type="button" onClick={() => setEditingFaq(null)} className={btnCancel}>キャンセル</button>
                                    <button type="submit" className={btnPrimary}>保存する</button>
                                </div>
                            </form>
                        )}
                    </div>
                )}
            </div>
        </div>
    );
};

const AdminViewApp = () => {
    const [isLoggedIn, setIsLoggedIn] = useState(false); 
    const [authUser, setAuthUser] = useState(null); 
    const [userid, setUserid] = useState(''); 
    const [password, setPassword] = useState('');
    const [sessionChecked, setSessionChecked] = useState(false);
    
    const [activeTab, setActiveTab] = useState(() => {
        if (typeof window !== 'undefined') {
            const params = new URLSearchParams(window.location.search);
            return params.get('tab') || 'schedule';
        }
        return 'schedule';
    });
    
    const [tellers, setTellers] = useState([]); 
    const [bookings, setBookings] = useState([]); 
    const [selectedTellerId, setSelectedTellerId] = useState(null); 
    const [viewingBooking, setViewingBooking] = useState(null);
    
    const [showForm, setShowForm] = useState(false); 
    const [editingTeller, setEditingTeller] = useState(null);

    const [toast, setToast] = useState(null);

    const isAdmin = authUser && parseInt(authUser.is_admin) === 1;

    const showToast = (message, type = 'success') => setToast({ message, type, id: Date.now() });

    // 🟡 ページリロード時にセッション復帰
    useEffect(() => {
        fetchApi('check_session').then(res => {
            if (res && res.logged_in && res.user) {
                setAuthUser(res.user);
                setIsLoggedIn(true);
                if (parseInt(res.user.is_admin) === 0) { setSelectedTellerId(res.user.id); }
            }
            setSessionChecked(true);
        }).catch(() => setSessionChecked(true));
    }, []);

    const handleTabChange = (tab) => {
        setActiveTab(tab);
        if (typeof window !== 'undefined') {
            const url = new URL(window.location.href);
            url.searchParams.set('tab', tab);
            window.history.replaceState({}, '', url);
        }
    };

    const fetchData = () => { 
        fetchApi('fortune_tellers_admin').then(data => { 
            setTellers(data); 
            if(data.length > 0 && !selectedTellerId) { 
                if (authUser && parseInt(authUser.is_admin) === 0) { setSelectedTellerId(authUser.id); } 
                else { setSelectedTellerId(data[0].id); } 
            } 
        }); 
        fetchApi('bookings_admin').then(setBookings); 
    };

    useEffect(() => { if (isLoggedIn && authUser) fetchData(); }, [isLoggedIn, authUser]);

    const handleLogin = async (e) => { 
        e.preventDefault(); 
        const res = await fetchApi('login', { method: 'POST', body: JSON.stringify({ userid, password }) }); 
        if (res.success) { 
            setAuthUser(res.user); 
            if (parseInt(res.user.is_admin) === 0) { setSelectedTellerId(res.user.id); } 
            setIsLoggedIn(true); 
            showToast('ログインしました');
        } else { 
            showToast(res.message, 'error'); 
        } 
    };

    const handleSaveTeller = async (data) => { 
        const action = editingTeller ? 'update_teller' : 'create_teller'; 
        const payload = editingTeller ? { ...data, id: editingTeller.id } : data; 
        await fetchApi(action, { method: 'POST', body: JSON.stringify(payload) }); 
        fetchData(); 
        setShowForm(false); 
        setEditingTeller(null); 
    };

    const toggleVisibility = async (id, current) => { 
        const nextVal = parseInt(current) === 1 ? 0 : 1; 
        await fetchApi('toggle_visibility', { method: 'POST', body: JSON.stringify({ id, is_visible: nextVal }) }); 
        fetchData(); 
        showToast(nextVal ? '公開にしました' : '非公開にしました');
    };

    if (!isLoggedIn) {
        return ( 
            <div className="min-h-screen bg-gray-950 flex items-center justify-center p-4 relative z-50">
                {toast && <Toast message={toast.message} type={toast.type} onClose={() => setToast(null)} />}
                <div className="absolute inset-0 bg-[radial-gradient(ellipse_at_center,_var(--tw-gradient-stops))] from-yellow-900/20 via-gray-950 to-gray-950 pointer-events-none"></div>
                <div className="bg-gray-900/90 backdrop-blur-md p-10 rounded-3xl border border-gray-800 w-full max-w-md shadow-[0_0_50px_rgba(0,0,0,0.8)] animate-slide-down relative z-10">
                    <div className="text-center mb-10">
                        <div className="w-20 h-20 bg-gray-950 rounded-full flex items-center justify-center mx-auto mb-4 border border-gray-800 shadow-inner">
                            <window.DragonIcon className="w-10 h-10 text-yellow-500 drop-shadow-[0_0_10px_rgba(234,179,8,0.5)]" />
                        </div>
                        <h2 className="text-2xl font-serif font-bold text-white tracking-widest">管理パネル</h2>
                    </div>
                    <form onSubmit={handleLogin} className="space-y-5">
                        <div>
                            <label className="text-xs text-gray-500 font-bold tracking-widest mb-1.5 block">LOGIN ID</label>
                            <input required className="w-full bg-gray-950 border border-gray-800 rounded-xl p-3.5 text-white focus:border-yellow-600 focus:ring-1 outline-none" value={userid} onChange={e=>setUserid(e.target.value)} />
                        </div>
                        <div>
                            <label className="text-xs text-gray-500 font-bold tracking-widest mb-1.5 block">PASSWORD</label>
                            <input required type="password" className="w-full bg-gray-950 border border-gray-800 rounded-xl p-3.5 text-white focus:border-yellow-600 focus:ring-1 outline-none" value={password} onChange={e=>setPassword(e.target.value)} />
                        </div>
                        <div className="pt-4">
                            <button type="submit" className="w-full bg-gradient-to-r from-yellow-600 to-yellow-500 text-gray-900 font-black tracking-widest py-4 rounded-xl hover:shadow-[0_0_20px_rgba(234,179,8,0.3)] transition-all active:scale-95">LOGIN</button>
                        </div>
                        <button type="button" onClick={() => window.location.reload()} className="w-full text-gray-500 text-sm py-2 hover:text-gray-300">サイトに戻る</button>
                    </form>
                </div>
            </div> 
        );
    }

    return (
        <div className="min-h-screen bg-gray-950 text-gray-200 flex flex-col relative z-50 pt-[72px] md:pt-0">
            {toast && <Toast key={toast.id} message={toast.message} type={toast.type} onClose={() => setToast(null)} />}
            
            <header className="fixed top-0 left-0 w-full md:static bg-gray-900 border-b border-gray-800 p-4 flex justify-between items-center z-40 shadow-md">
                <div className="flex items-center gap-3 pl-2">
                    <window.DragonIcon className="w-6 h-6 text-yellow-500"/>
                    <span className="font-bold text-white tracking-widest font-serif text-lg">管理パネル</span>
                    <span className="text-xs text-yellow-600 font-bold bg-yellow-600/10 px-2 py-1 rounded border border-yellow-600/30 ml-2">{isAdmin ? '管理者権限' : authUser.name}</span>
                </div>
                <div className="flex items-center gap-4 pr-2">
                    <button onClick={() => { fetchData(); showToast('データを最新に更新しました'); }} className="text-gray-400 hover:text-yellow-400 transition-colors p-2"><Icons.Refresh className="w-5 h-5"/></button>
                    <button onClick={() => { fetchApi('logout').then(() => { setIsLoggedIn(false); setAuthUser(null); window.location.reload(); }); }} className="text-sm text-gray-400 hover:text-white font-bold tracking-widest border border-gray-700 px-4 py-1.5 rounded-lg hover:bg-gray-800">ログアウト</button>
                </div>
            </header>
            
            <div className="flex flex-1 overflow-hidden">
                <div className="w-64 bg-gray-900/50 border-r border-gray-800 flex-col hidden md:flex backdrop-blur-sm">
                    <div className="p-4 space-y-2">
                        <button onClick={() => handleTabChange('schedule')} className={`w-full text-left p-3.5 rounded-xl font-bold transition-all relative overflow-hidden flex items-center gap-3 ${activeTab === 'schedule' ? 'text-yellow-400 bg-yellow-400/10 border-yellow-400/30' : 'text-gray-400 hover:bg-gray-800 border-transparent'}`}>
                            <span className="text-xl">📅</span><span>スケジュール</span>
                        </button>
                        
                        {isAdmin && (
                            <button onClick={() => handleTabChange('tellers')} className={`w-full text-left p-3.5 rounded-xl font-bold transition-all relative overflow-hidden flex items-center gap-3 ${activeTab === 'tellers' ? 'text-yellow-400 bg-yellow-400/10 border-yellow-400/30' : 'text-gray-400 hover:bg-gray-800 border-transparent'}`}>
                                <span className="text-xl">🔮</span><span>鑑定師管理</span>
                            </button>
                        )}
                        
                        {!isAdmin && (
                            <button onClick={() => { setEditingTeller(tellers.find(t=>t.id===authUser.id)); setShowForm(true); }} className={`w-full text-left p-3.5 rounded-xl font-bold transition-all flex items-center gap-3 text-gray-400 hover:bg-gray-800`}>
                                <span className="text-xl">👤</span><span>プロフィール編集</span>
                            </button>
                        )}
                        
                        <button onClick={() => handleTabChange('analytics')} className={`w-full text-left p-3.5 rounded-xl font-bold transition-all relative overflow-hidden flex items-center gap-3 ${activeTab === 'analytics' ? (isAdmin ? 'text-yellow-400 bg-yellow-400/10' : 'text-green-400 bg-green-400/10') : 'text-gray-400 hover:bg-gray-800'}`}>
                            <span className="text-xl">{isAdmin ? '📊' : '💰'}</span><span>{isAdmin ? '売上分析' : '今月の報酬明細'}</span>
                        </button>
                        
                        <button onClick={() => handleTabChange('customers')} className={`w-full text-left p-3.5 rounded-xl font-bold transition-all relative overflow-hidden flex items-center gap-3 ${activeTab === 'customers' ? 'text-red-400 bg-red-400/10' : 'text-gray-400 hover:bg-gray-800'}`}>
                            <span className="text-xl">⚠</span><span>顧客管理</span>
                        </button>
                        
                        {isAdmin && <button onClick={() => handleTabChange('coupons')} className={`w-full text-left p-3.5 rounded-xl font-bold transition-all relative flex items-center gap-3 ${activeTab === 'coupons' ? 'text-yellow-400 bg-yellow-400/10' : 'text-gray-400 hover:bg-gray-800'}`}><span className="text-xl">🎫</span><span>クーポン管理</span></button>}
                        
                        <button onClick={() => handleTabChange('contents')} className={`w-full text-left p-3.5 rounded-xl font-bold transition-all relative flex items-center gap-3 ${activeTab === 'contents' ? 'text-yellow-400 bg-yellow-400/10' : 'text-gray-400 hover:bg-gray-800'}`}><span className="text-xl">📝</span><span>コンテンツ管理</span></button>
                    </div>
                </div>
                
                <div className="flex-1 flex flex-col p-4 md:p-6 bg-gray-950 overflow-hidden relative">
                    <div className="md:hidden flex overflow-x-auto custom-scrollbar bg-gray-900 border border-gray-800 shrink-0 mb-4 rounded-xl shadow-inner px-2 py-1">
                        <button onClick={() => handleTabChange('schedule')} className={`p-3 text-sm whitespace-nowrap font-bold ${activeTab === 'schedule' ? 'text-yellow-400' : 'text-gray-500'}`}>スケジュール</button>
                        {isAdmin && <button onClick={() => handleTabChange('tellers')} className={`p-3 text-sm whitespace-nowrap font-bold ${activeTab === 'tellers' ? 'text-yellow-400' : 'text-gray-500'}`}>鑑定師管理</button>}
                        <button onClick={() => handleTabChange('analytics')} className={`p-3 text-sm whitespace-nowrap font-bold ${activeTab === 'analytics' ? 'text-yellow-400' : 'text-gray-500'}`}>{isAdmin ? '売上分析' : '報酬明細'}</button>
                        <button onClick={() => handleTabChange('customers')} className={`p-3 text-sm whitespace-nowrap font-bold ${activeTab === 'customers' ? 'text-red-400' : 'text-gray-500'}`}>顧客管理</button>
                        {isAdmin && <button onClick={() => handleTabChange('coupons')} className={`p-3 text-sm whitespace-nowrap font-bold ${activeTab === 'coupons' ? 'text-yellow-400' : 'text-gray-500'}`}>クーポン</button>}
                        <button onClick={() => handleTabChange('contents')} className={`p-3 text-sm whitespace-nowrap font-bold ${activeTab === 'contents' ? 'text-yellow-400' : 'text-gray-500'}`}>コンテンツ</button>
                    </div>

                    {activeTab === 'schedule' && isAdmin && (
                        <div className="p-4 bg-gray-900 border border-gray-800 rounded-xl shrink-0 mb-4 shadow-sm flex flex-col md:flex-row md:items-center justify-between gap-3">
                            <div className="text-[10px] md:text-xs text-gray-500 font-bold uppercase tracking-widest">表示する占い師を選択</div>
                            <select value={selectedTellerId || ''} onChange={(e) => setSelectedTellerId(Number(e.target.value))} className="w-full md:w-auto min-w-[250px] bg-gray-950 border border-gray-700 rounded-lg p-3 md:p-2 text-white focus:border-yellow-500 outline-none font-bold">
                                {tellers.map(t => <option key={t.id} value={t.id}>{t.name} (スケジュール)</option>)}
                            </select>
                        </div>
                    )}

                    {activeTab === 'schedule' ? (
                        <div className="flex-1 min-h-0 animate-fade-in shadow-2xl rounded-xl">
                            <AdminScheduleTable 
                                selectedTeller={tellers.find(t=>t.id===selectedTellerId)} 
                                bookings={bookings} 
                                onBookingClick={setViewingBooking} 
                                showToast={showToast}
                                onBookingDrop={(id, date, time) => {
                                    if (!confirm(`予約日時を ${date} ${time} に変更しますか？\n※お客様には自動で通知されませんので別途ご連絡ください。`)) return;
                                    fetchApi('update_booking_time', { method: 'POST', body: JSON.stringify({ id, booking_date: `${date} ${time}:00` }) })
                                        .then(() => { fetchData(); showToast('予約日時を変更しました'); });
                                }}
                                onToggleHoliday={(date) => {
                                    fetchApi('toggle_holiday', { method: 'POST', body: JSON.stringify({ teller_id: selectedTellerId, date }) })
                                        .then(fetchData);
                                }}
                            />
                        </div>
                    ) : (
                        <div className="flex-1 overflow-y-auto custom-scrollbar pr-1">
                            {activeTab === 'analytics' && <div className="animate-fade-in"><AdminAnalytics tellers={tellers} bookings={bookings} authUser={authUser} isAdmin={isAdmin} /></div>}
                            {activeTab === 'customers' && <div className="animate-fade-in"><AdminCustomers showToast={showToast} /></div>}
                            {activeTab === 'coupons' && isAdmin && <div className="animate-fade-in"><AdminCoupons showToast={showToast} /></div>}
                            {activeTab === 'contents' && <div className="animate-fade-in"><AdminContents tellers={tellers} authUser={authUser} isAdmin={isAdmin} showToast={showToast} /></div>}
                            {activeTab === 'tellers' && isAdmin && <AdminTellers tellers={tellers} onEdit={(t) => {setEditingTeller(t); setShowForm(true);}} onToggleVisibility={toggleVisibility} onAddNew={() => {setEditingTeller(null); setShowForm(true);}} />}
                        </div>
                    )}
                </div>
            </div>
            
            {showForm && <TellerForm initialData={editingTeller} onSave={handleSaveTeller} onClose={() => { setShowForm(false); setEditingTeller(null); }} isAdmin={isAdmin} showToast={showToast} />}
            
            <AdminBookingModal 
                booking={viewingBooking} 
                teller={viewingBooking ? tellers.find(t => t.id == viewingBooking.fortune_teller_id) : null}
                onClose={() => setViewingBooking(null)} 
                onUpdateStatus={(id, st) => { 
                    fetchApi('booking_status', {method:'POST', body:JSON.stringify({id, status:st})}).then(() => { fetchData(); showToast('ステータスを更新しました'); }); 
                    setViewingBooking(null); 
                }} 
                onRequestExtension={(id, fee) => { 
                    fetchApi('request_extension', {method: 'POST', body: JSON.stringify({id, fee})}).then(() => { 
                        fetchData(); showToast('延長を許可しました。お客様の支払いを待ちます'); 
                        setViewingBooking(prev => ({...prev, extension_status: 'pending', extension_fee: fee})); 
                    }); 
                }} 
            />
        </div>
    );
};

if (typeof window !== 'undefined') window.AdminView = AdminViewApp;