import * as THREE from 'three';

export class Player {
    constructor(game) {
        this.game = game;

        // Характеристики
        this.stats = {
            health: 100,
            hunger: 100,
            warmth: 100,
            mood: 50,
            money: 0,
            hygiene: 100
        };

        // Физика
        this.position = new THREE.Vector3(0, 0, 15);
        this.velocity = new THREE.Vector3();
        this.direction = new THREE.Vector3();
        this.speed = 5;
        this.sprintMultiplier = 1.7;
        this.height = 1.7;
        this.radius = 0.4;

        // Mesh
        this.mesh = null;
        this.nearestInteractable = null;

        // Таймеры
        this.statTimer = 0;
        this.isSleeping = false;
        this.sleepTimer = 0;
        this.isWarming = false;
        this._shelterSleep = false;

        // Begging
        this.isBegging = false;
        this.begTimer = 0;
        this.begCooldown = 0;
        this.begDuration = 3;

        // Busking
        this.isBusking = false;
        this.buskTimer = 0;
        this.buskCooldown = 0;
        this.buskDuration = 5;

        // Hygiene & Disease
        this.isDiseased = false;
        this.diseaseTimer = 0;
        this.diseaseCheckTimer = 0;
        this.washCooldown = 0;

        // Addiction
        this.addictionLevel = 0;
        this.withdrawalTimer = 0;
        this.lastDrinkTime = 0;

        // Шаги
        this.stepTimer = 0;
        this.stepInterval = 0.45;

        // Предыдущее здоровье
        this._prevHealth = 100;

        // Head bob
        this.bobPhase = 0;
        this.bobAmount = 0;

        // Stamina
        this.stamina = 100;
        this.maxStamina = 100;
        this.isSprinting = false;

        // Сытость 100 таймер (для ачивки)
        this._wellFedTimer = 0;
    }

    spawn() {
        this.createMesh();
        this.position.set(0, 0, 15);
        this.mesh.position.copy(this.position);
        this.game.camera.position.set(0, this.height, 15);
    }

    createMesh() {
        const group = new THREE.Group();

        const bodyGeo = new THREE.CylinderGeometry(0.3, 0.35, 1.0, 8);
        const bodyMat = new THREE.MeshStandardMaterial({ color: 0x5c4033 });
        const body = new THREE.Mesh(bodyGeo, bodyMat);
        body.position.y = 0.8;
        body.castShadow = true;
        group.add(body);

        const headGeo = new THREE.SphereGeometry(0.22, 8, 6);
        const headMat = new THREE.MeshStandardMaterial({ color: 0xd4a574 });
        const head = new THREE.Mesh(headGeo, headMat);
        head.position.y = 1.5;
        head.castShadow = true;
        group.add(head);

        const hatGeo = new THREE.CylinderGeometry(0.25, 0.28, 0.2, 8);
        const hatMat = new THREE.MeshStandardMaterial({ color: 0x333355 });
        const hat = new THREE.Mesh(hatGeo, hatMat);
        hat.position.y = 1.7;
        group.add(hat);

        const armMat = new THREE.MeshStandardMaterial({ color: 0x5c4033 });
        [-0.4, 0.4].forEach(side => {
            const armGeo = new THREE.CylinderGeometry(0.08, 0.08, 0.7, 6);
            const arm = new THREE.Mesh(armGeo, armMat);
            arm.position.set(side, 0.7, 0);
            arm.rotation.z = side > 0 ? -0.15 : 0.15;
            arm.castShadow = true;
            group.add(arm);
        });

        const legMat = new THREE.MeshStandardMaterial({ color: 0x333344 });
        [-0.15, 0.15].forEach(side => {
            const legGeo = new THREE.CylinderGeometry(0.1, 0.1, 0.6, 6);
            const leg = new THREE.Mesh(legGeo, legMat);
            leg.position.set(side, 0.3, 0);
            leg.castShadow = true;
            group.add(leg);
        });

        this.mesh = group;
        group.traverse(child => {
            if (child.isMesh) {
                child.castShadow = true;
                child.layers.set(1);
            }
        });
        this.game.scene.add(group);
    }

    reset() {
        if (this.mesh) {
            this.game.scene.remove(this.mesh);
        }
        this.stats = { health: 100, hunger: 100, warmth: 100, mood: 50, money: 0, hygiene: 100 };
        this.stamina = 100;
        this.isSleeping = false;
        this.isWarming = false;
        this.isBegging = false;
        this.begTimer = 0;
        this.begCooldown = 0;
        this.isBusking = false;
        this.buskTimer = 0;
        this.buskCooldown = 0;
        this.isDiseased = false;
        this.diseaseTimer = 0;
        this.diseaseCheckTimer = 0;
        this.washCooldown = 0;
        this.addictionLevel = 0;
        this.withdrawalTimer = 0;
        this.lastDrinkTime = 0;
        this.nearestInteractable = null;
        this._prevHealth = 100;
        this._shelterSleep = false;
        this._wellFedTimer = 0;
    }

    update(dt) {
        if (this.isSleeping) {
            this.updateSleep(dt);
            this.updateScreenEffects();
            return;
        }

        this.updateMovement(dt);
        this.updateStats(dt);
        this.updateBegging(dt);
        this.updateBusking(dt);
        this.checkInteractables();
        this.updateScreenEffects();
        this.checkDeath();
        this.trackLocations();

        if (this.begCooldown > 0) this.begCooldown -= dt;
        if (this.buskCooldown > 0) this.buskCooldown -= dt;
    }

