const express = require('express');
const { Address, sequelize } = require('../models');
const { authenticateToken } = require('../middleware/auth');
const router = express.Router();

// Get all addresses for logged in user
router.get('/', authenticateToken, async (req, res) => {
    try {
        const addresses = await Address.findAll({
            where: { user_id: req.user.id },
            order: [['is_primary', 'DESC'], ['created_at', 'DESC']]
        });
        res.json(addresses);
    } catch (error) {
        res.status(500).json({ message: 'Server error', error: error.message });
    }
});

// Create new address
router.post('/', authenticateToken, async (req, res) => {
    try {
        const { label, name, phone, province, city, street, detail } = req.body;
        
        // Check if user has any addresses
        const count = await Address.count({ where: { user_id: req.user.id } });
        const isPrimary = count === 0; // First address is primary by default

        const address = await Address.create({
            user_id: req.user.id,
            label,
            name,
            phone,
            province,
            city,
            street,
            detail,
            is_primary: isPrimary
        });

        res.status(201).json(address);
    } catch (error) {
        res.status(500).json({ message: 'Server error', error: error.message });
    }
});

// Update address
router.put('/:id', authenticateToken, async (req, res) => {
    try {
        const { label, name, phone, province, city, street, detail } = req.body;
        const address = await Address.findOne({
            where: { id: req.params.id, user_id: req.user.id }
        });

        if (!address) return res.status(404).json({ message: 'Address not found' });

        address.label = label || address.label;
        address.name = name || address.name;
        address.phone = phone || address.phone;
        address.province = province || address.province;
        address.city = city || address.city;
        address.street = street || address.street;
        address.detail = detail || address.detail;

        await address.save();
        res.json(address);
    } catch (error) {
        res.status(500).json({ message: 'Server error', error: error.message });
    }
});

// Delete address
router.delete('/:id', authenticateToken, async (req, res) => {
    try {
        const address = await Address.findOne({
            where: { id: req.params.id, user_id: req.user.id }
        });

        if (!address) return res.status(404).json({ message: 'Address not found' });

        // If trying to delete primary address, warn user or auto-assign new primary?
        // Logic: allow delete, if it was primary and others exist, make the latest one primary.
        const wasPrimary = address.is_primary;

        await address.destroy();

        if (wasPrimary) {
            const latestAddress = await Address.findOne({
                where: { user_id: req.user.id },
                order: [['created_at', 'DESC']]
            });
            if (latestAddress) {
                latestAddress.is_primary = true;
                await latestAddress.save();
            }
        }

        res.json({ message: 'Address deleted successfully' });
    } catch (error) {
        res.status(500).json({ message: 'Server error', error: error.message });
    }
});

// Set as Primary Address
router.put('/:id/primary', authenticateToken, async (req, res) => {
    const t = await sequelize.transaction();
    try {
        const address = await Address.findOne({
            where: { id: req.params.id, user_id: req.user.id },
            transaction: t
        });

        if (!address) {
            await t.rollback();
            return res.status(404).json({ message: 'Address not found' });
        }

        // Set all user's addresses to false
        await Address.update({ is_primary: false }, {
            where: { user_id: req.user.id },
            transaction: t
        });

        // Set target to true
        address.is_primary = true;
        await address.save({ transaction: t });

        await t.commit();
        res.json(address);
    } catch (error) {
        await t.rollback();
        res.status(500).json({ message: 'Server error', error: error.message });
    }
});

module.exports = router;
