import React, { useEffect, useMemo, useState } from 'react';
import { createRoot } from 'react-dom/client';
import {
  Banknote, BatteryCharging, Beef, BriefcaseBusiness, Building2, Car,
  Coffee, Dumbbell, Factory, Home, MapPin, Moon, Package, RotateCcw, Save,
  School, ShoppingCart, Smile, Store, Trees, Trophy, Utensils, Waves, Wrench
} from 'lucide-react';
import './styles.css';

const tg = window.Telegram?.WebApp;
const SAVE_KEY = 'life-district-save-v3-strength-minigames';

const START_PLAYER = {
  name: 'Alex', level: 1, money: 480, hunger: 76, energy: 84, mood: 72, strength: 1,
  day: 1, hour: 8, position: 'home', home: 'home', rentDueIn: 3,
  inventory: { groceries: 0 }, owned: [], career: 'Безработный',
  log: ['Ты приехал в Life District с €480 и планом стать богачом.']
};

const PLACES = [
  { id: 'business', title: 'Бизнес-центр', icon: BriefcaseBusiness, kind: 'work', grid: [1, 1, 1, 1], visual: 'skyscrapers', wage: 92, energyCost: 26, hungerCost: 16, desc: 'Высокие офисные башни. Работа через мини-игру сортировки задач.' },
  { id: 'mall', title: 'Торговый центр', icon: Store, kind: 'shop', grid: [2, 1, 1, 1], visual: 'mall', price: 14, desc: 'Большой молл. Покупки через мини-игру поиска товаров.' },
  { id: 'luxury', title: 'Элитные апартаменты', icon: Building2, kind: 'asset', grid: [3, 1, 1, 1], visual: 'luxury', price: 1500, income: 120, desc: 'Высокие жилые башни. Дорогой актив с пассивным доходом.' },
  { id: 'university', title: 'Университет', icon: School, kind: 'rest', grid: [4, 1, 1, 1], visual: 'university', desc: 'Кампус. Отдых через мини-игру концентрации.' },
  { id: 'hospital', title: 'Больница', icon: Beef, kind: 'rest', grid: [1, 2, 1, 1], visual: 'hospital', desc: 'Городская больница. Восстановление через мини-игру терапии.' },
  { id: 'park', title: 'Центральный парк', icon: Trees, kind: 'park', grid: [2, 2, 2, 1], visual: 'park', desc: 'Большой парк на два квадрата: озеро, фонтан, деревья, дорожки.' },
  { id: 'restaurants', title: 'Рестораны', icon: Utensils, kind: 'food', grid: [4, 2, 1, 1], visual: 'restaurants', price: 28, desc: 'Быстро поесть. Мини-игра: собери продукты 3 в ряд.' },
  { id: 'home', title: 'Жилой район', icon: Home, kind: 'home', grid: [5, 2, 1, 1], visual: 'residential', rent: 65, desc: 'Твоя первая квартира. Сон, готовка и зарядка дома.' },
  { id: 'supermarket', title: 'Супермаркет', icon: ShoppingCart, kind: 'shop', grid: [1, 3, 1, 1], visual: 'supermarket', price: 12, desc: 'Дешёвые продукты. Мини-игра: найди нужные товары.' },
  { id: 'dealer', title: 'Автосалон', icon: Car, kind: 'asset', grid: [2, 3, 1, 1], visual: 'dealer', price: 1350, income: 105, desc: 'Бизнес-объект. Позже здесь будут машины.' },
  { id: 'service', title: 'Автосервис', icon: Wrench, kind: 'asset', grid: [3, 3, 1, 1], visual: 'service', price: 1200, income: 98, desc: 'Автосервис. Ремонт через мини-игру деталей.' },
  { id: 'factory', title: 'Завод', icon: Factory, kind: 'asset', grid: [4, 3, 2, 2], visual: 'factory', price: 4200, income: 380, desc: 'Огромный завод на 4 квадрата с трубами и резервуарами.' },
  { id: 'bank', title: 'Банк', icon: Banknote, kind: 'asset', grid: [1, 4, 1, 1], visual: 'bank', price: 2100, income: 180, desc: 'Финансовый актив. Позже: кредиты, вклады, налоги.' },
  { id: 'office', title: 'Офисы', icon: BriefcaseBusiness, kind: 'work', grid: [2, 4, 1, 1], visual: 'office', wage: 78, energyCost: 23, hungerCost: 14, desc: 'Офисная работа. Мини-игра: обработка документов.' },
  { id: 'warehouse', title: 'Склады', icon: Package, kind: 'work', grid: [3, 4, 1, 1], visual: 'warehouse', wage: 70, energyCost: 28, hungerCost: 18, desc: 'Физическая работа. Сила повышает награду.' },
  { id: 'gym', title: 'Спортзал', icon: Dumbbell, kind: 'gym', grid: [1, 5, 1, 1], visual: 'gym', price: 18, desc: 'Тренировка силы. Быстрее, чем зарядка дома.' },
  { id: 'pier', title: 'Причал', icon: Waves, kind: 'rest', grid: [2, 5, 1, 1], visual: 'pier', desc: 'Портовая зона, лодки и морской воздух.' },
  { id: 'beach', title: 'Пляж', icon: Coffee, kind: 'park', grid: [3, 5, 1, 1], visual: 'beach', desc: 'Пляж. Восстанавливает настроение через мини-игру отдыха.' },
  { id: 'oil', title: 'Нефтебаза', icon: Factory, kind: 'asset', grid: [4, 5, 2, 1], visual: 'oil', price: 2800, income: 240, desc: 'Промышленный объект у воды. Выглядит опасно, пахнет деньгами.' }
];