    updateMovement(dt) {
        const keys = this.game.keys;
        const camera = this.game.camera;

        if (this.isBegging || this.isBusking) return;

        const forward = new THREE.Vector3();
        camera.getWorldDirection(forward);
        forward.y = 0;
        forward.normalize();

        const right = new THREE.Vector3();
        right.crossVectors(forward, new THREE.Vector3(0, 1, 0)).normalize();

        this.direction.set(0, 0, 0);
        if (keys['KeyW']) this.direction.add(forward);
        if (keys['KeyS']) this.direction.sub(forward);
        if (keys['KeyD']) this.direction.add(right);
        if (keys['KeyA']) this.direction.sub(right);

        if (this.direction.length() > 0) {
            this.direction.normalize();

            const wantSprint = keys['ShiftLeft'] || keys['ShiftRight'];
            const sprint = wantSprint && this.stamina > 0;
            this.isSprinting = sprint;

            if (sprint) {
                this.stamina = Math.max(0, this.stamina - 20 * dt);
            } else {
                this.stamina = Math.min(this.maxStamina, this.stamina + 10 * dt);
            }

            const moveSpeed = this.speed * (sprint ? this.sprintMultiplier : 1);

            let speedMod = 1;
            if (this.stats.hunger < 20) speedMod *= 0.7;
            if (this.stats.warmth < 15) speedMod *= 0.8;
            if (this.stats.health < 25) speedMod *= 0.6;
            if (this.isDiseased) speedMod *= 0.8;

            const newPos = this.position.clone().add(
                this.direction.clone().multiplyScalar(moveSpeed * speedMod * dt)
            );

            if (!this.checkCollision(newPos)) {
                this.position.copy(newPos);
            }

            if (this.game.interiors && this.game.interiors.isInside) {
                this.position.x = THREE.MathUtils.clamp(this.position.x, 490, 510);
                this.position.z = THREE.MathUtils.clamp(this.position.z, -10, 120);
            } else {
                this.position.x = THREE.MathUtils.clamp(this.position.x, -95, 95);
                this.position.z = THREE.MathUtils.clamp(this.position.z, -95, 95);
            }

            this.stepTimer += dt * (sprint ? 1.5 : 1);
            if (this.stepTimer >= this.stepInterval) {
                this.stepTimer = 0;
                this.game.sound.playStep();
            }

            this.bobPhase += dt * (sprint ? 14 : 10);
            this.bobAmount = THREE.MathUtils.lerp(this.bobAmount, 0.04, dt * 5);
        } else {
            this.bobAmount = THREE.MathUtils.lerp(this.bobAmount, 0, dt * 8);
            this.isSprinting = false;
            this.stamina = Math.min(this.maxStamina, this.stamina + 15 * dt);
        }

        this.mesh.position.copy(this.position);
        const bobY = Math.sin(this.bobPhase) * this.bobAmount;

        // Withdrawal tremor
        let tremorX = 0, tremorY = 0;
        if (this.addictionLevel > 40 && this.withdrawalTimer > 0) {
            const intensity = Math.min(0.02, this.addictionLevel * 0.0003);
            tremorX = (Math.random() - 0.5) * intensity;
            tremorY = (Math.random() - 0.5) * intensity;
        }

        this.game.camera.position.set(
            this.position.x + tremorX,
            this.position.y + this.height + bobY + tremorY,
            this.position.z
        );

        const camDir = new THREE.Vector3();
        camera.getWorldDirection(camDir);
        this.mesh.rotation.y = Math.atan2(camDir.x, camDir.z);
    }

    checkCollision(newPos) {
        const playerBox = new THREE.Box3(
            new THREE.Vector3(newPos.x - this.radius, 0, newPos.z - this.radius),
            new THREE.Vector3(newPos.x + this.radius, this.height, newPos.z + this.radius)
        );

        // Статические коллайдеры (здания, мебель и т.д.)
        for (const collider of this.game.world.colliders) {
            if (playerBox.intersectsBox(collider)) return true;
        }

        // Динамические коллайдеры движущихся машин
        for (const collider of this.game.world.vehicleColliders) {
            if (!collider.isEmpty() && playerBox.intersectsBox(collider)) return true;
        }

        return false;
    }

