const express = require('express');
const jwt = require('jsonwebtoken');
const Player = require('../models/Player');
const Ship = require('../models/Ship');
const Inventory = require('../models/Inventory');
const { getGameSystem } = require('../systems/GameSystem');
const logger = require('../utils/logger');

const router = express.Router();

// Middleware to authenticate JWT token
const authenticateToken = (req, res, next) => {
  const token = req.header('Authorization')?.replace('Bearer ', '');
  
  if (!token) {
    return res.status(401).json({ error: 'Access token required' });
  }

  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET || 'fallback_secret');
    req.userId = decoded.userId;
    next();
  } catch (error) {
    res.status(401).json({ error: 'Invalid token' });
  }
};

// Get player data
router.get('/player', authenticateToken, async (req, res) => {
  try {
    const gameSystem = getGameSystem();
    const player = await gameSystem.loadPlayer(req.userId);
    
    if (!player) {
      return res.status(404).json({ error: 'Player not found' });
    }

    res.json({
      userId: player.userId,
      username: player.username,
      stats: player.stats,
      attributes: player.attributes,
      info: player.info,
      settings: player.settings,
      dailyRewards: player.dailyRewards
    });

  } catch (error) {
    logger.error('Error getting player data:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

// Get player's ships
router.get('/ships', authenticateToken, async (req, res) => {
  try {
    const ships = await Ship.find({ userId: req.userId });
    
    res.json({
      ships: ships.map(ship => ({
        id: ship.id,
        name: ship.name,
        class: ship.class,
        level: ship.level,
        stats: ship.stats,
        isEquipped: ship.isEquipped,
        isCurrent: ship.isCurrent,
        rarity: ship.rarity,
        texture: ship.texture,
        acquiredAt: ship.acquiredAt
      }))
    });

  } catch (error) {
    logger.error('Error getting player ships:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

// Equip a ship
router.post('/ships/equip', authenticateToken, async (req, res) => {
  try {
    const { shipId } = req.body;
    
    if (!shipId) {
      return res.status(400).json({ error: 'Ship ID required' });
    }

    const gameSystem = getGameSystem();
    const ship = await gameSystem.equipShip(req.userId, shipId);
    
    res.json({
      message: 'Ship equipped successfully',
      ship: {
        id: ship.id,
        name: ship.name,
        class: ship.class,
        level: ship.level,
        stats: ship.stats,
        isEquipped: ship.isEquipped,
        isCurrent: ship.isCurrent
      }
    });

  } catch (error) {
    logger.error('Error equipping ship:', error);
    res.status(500).json({ error: error.message });
  }
});

// Get player's inventory
router.get('/inventory', authenticateToken, async (req, res) => {
  try {
    let inventory = await Inventory.findOne({ userId: req.userId });
    
    if (!inventory) {
      // Create new inventory if it doesn't exist
      inventory = new Inventory({ userId: req.userId });
      await inventory.save();
    }

    res.json({
      items: inventory.items,
      equippedItems: inventory.equippedItems,
      summary: inventory.getInventorySummary()
    });

  } catch (error) {
    logger.error('Error getting inventory:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

// Add item to inventory
router.post('/inventory/add', authenticateToken, async (req, res) => {
  try {
    const { itemData } = req.body;
    
    if (!itemData) {
      return res.status(400).json({ error: 'Item data required' });
    }

    let inventory = await Inventory.findOne({ userId: req.userId });
    
    if (!inventory) {
      inventory = new Inventory({ userId: req.userId });
    }

    await inventory.addItem(itemData);
    
    res.json({
      message: 'Item added to inventory',
      item: itemData,
      summary: inventory.getInventorySummary()
    });

  } catch (error) {
    logger.error('Error adding item to inventory:', error);
    res.status(500).json({ error: error.message });
  }
});

// Equip item
router.post('/inventory/equip', authenticateToken, async (req, res) => {
  try {
    const { itemId, slot } = req.body;
    
    if (!itemId || !slot) {
      return res.status(400).json({ error: 'Item ID and slot required' });
    }

    const inventory = await Inventory.findOne({ userId: req.userId });
    
    if (!inventory) {
      return res.status(404).json({ error: 'Inventory not found' });
    }

    await inventory.equipItem(itemId, slot);
    
    res.json({
      message: 'Item equipped successfully',
      equippedItems: inventory.equippedItems
    });

  } catch (error) {
    logger.error('Error equipping item:', error);
    res.status(500).json({ error: error.message });
  }
});

// Use consumable
router.post('/inventory/use', authenticateToken, async (req, res) => {
  try {
    const { itemId } = req.body;
    
    if (!itemId) {
      return res.status(400).json({ error: 'Item ID required' });
    }

    const inventory = await Inventory.findOne({ userId: req.userId });
    
    if (!inventory) {
      return res.status(404).json({ error: 'Inventory not found' });
    }

    const effects = await inventory.useConsumable(itemId);
    
    res.json({
      message: 'Item used successfully',
      effects,
      summary: inventory.getInventorySummary()
    });

  } catch (error) {
    logger.error('Error using consumable:', error);
    res.status(500).json({ error: error.message });
  }
});

// Process game action
router.post('/action', authenticateToken, async (req, res) => {
  try {
    const { actionData } = req.body;
    
    if (!actionData) {
      return res.status(400).json({ error: 'Action data required' });
    }

    const gameSystem = getGameSystem();
    const result = await gameSystem.processGameAction(req.userId, actionData);
    
    res.json(result);

  } catch (error) {
    logger.error('Error processing game action:', error);
    res.status(500).json({ error: error.message });
  }
});

// Claim daily reward
router.post('/daily-reward', authenticateToken, async (req, res) => {
  try {
    const player = await Player.findOne({ userId: req.userId });
    
    if (!player) {
      return res.status(404).json({ error: 'Player not found' });
    }

    const rewardResult = player.claimDailyReward();
    await player.save();
    
    res.json(rewardResult);

  } catch (error) {
    logger.error('Error claiming daily reward:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

// Save player data
router.post('/save', authenticateToken, async (req, res) => {
  try {
    const gameSystem = getGameSystem();
    await gameSystem.savePlayer(req.userId);
    
    res.json({ message: 'Game saved successfully' });

  } catch (error) {
    logger.error('Error saving game:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

// Get shop items
router.get('/shop/:category?', authenticateToken, async (req, res) => {
  try {
    const gameSystem = getGameSystem();
    const category = req.params.category;
    const items = gameSystem.economy.getShopItems(category);
    
    res.json({ items });

  } catch (error) {
    logger.error('Error getting shop items:', error);
    res.status(500).json({ error: 'Internal server error' });
  }
});

// Purchase item
router.post('/shop/purchase', authenticateToken, async (req, res) => {
  try {
    const { itemId, quantity = 1 } = req.body;
    
    if (!itemId) {
      return res.status(400).json({ error: 'Item ID required' });
    }

    const gameSystem = getGameSystem();
    const purchaseInfo = gameSystem.economy.purchaseItem(req.userId, itemId, quantity);
    
    const player = await Player.findOne({ userId: req.userId });
    
    if (!player.canAfford(purchaseInfo.totalCost)) {
      return res.status(400).json({ error: 'Insufficient credits' });
    }

    // Deduct credits
    player.spendCredits(purchaseInfo.totalCost);
    await player.save();

    // Add item to inventory
    const inventory = await Inventory.findOne({ userId: req.userId });
    if (!inventory) {
      return res.status(404).json({ error: 'Inventory not found' });
    }

    await inventory.addItem({
      ...purchaseInfo.item,
      quantity
    });

    res.json({
      message: 'Purchase successful',
      item: purchaseInfo.item,
      quantity,
      totalCost: purchaseInfo.totalCost,
      remainingCredits: player.stats.credits
    });

  } catch (error) {
    logger.error('Error purchasing item:', error);
    res.status(500).json({ error: error.message });
  }
});

module.exports = router;