const clamp = (v) => Math.max(0, Math.min(100, Math.round(v)));
const euro = (v) => `€${Math.round(v)}`;
const icons = ['🍔', '🥦', '🥤', '🍕', '🍎'];

function safeLoadPlayer() {
  try {
    const saved = localStorage.getItem(SAVE_KEY) || localStorage.getItem('life-district-save-v2');
    if (!saved) return START_PLAYER;
    return { ...START_PLAYER, ...JSON.parse(saved), inventory: { ...START_PLAYER.inventory, ...(JSON.parse(saved).inventory || {}) } };
  } catch { return START_PLAYER; }
}

function makeBoard(size = 16) { return Array.from({ length: size }, (_, i) => ({ id: `${Date.now()}-${i}-${Math.random()}`, icon: icons[Math.floor(Math.random() * icons.length)], selected: false })); }
function makeTargets() { return icons.slice(0, 3).map(icon => ({ icon, need: 2, got: 0 })); }

function BuildingVisual({ type }) {
  if (type === 'skyscrapers' || type === 'luxury') return <div className={`visual towersVisual ${type}`}><i/><i/><i/><b/></div>;
  if (type === 'park') return <div className="visual parkVisual"><span/><b/><i/><i/><i/><i/></div>;
  if (type === 'factory') return <div className="visual factoryVisual"><i/><span className="pipe p1"/><span className="pipe p2"/><span className="pipe p3"/><b/><em/><strong/></div>;
  if (type === 'oil') return <div className="visual oilVisual"><i/><i/><i/><span/></div>;
  if (type === 'beach') return <div className="visual beachVisual"><span/><b/></div>;
  if (type === 'pier') return <div className="visual pierVisual"><span/><b/></div>;
  return <div className={`visual buildingVisual ${type}`}><i/><i/><i/><i/><span/></div>;
}