    updateStats(dt) {
        this.statTimer += dt;
        if (this.statTimer < 1) return;
        this.statTimer = 0;

        this._prevHealth = this.stats.health;

        // Голод
        const survMod = this.game.skills.getSurvivalModifier();
        const hungerDrain = this.game.seasons.getHungerDrain();
        const diseaseMult = this.isDiseased ? 1.5 : 1;
        this.stats.hunger = Math.max(0, this.stats.hunger - 0.15 * survMod * hungerDrain * diseaseMult);

        // Тепло (с бонусом экипировки)
        const warmthDrain = this.game.seasons.getWarmthDrain();
        const eqWarmth = this.game.equipment.getWarmthBonus();
        const warmthReduction = Math.min(0.8, eqWarmth * 0.01); // Макс 80% снижение потери

        if (this.game.isNight()) {
            const drain = this.isWarming ? 0 : 0.3 * warmthDrain * (1 - warmthReduction);
            this.stats.warmth = Math.max(0, this.stats.warmth - drain);

            // В своём укрытии с крышей — меньше потеря
            if (this.game.housing.isPlayerInShelter() && this.game.housing.hasRoof()) {
                this.stats.warmth = Math.min(100, this.stats.warmth + 0.1);
            }
        } else {
            const warmthRegen = this.game.seasons.current === 'summer' ? 0.1 : 0.05;
            this.stats.warmth = Math.min(100, this.stats.warmth + warmthRegen);
        }

        if (this.isWarming) {
            this.stats.warmth = Math.min(100, this.stats.warmth + 0.5);
        }

        // Настроение от экипировки
        const eqMood = this.game.equipment.getMoodBonus();
        if (eqMood > 0) {
            this.stats.mood = Math.min(100, this.stats.mood + eqMood * 0.02);
        }

        // Здоровье
        if (this.stats.hunger <= 0) {
            this.stats.health = Math.max(0, this.stats.health - 0.5);
        }
        if (this.stats.warmth <= 10) {
            this.stats.health = Math.max(0, this.stats.health - 0.3);
        }
        if (this.stats.hunger > 50 && this.stats.warmth > 50) {
            this.stats.health = Math.min(100, this.stats.health + 0.1);
        }

        // Гигиена
        let hygieneDrain = 0.03;
        if (this.game.weather.current === 'rain') hygieneDrain += 0.02;
        this.stats.hygiene = Math.max(0, this.stats.hygiene - hygieneDrain);

        // Болезнь
        if (this.isDiseased) {
            this.stats.health = Math.max(0, this.stats.health - 0.1);
            this.diseaseTimer--;
            if (this.diseaseTimer <= 0) {
                this.isDiseased = false;
                this.game.notify('Вы выздоровели!', 'good');
            }
        } else if (this.stats.hygiene < 20) {
            this.diseaseCheckTimer++;
            if (this.diseaseCheckTimer >= 60) {
                this.diseaseCheckTimer = 0;
                if (Math.random() < 0.3) {
                    this.isDiseased = true;
                    this.diseaseTimer = 180;
                    this.game.notify('Вы заболели! Нужна аптечка или больница.', 'bad');
                }
            }
        }

        if (this.washCooldown > 0) this.washCooldown--;

        // Зависимость
        if (this.addictionLevel > 0) {
            this.addictionLevel = Math.max(0, this.addictionLevel - 0.008);
        }
        if (this.addictionLevel > 40) {
            const currentTime = this.game.gameTime + (this.game.gameDay - 1) * 24 * 60;
            const timeSinceDrink = currentTime - this.lastDrinkTime;
            if (timeSinceDrink > 30) {
                // Ломка
                this.withdrawalTimer++;
                if (this.withdrawalTimer % 60 === 0) {
                    this.stats.mood = Math.max(0, this.stats.mood - 5);
                    this.game.notify('Хочется выпить...', 'bad');
                }
            }
        }
        // Квест: снизить зависимость до 0
        if (this.addictionLevel <= 0 && this._hadAddiction) {
            this.game.questSystem.onEvent('sobriety');
            this._hadAddiction = false;
        }
        if (this.addictionLevel >= 50) this._hadAddiction = true;

        // Настроение
        if (this.stats.hunger < 20) this.stats.mood = Math.max(0, this.stats.mood - 0.2);
        if (this.stats.warmth < 20) this.stats.mood = Math.max(0, this.stats.mood - 0.15);
        if (this.stats.health < 30) this.stats.mood = Math.max(0, this.stats.mood - 0.1);
        if (this.stats.hygiene < 30) this.stats.mood = Math.max(0, this.stats.mood - 0.1);

        // Звук урона
        if (this.stats.health < this._prevHealth - 1) {
            this.game.sound.playHurt();
        }

        // Ачивка: сытость 100
        if (this.stats.hunger >= 99) {
            this._wellFedTimer++;
            if (this._wellFedTimer >= 300) {
                this.game.achievements.check('well_fed');
            }
        } else {
            this._wellFedTimer = 0;
        }
    }

    updateScreenEffects() {
        const dmg = document.getElementById('effect-damage');
        const cold = document.getElementById('effect-cold');
        const hunger = document.getElementById('effect-hunger');
        const sleep = document.getElementById('effect-sleep');

        if (this.stats.health < this._prevHealth - 1) {
            dmg.classList.add('active');
            setTimeout(() => dmg.classList.remove('active'), 400);
        }

        if (this.stats.warmth < 25) {
            cold.classList.add('active');
        } else {
            cold.classList.remove('active');
        }

        if (this.stats.hunger < 15) {
            hunger.classList.add('active');
        } else {
            hunger.classList.remove('active');
        }

        if (this.isSleeping) {
            sleep.classList.add('active');
        } else {
            sleep.classList.remove('active');
        }

        const disease = document.getElementById('effect-disease');
        if (disease) {
            if (this.isDiseased) {
                disease.classList.add('active');
            } else {
                disease.classList.remove('active');
            }
        }
    }

    checkInteractables() {
        let nearest = null;
        let nearestDist = Infinity;

        for (const obj of this.game.world.interactables) {
            const dist = this.position.distanceTo(obj.position);
            if (dist < obj.radius && dist < nearestDist) {
                nearest = obj;
                nearestDist = dist;
            }
        }

        // NPC
        for (const npc of this.game.npcManager.npcs) {
            const dist = this.position.distanceTo(npc.position);
            if (dist < 3 && dist < nearestDist) {
                nearest = {
                    type: 'npc',
                    npc: npc,
                    position: npc.position,
                    label: `Поговорить: ${npc.name}`
                };
                nearestDist = dist;
            }
        }

        // Костёр
        this.isWarming = false;
        for (const obj of this.game.world.interactables) {
            if (obj.type === 'campfire') {
                const dist = this.position.distanceTo(obj.position);
                if (dist < obj.radius) {
                    this.isWarming = true;
                }
            }
        }

        // Печка в укрытии
        if (this.game.housing.built && this.game.housing.upgrades.stove.built) {
            if (this.position.distanceTo(this.game.housing.position) < 5) {
                this.isWarming = true;
            }
        }

        this.nearestInteractable = nearest;
        this.game.ui.updateInteractionHint(nearest);
    }

    interact() {
        if (!this.nearestInteractable) return;
        const obj = this.nearestInteractable;

        switch (obj.type) {
            case 'dumpster':
                this.searchDumpster(obj);
                break;
            case 'bench':
                this.restOnBench();
                break;
            case 'shop':
                this.game.interiors.enterBuilding('shop');
                break;
            case 'shelter':
                this.sleep();
                break;
            case 'campfire':
                this.game.notify('Вы греетесь у костра...');
                break;
            case 'npc':
                this.game.npcManager.talkTo(obj.npc);
                break;
            case 'fountain':
                this.drinkFountain();
                break;
            case 'trashpile':
                this.searchTrashPile(obj);
                break;
            case 'phone':
                this.usePhone();
                break;
            case 'church':
                this.game.interiors.enterBuilding('church');
                break;
            case 'jobboard':
                this.game.jobSystem.showJobBoard();
                break;
            case 'player_shelter':
                this.game.housing.showMenu();
                break;
            case 'camp_spot':
                this.game.housing.showMenu();
                break;
            case 'hospital':
                this.game.interiors.enterBuilding('hospital');
                break;
            case 'market':
                this.enterMarket();
                break;
            // Интерьерные объекты
            case 'shop_counter':
                this.enterShop();
                break;
            case 'hospital_desk':
                this.enterHospital();
                break;
            case 'church_altar':
                this.enterChurch();
                break;
            case 'exit_door':
                this.game.interiors.exitBuilding();
                break;
        }
    }

    // === Попрошайничество ===
    startBegging() {
        if (this.isBegging || this.begCooldown > 0) return;

        let nearNPC = false;
        for (const npc of this.game.npcManager.npcs) {
            if (this.position.distanceTo(npc.position) < 8) {
                nearNPC = true;
                break;
            }
        }

        if (!nearNPC) {
            this.game.notify('Рядом никого нет...');
            return;
        }

        this.isBegging = true;
        this.begTimer = 0;
        this.game.ui.showBegProgress(true);
    }

    stopBegging() {
        if (!this.isBegging) return;
        this.isBegging = false;
        this.game.ui.showBegProgress(false);
    }

    updateBegging(dt) {
        if (!this.isBegging) return;

        this.begTimer += dt;
        this.game.ui.updateBegProgress(this.begTimer / this.begDuration);

        if (this.begTimer >= this.begDuration) {
            this.isBegging = false;
            this.begCooldown = 15;
            this.game.ui.showBegProgress(false);

            const begBonus = this.game.skills.getBegBonus() * this.game.reputation.getBegModifier();
            this.game.skills.addXP('begging', 2);
            this.game.reputation.change(-1);
            const roll = Math.random();
            if (roll < 0.35) {
                const amount = Math.floor((Math.random() * 20 + 5) * begBonus);
                this.stats.money += amount;
                this.game.sound.playCoin();
                this.game.notify(`Вам дали ${amount} ₽!`, 'good');
                this.game.questSystem.onEvent('find_money', amount);
                this.game.questSystem.onEvent('beg');
            } else if (roll < 0.55) {
                this.game.inventory.addItem('bread', 1);
                this.game.sound.playPickup();
                this.game.notify('Вам дали хлеб!', 'good');
                this.game.questSystem.onEvent('find_food');
            } else if (roll < 0.7) {
                this.game.notify('Прохожие игнорируют вас...');
                this.stats.mood = Math.max(0, this.stats.mood - 3);
            } else if (roll < 0.85) {
                this.game.notify('"Иди работай!" — грубо ответили вам.');
                this.stats.mood = Math.max(0, this.stats.mood - 5);
            } else {
                const amount = Math.floor(Math.random() * 50) + 20;
                this.stats.money += amount;
                this.game.sound.playCoin();
                this.game.notify(`Щедрый прохожий дал ${amount} ₽!`, 'good');
                this.game.questSystem.onEvent('find_money', amount);
                this.stats.mood = Math.min(100, this.stats.mood + 5);
            }
        }
    }

    // === Бускинг ===
    startBusking() {
        if (this.isBusking || this.buskCooldown > 0 || this.isBegging) return;

        if (this.game.inventory.getCount('harmonica') <= 0) {
            this.game.notify('У вас нет гармошки!');
            return;
        }

        // Ищем прохожих и NPC в радиусе 12
        let nearCount = 0;
        for (const npc of this.game.npcManager.npcs) {
            if (this.position.distanceTo(npc.position) < 12) nearCount++;
        }
        if (this.game.npcManager.passersby) {
            for (const pb of this.game.npcManager.passersby) {
                if (pb.mesh) {
                    const dist = this.position.distanceTo(pb.mesh.position);
                    if (dist < 12) nearCount++;
                }
            }
        }

        if (nearCount === 0) {
            this.game.notify('Рядом некому играть...');
            return;
        }

        this.isBusking = true;
        this.buskTimer = 0;
        this._buskNearCount = nearCount;
        this.game.ui.showBuskProgress(true);
    }

    stopBusking() {
        if (!this.isBusking) return;
        this.isBusking = false;
        this.game.ui.showBuskProgress(false);
    }