function MiniGame({ game, onDone, onCancel }) {
  const [score, setScore] = useState(0);
  const [board, setBoard] = useState(makeBoard());
  const [targets, setTargets] = useState(makeTargets());
  const [timer, setTimer] = useState(35);

  useEffect(() => {
    const id = setInterval(() => setTimer(t => Math.max(0, t - 1)), 1000);
    return () => clearInterval(id);
  }, []);

  useEffect(() => {
    if (timer === 0) finish();
  }, [timer]);

  const targetDone = targets.every(t => t.got >= t.need);

  function tapTile(tile) {
    let bonus = 0;
    setTargets(prev => prev.map(t => {
      if (t.icon === tile.icon && t.got < t.need) { bonus = 8; return { ...t, got: t.got + 1 }; }
      return t;
    }));
    setScore(s => s + 5 + bonus);
    setBoard(prev => prev.map(x => x.id === tile.id ? { ...x, icon: icons[Math.floor(Math.random() * icons.length)] } : x));
  }

  function qteHit(mult = 1) {
    setScore(s => s + Math.round((8 + Math.random() * 12) * mult));
  }

  function finish() {
    const success = game.type === 'match' ? (targetDone || score >= 80) : score >= 60;
    onDone({ success, score });
  }

  return <div className="modalBackdrop">
    <section className="miniGame panel">
      <div className="miniHead">
        <div><b>{game.title}</b><p>{game.desc}</p></div>
        <div className="timer">⏱ {timer}s</div>
      </div>
      <div className="miniScore"><Trophy size={18}/> Очки: {score}</div>
      {game.type === 'match' ? <>
        <div className="targets">{targets.map(t => <span key={t.icon}>{t.icon} {t.got}/{t.need}</span>)}</div>
        <div className="matchGrid">{board.map(tile => <button key={tile.id} onClick={() => tapTile(tile)}>{tile.icon}</button>)}</div>
      </> : <div className="qteBox">
        <p>{game.qteText}</p>
        <button onClick={() => qteHit(1)}>Попасть в ритм</button>
        <button onClick={() => qteHit(1.35)}>Идеальный тайминг</button>
        <button onClick={() => qteHit(.8)}>Быстрое действие</button>
      </div>}
      <div className="miniActions"><button className="secondary" onClick={onCancel}>Отмена</button><button onClick={finish}>Завершить действие</button></div>
    </section>
  </div>;
}