    updateBusking(dt) {
        if (!this.isBusking) return;

        this.buskTimer += dt;
        this.game.ui.updateBuskProgress(this.buskTimer / this.buskDuration);

        if (this.buskTimer >= this.buskDuration) {
            this.isBusking = false;
            this.buskCooldown = 20;
            this.game.ui.showBuskProgress(false);

            const begBonus = this.game.skills.getBegBonus();
            const crowdMult = Math.min(2, 1 + (this._buskNearCount - 1) * 0.3);
            this.game.skills.addXP('begging', 1);

            const roll = Math.random();
            if (roll < 0.50) {
                // Дали денег
                const amount = Math.floor((Math.random() * 20 + 10) * begBonus * crowdMult);
                this.stats.money += amount;
                this.game.sound.playCoin();
                this.game.notify(`Прохожие оценили игру! +${amount} ₽`, 'good');
                this.game.questSystem.onEvent('find_money', amount);
                this.game.questSystem.onEvent('busking');
            } else if (roll < 0.75) {
                // Хорошие деньги
                const amount = Math.floor((Math.random() * 30 + 20) * begBonus * crowdMult);
                this.stats.money += amount;
                this.game.sound.playCoin();
                this.game.notify(`Отличное выступление! +${amount} ₽`, 'good');
                this.game.questSystem.onEvent('find_money', amount);
                this.game.questSystem.onEvent('busking');
                this.stats.mood = Math.min(100, this.stats.mood + 5);
            } else if (roll < 0.90) {
                // Никто не обратил внимания
                this.game.notify('Прохожие не обратили внимания...');
            } else {
                // Бонус к настроению
                this.stats.mood = Math.min(100, this.stats.mood + 10);
                const amount = Math.floor((Math.random() * 15 + 5) * begBonus * crowdMult);
                this.stats.money += amount;
                this.game.sound.playCoin();
                this.game.notify(`Музыка подняла настроение! +${amount} ₽, +10 Настроение`, 'good');
                this.game.questSystem.onEvent('find_money', amount);
                this.game.questSystem.onEvent('busking');
            }
        }
    }

    // === Взаимодействия ===
    searchDumpster(dumpster) {
        if (dumpster.searchCooldown > 0) {
            this.game.notify('Тут уже нечего искать. Подождите...');
            return;
        }

        const scavBonus = this.game.skills.getScavengeBonus();
        dumpster.searchCooldown = Math.floor(120 / scavBonus);
        this.game.sound.playPickup();
        this.game.skills.addXP('scavenging', 1);
        this.stats.hygiene = Math.max(0, this.stats.hygiene - 5);

        const roll = Math.random();
        if (roll < 0.18) {
            const count = Math.random() < 0.3 + scavBonus * 0.05 ? 2 : 1;
            this.game.inventory.addItem('bottle', count);
            this.game.notify(`Вы нашли бутылк${count > 1 ? 'и' : 'у'}!`, 'good');
            this.game.questSystem.onEvent('collect_bottle');
            if (count > 1) this.game.questSystem.onEvent('collect_bottle');
        } else if (roll < 0.29) {
            this.game.inventory.addItem('bread', 1);
            this.game.notify('Вы нашли кусок хлеба!', 'good');
            this.game.questSystem.onEvent('find_food');
        } else if (roll < 0.38) {
            this.game.inventory.addItem('can', 1);
            this.game.notify('Вы нашли консервную банку!', 'good');
            this.game.questSystem.onEvent('find_food');
        } else if (roll < 0.47) {
            this.game.inventory.addItem('clothing', 1);
            this.game.notify('Вы нашли старую одежду!', 'good');
        } else if (roll < 0.54) {
            this.game.inventory.addItem('newspaper', 1);
            this.game.notify('Вы нашли газету!');
        } else if (roll < 0.62) {
            const coins = Math.floor(Math.random() * 15) + 1;
            this.stats.money += coins;
            this.game.sound.playCoin();
            this.game.notify(`Вы нашли ${coins} ₽!`, 'good');
            this.game.questSystem.onEvent('find_money', coins);
        } else if (roll < 0.70) {
            this.game.inventory.addItem('scrap', 1);
            this.game.notify('Вы нашли полезный хлам!', 'good');
        } else if (roll < 0.77) {
            this.game.inventory.addItem('rope', 1);
            this.game.notify('Вы нашли верёвку!', 'good');
        } else if (roll < 0.82) {
            // Шанс найти экипировку
            const eqItems = ['eq_old_hat', 'eq_old_jacket', 'eq_old_boots', 'eq_old_gloves'];
            const eqItem = eqItems[Math.floor(Math.random() * eqItems.length)];
            this.game.inventory.addItem(eqItem, 1);
            this.game.notify(`Вы нашли ${this.game.inventory.itemData[eqItem].name}!`, 'good');
        } else if (roll < 0.87) {
            this.game.inventory.addItem('apple', 1);
            this.game.notify('Вы нашли яблоко!', 'good');
        } else {
            this.game.notify('Ничего полезного...');
            this.stats.mood = Math.max(0, this.stats.mood - 3);
        }
    }

    restOnBench() {
        this.stats.mood = Math.min(100, this.stats.mood + 5);
        this.stats.health = Math.min(100, this.stats.health + 2);
        this.game.notify('Вы отдохнули на скамейке. +5 Настроение, +2 Здоровье.', 'good');
    }

    drinkFountain() {
        this.game.ui.showDialog('Фонтанчик', 'Что хотите сделать?', [
            'Попить воды',
            'Помыться',
            'Уйти'
        ], (index) => {
            if (index === 0) {
                this.stats.hunger = Math.min(100, this.stats.hunger + 5);
                this.stats.mood = Math.min(100, this.stats.mood + 2);
                this.game.notify('Вы попили воды. +5 Сытость, +2 Настроение', 'good');
            } else if (index === 1) {
                if (this.washCooldown > 0) {
                    this.game.notify('Вы недавно мылись. Подождите...');
                } else {
                    this.stats.hygiene = Math.min(100, this.stats.hygiene + 40);
                    this.washCooldown = 300;
                    this.game.notify('+40 Гигиена', 'good');
                    this.game.questSystem.onEvent('wash');
                }
            }
            this.game.ui.hideDialog();
        });
    }

    searchTrashPile(obj) {
        if (obj.searchCooldown > 0) {
            this.game.notify('Здесь уже нечего искать...');
            return;
        }
        obj.searchCooldown = 90;
        this.game.skills.addXP('scavenging', 1);
        this.stats.hygiene = Math.max(0, this.stats.hygiene - 3);

        const roll = Math.random();
        if (roll < 0.25) {
            this.game.inventory.addItem('bottle', 1);
            this.game.sound.playPickup();
            this.game.notify('Нашли бутылку в мусоре!', 'good');
            this.game.questSystem.onEvent('collect_bottle');
        } else if (roll < 0.38) {
            const coins = Math.floor(Math.random() * 5) + 1;
            this.stats.money += coins;
            this.game.sound.playCoin();
            this.game.notify(`Нашли ${coins} ₽!`, 'good');
        } else if (roll < 0.50) {
            this.game.inventory.addItem('scrap', 1);
            this.game.sound.playPickup();
            this.game.notify('Нашли полезный хлам!', 'good');
        } else if (roll < 0.60) {
            this.game.inventory.addItem('candle', 1);
            this.game.sound.playPickup();
            this.game.notify('Нашли свечу!', 'good');
        } else if (roll < 0.68) {
            this.game.inventory.addItem('rope', 1);
            this.game.sound.playPickup();
            this.game.notify('Нашли верёвку!', 'good');
        } else {
            this.game.notify('Мусор как мусор...');
        }
    }

    usePhone() {
        this.game.ui.showDialog('Таксофон', 'Позвонить на горячую линию помощи?', [
            'Позвонить (бесплатно)',
            'Не нужно'
        ], (index) => {
            if (index === 0) {
                this.stats.mood = Math.min(100, this.stats.mood + 10);
                this.game.notify('Вам дали полезные советы. +10 Настроение', 'good');
            }
            this.game.ui.hideDialog();
        });
    }

    enterShop() {
        const items = [
            { name: 'Хлеб', key: 'bread', price: 30, desc: '+20 Сытость' },
            { name: 'Консервы', key: 'can', price: 50, desc: '+35 Сытость' },
            { name: 'Чай', key: 'tea', price: 20, desc: '+20 Тепло, +5 Настроение' },
            { name: 'Бинт', key: 'bandage', price: 40, desc: '+25 Здоровье' },
            { name: 'Свеча', key: 'candle', price: 15, desc: 'Для крафта' },
            { name: 'Верёвка', key: 'rope', price: 25, desc: 'Для крафта' },
            { name: 'Яблоко', key: 'apple', price: 15, desc: '+10 Сытость, +5 Здоровье' },
            { name: 'Мыло', key: 'soap', price: 20, desc: '+30 Гигиена' },
            { name: 'Перчатки', key: 'eq_gloves', price: 60, desc: 'Экипировка: +8 Тепло' },
            { name: 'Ботинки', key: 'eq_boots', price: 80, desc: 'Экипировка: +10 Тепло' },
        ];

        const discount = this.game.skills.getTradeDiscount() * this.game.reputation.getShopModifier();
        const choices = items.map(item => {
            const finalPrice = Math.floor(item.price * discount);
            return `${item.name} — ${finalPrice} ₽ (${item.desc})`;
        });
        choices.push('Сдать бутылки (5₽/шт)');
        choices.push('Уйти');

        this.game.sound.playDialogOpen();

        this.game.ui.showDialog('Продавец', 'Чего желаете?', choices, (index) => {
            if (index < items.length) {
                const item = items[index];
                const finalPrice = Math.floor(item.price * discount);
                if (this.stats.money >= finalPrice) {
                    this.stats.money -= finalPrice;
                    this.game.skills.addXP('trading', 1);
                    this.game.inventory.addItem(item.key, 1);
                    this.game.sound.playCoin();
                    this.game.notify(`Куплено: ${item.name}`, 'good');
                } else {
                    this.game.notify('Не хватает денег!', 'bad');
                }
            } else if (index === items.length) {
                const bottles = this.game.inventory.getCount('bottle');
                if (bottles > 0) {
                    const earnings = bottles * 5;
                    this.stats.money += earnings;
                    this.game.inventory.removeItem('bottle', bottles);
                    this.game.sound.playCoin();
                    this.game.notify(`Сдали ${bottles} бутылок за ${earnings} ₽!`, 'good');
                    this.game.questSystem.onEvent('sell_bottles', bottles);
                    this.game.totalBottlesSold += bottles;
                    if (this.game.totalBottlesSold >= 20) {
                        this.game.achievements.check('bottle_king');
                    }
                } else {
                    this.game.notify('У вас нет бутылок.');
                }
            }
            this.game.ui.hideDialog();
        });
    }

    enterHospital() {
        const choices = ['Осмотр (бесплатно)', 'Лечение (50₽)', 'Уйти'];

        this.game.sound.playDialogOpen();
        this.game.ui.showDialog('Больница', 'Добро пожаловать. Чем помочь?', choices, (index) => {
            if (index === 0) {
                this.stats.health = Math.min(100, this.stats.health + 15);
                if (this.isDiseased) {
                    this.isDiseased = false;
                    this.diseaseTimer = 0;
                    this.game.notify('+15 Здоровье. Болезнь вылечена!', 'good');
                } else {
                    this.game.notify('+15 Здоровье. Вас осмотрели.', 'good');
                }
            } else if (index === 1) {
                if (this.stats.money >= 50) {
                    this.stats.money -= 50;
                    this.stats.health = 100;
                    this.isDiseased = false;
                    this.diseaseTimer = 0;
                    this.game.sound.playCoin();
                    this.game.notify('Полное здоровье восстановлено! Болезнь вылечена!', 'good');
                } else {
                    this.game.notify('Не хватает денег!', 'bad');
                }
            }
            this.game.ui.hideDialog();
            this.game.questSystem.onEvent('visit_hospital');
        });
    }