function App() {
  const [player, setPlayer] = useState(safeLoadPlayer);
  const [toast, setToast] = useState('');
  const [miniGame, setMiniGame] = useState(null);
  const currentPlace = useMemo(() => PLACES.find(p => p.id === player.position) || PLACES[0], [player.position]);

  useEffect(() => { tg?.ready?.(); tg?.expand?.(); tg?.setHeaderColor?.('#08111f'); tg?.setBackgroundColor?.('#08111f'); }, []);
  useEffect(() => { localStorage.setItem(SAVE_KEY, JSON.stringify(player)); }, [player]);

  function notify(text) {
    setToast(text);
    setPlayer(prev => ({ ...prev, log: [text, ...prev.log].slice(0, 8) }));
    window.clearTimeout(window.__lifeToastTimer);
    window.__lifeToastTimer = window.setTimeout(() => setToast(''), 2200);
  }

  function passTime(hours, patch = {}) {
    setPlayer(prev => {
      let hour = prev.hour + hours, day = prev.day;
      while (hour >= 24) { hour -= 24; day += 1; }
      const newDays = day - prev.day;
      let money = prev.money;
      let rentDueIn = prev.rentDueIn - newDays;
      const newLogs = [];
      if (newDays > 0 && prev.owned.length > 0) {
        const income = prev.owned.reduce((sum, id) => sum + (PLACES.find(p => p.id === id)?.income || 0), 0);
        money += income; newLogs.push(`Пассивный доход за день: ${euro(income)}.`);
      }
      if (rentDueIn <= 0) { const rent = PLACES.find(p => p.id === prev.home)?.rent || 65; money -= rent; rentDueIn = 3; newLogs.push(`Списана аренда: ${euro(rent)}.`); }
      return { ...prev, ...patch, day, hour, rentDueIn, money: Math.round(patch.money ?? money), hunger: clamp(patch.hunger ?? prev.hunger - hours * 3), energy: clamp(patch.energy ?? prev.energy - hours * 2), mood: clamp(patch.mood ?? prev.mood - hours), strength: Math.max(1, Math.round((patch.strength ?? prev.strength) * 10) / 10), log: [...newLogs.reverse(), ...prev.log].slice(0, 8) };
    });
  }

  function runMiniGame(config, reward) { setMiniGame({ ...config, reward }); }
  function finishMiniGame(result) { const { reward } = miniGame; setMiniGame(null); reward(result); }

  function moveTo(place) { setPlayer(prev => ({ ...prev, position: place.id, energy: clamp(prev.energy - 3), hunger: clamp(prev.hunger - 2), mood: clamp(prev.mood + (place.kind === 'park' ? 3 : 0)) })); }

  function work() {
    if (player.energy < 30 || player.hunger < 25) return notify('Слишком мало еды или энергии для работы.');
    const isPhysical = currentPlace.id === 'warehouse' || currentPlace.id === 'factory';
    runMiniGame({ title: `Работа: ${currentPlace.title}`, type: isPhysical ? 'qte' : 'match', desc: isPhysical ? 'Нажимай действия и набери минимум 60 очков.' : 'Собери нужные элементы, чтобы выполнить смену.', qteText: 'Таскай коробки, чини процессы, держи темп.' }, ({ success, score }) => {
      if (!success) return notify(`Смена провалена. Очки: ${score}. Награды нет.`);
      const strengthBonus = isPhysical ? player.strength * 4 : 0;
      const pay = Math.round((currentPlace.wage || 70) + strengthBonus + score * .18);
      passTime(4, { money: player.money + pay, hunger: clamp(player.hunger - (currentPlace.hungerCost || 15)), energy: clamp(player.energy - (currentPlace.energyCost || 25)), mood: clamp(player.mood - 5), career: 'Стажёр', level: Math.max(player.level, 2), strength: isPhysical ? player.strength + .15 : player.strength });
      notify(`Смена выполнена. Получено ${euro(pay)}.`);
    });
  }

  function eat() {
    if (player.money < currentPlace.price) return notify('Не хватает денег на еду.');
    runMiniGame({ title: 'Кафе: 3 в ряд', type: 'match', desc: 'Собери продукты для заказа. Чем лучше результат — тем больше настроение.' }, ({ success, score }) => {
      if (!success) return notify(`Заказ испорчен. Очки: ${score}. Деньги не списаны.`);
      passTime(1, { money: player.money - currentPlace.price, hunger: clamp(player.hunger + 40 + score * .08), mood: clamp(player.mood + 4 + score * .03) });
      notify(`Ты поел за ${euro(currentPlace.price)}. Очки мини-игры: ${score}.`);
    });
  }

  function buyGroceries() {
    if (player.money < currentPlace.price) return notify('Не хватает денег на продукты.');
    runMiniGame({ title: 'Супермаркет', type: 'match', desc: 'Собери список покупок: продукты, напитки, овощи.' }, ({ success, score }) => {
      if (!success) return notify(`Покупки не собраны. Очки: ${score}.`);
      const extra = score >= 110 ? 1 : 0;
      setPlayer(prev => ({ ...prev, money: prev.money - currentPlace.price, hunger: clamp(prev.hunger - 2), inventory: { ...prev.inventory, groceries: prev.inventory.groceries + 1 + extra } }));
      notify(`Куплены продукты за ${euro(currentPlace.price)}${extra ? ' + бонусный пакет' : ''}.`);
    });
  }

  function cook() {
    if (player.position !== player.home) return notify('Готовить можно только дома.');
    if (player.inventory.groceries < 1) return notify('Нет продуктов. Сначала зайди в супермаркет.');
    runMiniGame({ title: 'Готовка дома', type: 'match', desc: 'Собери ингредиенты, чтобы приготовить нормальную еду, а не грустный кирпич.' }, ({ success, score }) => {
      if (!success) return notify(`Еда сгорела. Очки: ${score}. Продукты сохранены.`);
      passTime(1, { inventory: { ...player.inventory, groceries: player.inventory.groceries - 1 }, hunger: clamp(player.hunger + 50 + score * .08), energy: clamp(player.energy - 4), mood: clamp(player.mood + 3) });
      notify('Ты приготовил еду дома. Дешево и эффективно.');
    });
  }

  function sleep() {
    if (player.position !== player.home) return notify('Спать можно только дома.');
    runMiniGame({ title: 'Сон', type: 'qte', desc: 'Настрой будильник и режим сна. Да, даже сон теперь работает, добро пожаловать в капитализм.', qteText: 'Поймай спокойный ритм сна.' }, ({ success, score }) => {
      passTime(8, { energy: success ? 100 : 82, hunger: clamp(player.hunger - 16), mood: clamp(player.mood + (success ? 8 : 2)) });
      notify(success ? 'Ты отлично поспал. Энергия восстановлена.' : `Сон был так себе. Очки: ${score}.`);
    });
  }

  function rest() {
    runMiniGame({ title: `Отдых: ${currentPlace.title}`, type: 'qte', desc: 'Восстанови настроение через короткую мини-игру.', qteText: 'Дыши. Не думай об аренде. Невозможно, но попытайся.' }, ({ success, score }) => {
      passTime(2, { energy: clamp(player.energy + 12 + score * .05), mood: clamp(player.mood + (success ? 18 : 8)), hunger: clamp(player.hunger - 7) });
      notify('Отдых завершён.');
    });
  }

  function gym() {
    if (player.money < currentPlace.price) return notify('Не хватает денег на спортзал.');
    if (player.energy < 22 || player.hunger < 18) return notify('Сначала поешь или отдохни. На пустом баке мышцы не растут.');
    runMiniGame({ title: 'Спортзал', type: 'qte', desc: 'Тренируйся по таймингу. Чем лучше очки — тем больше сила.', qteText: 'Жим, присед, тяга. Не урони штангу на самооценку.' }, ({ success, score }) => {
      if (!success) return notify(`Тренировка слабая. Очки: ${score}.`);
      const gain = Math.min(.7, .25 + score / 250);
      passTime(2, { money: player.money - currentPlace.price, strength: player.strength + gain, energy: clamp(player.energy - 24), hunger: clamp(player.hunger - 18), mood: clamp(player.mood + 8) });
      notify(`Сила выросла на +${gain.toFixed(1)}.`);
    });
  }

  function homeWorkout() {
    if (player.position !== player.home) return notify('Зарядку дома можно делать только дома.');
    if (player.energy < 16 || player.hunger < 15) return notify('Слишком мало энергии или еды для зарядки.');
    runMiniGame({ title: 'Зарядка дома', type: 'qte', desc: 'Бесплатная тренировка. Медленнее спортзала, но зато без людей, которые заняли тренажёр полотенцем.', qteText: 'Отжимания, пресс, планка.' }, ({ success, score }) => {
      if (!success) return notify(`Зарядка не зашла. Очки: ${score}.`);
      const gain = Math.min(.35, .12 + score / 500);
      passTime(1, { strength: player.strength + gain, energy: clamp(player.energy - 14), hunger: clamp(player.hunger - 10), mood: clamp(player.mood + 3) });
      notify(`Домашняя зарядка: сила +${gain.toFixed(1)}.`);
    });
  }

  function buyAsset() {
    if (player.owned.includes(currentPlace.id)) return notify('Этот объект уже твой.');
    if (player.money < currentPlace.price) return notify(`Нужно ${euro(currentPlace.price)}.`);
    runMiniGame({ title: `Покупка: ${currentPlace.title}`, type: 'qte', desc: 'Проверь документы сделки. Нельзя просто купить завод, не потыкав бумажки.', qteText: 'Подписи, счета, договоры, печати.' }, ({ success, score }) => {
      if (!success) return notify(`Сделка сорвалась. Очки: ${score}. Деньги сохранены.`);
      setPlayer(prev => ({ ...prev, money: prev.money - currentPlace.price, owned: [...prev.owned, currentPlace.id], mood: clamp(prev.mood + 8), level: Math.max(prev.level, 3) }));
      notify(`Куплено: ${currentPlace.title}.`);
    });
  }

  function save() { localStorage.setItem(SAVE_KEY, JSON.stringify(player)); notify('Игра сохранена.'); }
  function reset() { localStorage.removeItem(SAVE_KEY); setPlayer(START_PLAYER); setToast('Прогресс сброшен.'); }

  return <main className="app">
    {toast && <div className="toast">{toast}</div>}
    {miniGame && <MiniGame game={miniGame} onCancel={() => setMiniGame(null)} onDone={finishMiniGame} />}

    <header className="topbar">
      <section className="profileCard"><div className="avatar">A</div><div><b>{player.name}</b><span>Уровень {player.level}</span><small>День {player.day}, {String(player.hour).padStart(2, '0')}:00</small></div></section>
      <section className="statsRow">
        <div className="stat money"><Banknote size={18}/><b>{euro(player.money)}</b></div>
        <div className="stat"><BatteryCharging size={18}/><b>{player.energy}/100</b></div>
        <div className="stat"><Beef size={18}/><b>{player.hunger}/100</b></div>
        <div className="stat"><Smile size={18}/><b>{player.mood}/100</b></div>
        <div className="stat strength"><Dumbbell size={18}/><b>Сила {player.strength.toFixed(1)}</b></div>
      </section>
    </header>

    <section className="layout">
      <nav className="sideMenu panel">
        <button><BriefcaseBusiness/>Работа</button><button><Home/>Дом</button><button><Building2/>Бизнес</button><button><Car/>Транспорт</button>
      </nav>
      <section className="cityWrap panel">
        <div className="cityMap">
          <div className="roadGrid" />
          {PLACES.map(place => {
            const Icon = place.icon; const [c, r, cs, rs] = place.grid;
            return <button key={place.id} className={`lot ${player.position === place.id ? 'active' : ''} ${player.owned.includes(place.id) ? 'owned' : ''}`} style={{ gridColumn: `${c} / span ${cs}`, gridRow: `${r} / span ${rs}` }} onClick={() => moveTo(place)}>
              <BuildingVisual type={place.visual}/><span className="label"><Icon size={16}/>{place.title}</span>{player.position === place.id && <MapPin className="playerPin" size={38}/>} </button>;
          })}
        </div>
      </section>
    </section>

    <section className="bottomPanel panel">
      <div className="placeInfo"><h1>{currentPlace.title}</h1><p>{currentPlace.desc}</p><span>Позиция: {player.position}</span><span>Продукты: {player.inventory.groceries}</span><span>Аренда через: {player.rentDueIn} дн.</span></div>
      <div className="actions">
        {currentPlace.kind === 'work' && <button onClick={work}><BriefcaseBusiness size={18}/>Работать</button>}
        {currentPlace.kind === 'food' && <button onClick={eat}><Utensils size={18}/>Поесть</button>}
        {currentPlace.kind === 'shop' && <button onClick={buyGroceries}><ShoppingCart size={18}/>Купить продукты</button>}
        {currentPlace.kind === 'home' && <><button onClick={cook}><Utensils size={18}/>Готовить</button><button onClick={sleep}><Moon size={18}/>Спать</button><button onClick={homeWorkout}><Dumbbell size={18}/>Зарядка дома</button></>}
        {currentPlace.kind === 'gym' && <button onClick={gym}><Dumbbell size={18}/>Тренироваться</button>}
        {(currentPlace.kind === 'rest' || currentPlace.kind === 'park') && <button onClick={rest}><Smile size={18}/>Отдыхать</button>}
        {currentPlace.kind === 'asset' && <button onClick={buyAsset}><Building2 size={18}/>Купить {euro(currentPlace.price)}</button>}
        <button className="secondary" onClick={save}><Save size={18}/>Сохранить</button><button className="secondary" onClick={reset}><RotateCcw size={18}/>Сброс</button>
      </div>
    </section>

    <section className="cityLog panel">{player.log.map((item, i) => <p key={i}>• {item}</p>)}</section>
  </main>;
}

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