    enterMarket() {
        const items = [
            { name: 'Рыба', key: 'fish', price: 25, desc: '+25 Сытость' },
            { name: 'Пальто', key: 'eq_coat', price: 120, desc: 'Экипировка: +18 Тепло' },
            { name: 'Тёплые сапоги', key: 'eq_warm_boots', price: 100, desc: 'Экипировка: +18 Тепло' },
            { name: 'Жилетка', key: 'eq_vest', price: 150, desc: 'Экипировка: +10 Защита' },
            { name: 'Каска', key: 'eq_helmet', price: 90, desc: 'Экипировка: +8 Защита' },
            { name: 'Водка', key: 'vodka', price: 40, desc: '+30 Тепло, -10 Здоровье' },
        ];

        const discount = this.game.skills.getTradeDiscount() * this.game.reputation.getShopModifier();
        const choices = items.map(item => {
            const finalPrice = Math.floor(item.price * discount);
            return `${item.name} — ${finalPrice} ₽ (${item.desc})`;
        });
        choices.push('Уйти');

        this.game.sound.playDialogOpen();
        this.game.ui.showDialog('Рынок', 'Здесь можно найти полезные вещи.', choices, (index) => {
            if (index < items.length) {
                const item = items[index];
                const finalPrice = Math.floor(item.price * discount);
                if (this.stats.money >= finalPrice) {
                    this.stats.money -= finalPrice;
                    this.game.skills.addXP('trading', 2);
                    this.game.inventory.addItem(item.key, 1);
                    this.game.sound.playCoin();
                    this.game.notify(`Куплено: ${item.name}`, 'good');
                } else {
                    this.game.notify('Не хватает денег!', 'bad');
                }
            }
            this.game.ui.hideDialog();
        });
    }

    sleep() {
        if (this.stats.hunger < 10) {
            this.game.notify('Слишком голодно, не уснуть...', 'bad');
            return;
        }
        this.isSleeping = true;
        this.sleepTimer = 0;
        this._shelterSleep = false;
        this.game.notify('Вы легли спать...');
    }

    updateSleep(dt) {
        this.sleepTimer += dt;
        if (this.sleepTimer >= 5) {
            this.isSleeping = false;

            let bonus;
            if (this._shelterSleep) {
                bonus = this.game.housing.getSleepBonus();
            } else {
                bonus = { health: 15, mood: 10, warmth: 20 };
            }

            this.stats.health = Math.min(100, this.stats.health + bonus.health);
            this.stats.mood = Math.min(100, this.stats.mood + bonus.mood);
            this.stats.warmth = Math.min(100, this.stats.warmth + bonus.warmth);
            this.stats.hunger = Math.max(0, this.stats.hunger - 15);
            this.game.gameTime += 360;
            this._shelterSleep = false;

            const bonusText = this._shelterSleep ? ' (улучшенный отдых)' : '';
            this.game.notify(`Вы проснулись отдохнувшим.${bonusText}`, 'good');
            this.game.questSystem.onEvent('sleep');
        }
    }

    checkDeath() {
        if (this.stats.health <= 0) {
            let reason = 'Вы не выдержали тяжёлой жизни на улице.';
            if (this.stats.hunger <= 0) reason = 'Вы умерли от голода.';
            if (this.stats.warmth <= 0) reason = 'Вы замёрзли насмерть.';
            this.game.gameOver(reason);
        }
    }

    useItem(itemKey) {
        const effects = {
            bread:     () => { this.stats.hunger = Math.min(100, this.stats.hunger + 20); this.game.sound.playEat(); this.game.notify('+20 Сытость', 'good'); },
            can:       () => { this.stats.hunger = Math.min(100, this.stats.hunger + 35); this.game.sound.playEat(); this.game.notify('+35 Сытость', 'good'); },
            tea:       () => { this.stats.warmth = Math.min(100, this.stats.warmth + 20); this.stats.mood += 5; this.game.sound.playEat(); this.game.notify('+20 Тепло, +5 Настроение', 'good'); },
            bandage:   () => { this.stats.health = Math.min(100, this.stats.health + 25); this.game.notify('+25 Здоровье', 'good'); },
            clothing:  () => { this.stats.warmth = Math.min(100, this.stats.warmth + 30); this.game.notify('+30 Тепло', 'good'); },
            newspaper: () => { this.stats.mood = Math.min(100, this.stats.mood + 5); this.game.notify('Вы почитали газету. +5 Настроение', 'good'); },
            medkit:    () => { this.stats.health = Math.min(100, this.stats.health + 50); if (this.isDiseased) { this.isDiseased = false; this.diseaseTimer = 0; this.game.notify('+50 Здоровье. Болезнь вылечена!', 'good'); } else { this.game.notify('+50 Здоровье', 'good'); } },
            stew:      () => { this.stats.hunger = Math.min(100, this.stats.hunger + 50); this.stats.warmth = Math.min(100, this.stats.warmth + 15); this.game.sound.playEat(); this.game.notify('+50 Сытость, +15 Тепло', 'good'); },
            blanket:   () => { this.stats.warmth = Math.min(100, this.stats.warmth + 50); this.stats.mood = Math.min(100, this.stats.mood + 10); this.game.notify('+50 Тепло, +10 Настроение', 'good'); },
            soap:      () => { this.stats.hygiene = Math.min(100, this.stats.hygiene + 30); this.game.notify('+30 Гигиена', 'good'); },
            harmonica: () => {
                // Если рядом есть люди — начать бускинг, иначе просто играть для себя
                let hasNearby = false;
                for (const npc of this.game.npcManager.npcs) {
                    if (this.position.distanceTo(npc.position) < 12) { hasNearby = true; break; }
                }
                if (!hasNearby && this.game.npcManager.passersby) {
                    for (const pb of this.game.npcManager.passersby) {
                        if (pb.mesh && this.position.distanceTo(pb.mesh.position) < 12) { hasNearby = true; break; }
                    }
                }
                if (hasNearby && this.buskCooldown <= 0 && !this.isBusking) {
                    this.startBusking();
                } else {
                    this.stats.mood = Math.min(100, this.stats.mood + 20);
                    this.game.notify('Вы сыграли мелодию. +20 Настроение', 'good');
                }
            },
            fish:      () => { this.stats.hunger = Math.min(100, this.stats.hunger + 25); this.game.sound.playEat(); this.game.notify('+25 Сытость', 'good'); },
            apple:     () => { this.stats.hunger = Math.min(100, this.stats.hunger + 10); this.stats.health = Math.min(100, this.stats.health + 5); this.game.sound.playEat(); this.game.notify('+10 Сытость, +5 Здоровье', 'good'); },
            vodka:     () => {
                this.stats.warmth = Math.min(100, this.stats.warmth + (this.addictionLevel > 60 ? 40 : 30));
                this.stats.health = Math.max(0, this.stats.health - 10);
                const moodGain = this.addictionLevel > 80 ? 0 : 15;
                if (moodGain > 0) this.stats.mood = Math.min(100, this.stats.mood + moodGain);
                this.addictionLevel = Math.min(100, this.addictionLevel + 20);
                this.lastDrinkTime = this.game.gameTime + (this.game.gameDay - 1) * 24 * 60;
                this.withdrawalTimer = 0;
                const msg = this.addictionLevel > 80
                    ? '+40 Тепло, -10 Здоровье (привычка...)'
                    : this.addictionLevel > 60
                        ? '+40 Тепло, -10 Здоровье, +15 Настроение (толерантность)'
                        : '+30 Тепло, -10 Здоровье, +15 Настроение';
                this.game.notify(msg, 'good');
            },
            vitamins:  () => { this.stats.health = Math.min(100, this.stats.health + 15); this.stats.mood = Math.min(100, this.stats.mood + 10); this.game.notify('+15 Здоровье, +10 Настроение', 'good'); },
            torch:     () => {
                this.stats.warmth = Math.min(100, this.stats.warmth + 20);
                if (this.game.isNight()) {
                    this.stats.mood = Math.min(100, this.stats.mood + 10);
                    this.game.notify('+20 Тепло, +10 Настроение', 'good');
                } else {
                    this.game.notify('+20 Тепло', 'good');
                }
            },
        };

        if (effects[itemKey]) {
            effects[itemKey]();
            if (itemKey !== 'harmonica') {
                this.game.inventory.removeItem(itemKey, 1);
            }
            return true;
        }
        return false;
    }

    enterChurch() {
        this.game.ui.showDialog('Церковь', 'Тёплое помещение. Тихо играет органная музыка. Добрая женщина предлагает помощь.', [
            'Попросить еду',
            'Попросить одежду',
            'Помолиться',
            'Уйти'
        ], (index) => {
            if (index === 0) {
                this.game.inventory.addItem('bread', 2);
                this.game.inventory.addItem('tea', 1);
                this.stats.warmth = Math.min(100, this.stats.warmth + 10);
                this.game.sound.playPickup();
                this.game.notify('Вам дали хлеб и чай. +10 Тепло', 'good');
            } else if (index === 1) {
                this.game.inventory.addItem('clothing', 1);
                this.stats.warmth = Math.min(100, this.stats.warmth + 10);
                this.game.sound.playPickup();
                this.game.notify('Вам дали тёплую одежду. +10 Тепло', 'good');
            } else if (index === 2) {
                this.stats.mood = Math.min(100, this.stats.mood + 20);
                this.stats.health = Math.min(100, this.stats.health + 5);
                this.game.notify('Вы чувствуете покой. +20 Настроение, +5 Здоровье', 'good');
            }
            this.game.ui.hideDialog();
            this.game.questSystem.onEvent('visit_church');
            this.game.reputation.change(2);
        });
    }

    trackLocations() {
        const cfg = this.game.world.mapConfig?.structures || {};
        const locs = {
            shop:         { x: cfg.shop?.x ?? -25,         z: cfg.shop?.z ?? -12,         r: 8 },
            church:       { x: cfg.church?.x ?? 30,        z: cfg.church?.z ?? 60,        r: 10 },
            park:         { x: cfg.park?.x ?? -30,         z: cfg.park?.z ?? 25,          r: cfg.park?.radius ?? 18 },
            shelter:      { x: cfg.shelter?.x ?? -35,      z: cfg.shelter?.z ?? 35,       r: 6 },
            construction: { x: cfg.construction?.x ?? 70,  z: cfg.construction?.z ?? 60,  r: cfg.construction?.radius ?? 8 },
            hospital:     { x: cfg.hospital?.x ?? -45,     z: cfg.hospital?.z ?? -55,     r: 8 },
            market:       { x: cfg.market?.x ?? 35,        z: cfg.market?.z ?? -55,       r: 8 },
            busstop:      { x: cfg.busStop?.x ?? -20,      z: cfg.busStop?.z ?? 7,        r: 5 },
        };

        for (const [name, loc] of Object.entries(locs)) {
            const dx = this.position.x - loc.x;
            const dz = this.position.z - loc.z;
            if (Math.sqrt(dx * dx + dz * dz) < loc.r) {
                this.game.visitedLocations.add(name);
            }
        }

        if (this.game.visitedLocations.size >= 8) {
            this.game.achievements.check('explorer');
        }
    }

    checkDanger() {
        return this.game.dangers.hasNearbyDanger();
    }
}
