'use strict'

const Admin   = require('../models/Admin')
const bcrypt  = require('bcryptjs')
const jwt     = require('jsonwebtoken')
const path    = require('path')
const { JWT_SECRET } = require('../middleware/auth')
const Claim   = require('../models/Claim')
const NotificationService = require('../services/notificationService')
const { query, queryOne } = require('../database/postgres')

const adminController = {
    getLoginPage(req, res) {
        res.sendFile(path.join(__dirname, '..', 'views', 'admin', 'login.html'))
    },

    getDashboardPage(req, res) {
        res.sendFile(path.join(__dirname, '..', 'views', 'admin', 'dashboard.html'))
    },

    async login(req, res) {
        try {
            const { username, password } = req.body
            const cleanUser = username?.trim();
            const admin = await Admin.findByUsername(cleanUser)
            
            if (!admin || !bcrypt.compareSync(password, admin.password_hash)) {
                return res.status(401).json({ error: 'Credenciais inválidas' })
            }
            const token = jwt.sign(
              { id: admin.id, username: admin.username, tenant_id: admin.tenant_id || 1 },
              JWT_SECRET,
              { expiresIn: '24h' }
            )
            // Remove sessão de equipe antes de criar sessão de admin
            res.clearCookie('team_token')
            res.cookie('cloud_token', token, {
              httpOnly: true,
              maxAge: 24 * 60 * 60 * 1000,
              secure: process.env.COOKIE_SECURE === 'true',
              sameSite: 'lax',
            })
            return res.json({ success: true, redirect: '/admin/dashboard' })
        } catch (error) {
            return res.status(500).json({ error: 'Erro interno no login' })
        }
    },

    logout(req, res) {
        res.clearCookie('cloud_token')
        res.clearCookie('team_token')
        res.redirect('/admin')
    },

    async listAdmins(req, res) {
        try {
            const admins = await Admin.findAll()
            return res.json(admins)
        } catch (error) {
            return res.status(500).json({ error: 'Erro ao listar administradores' })
        }
    },

    async createAdmin(req, res) {
        try {
            const { username, password } = req.body

            if (!username || !password) {
                return res.status(400).json({ error: 'Usuário e senha são obrigatórios' })
            }
            if (username.length < 3) return res.status(400).json({ error: 'Usuário curto' })
            if (password.length < 8) return res.status(400).json({ error: 'Senha deve ter no mínimo 8 caracteres' })

            const existing = await Admin.findByUsername(username)
            if (existing) return res.status(400).json({ error: 'Usuário existente' })

            const hash   = bcrypt.hashSync(password, 10)
            const result = await Admin.create(username, hash)
            return res.json({ success: true, id: result.lastInsertRowid, message: 'Sucesso' })
        } catch (error) {
            return res.status(500).json({ error: 'Erro ao criar' })
        }
    },

    async updateAdmin(req, res) {
        try {
            const { id } = req.params
            const { password, username, nome, email, telefone } = req.body

            const admin = await Admin.findById(parseInt(id))
            if (!admin) return res.status(404).json({ error: 'Não encontrado' })

            const updateData = {}
            if (username && username !== admin.username) {
                const existing = await Admin.findByUsername(username)
                if (existing && existing.id !== parseInt(id)) return res.status(400).json({ error: 'Nome em uso' })
                updateData.username = username
            }
            if (password) {
                if (password.length < 8) return res.status(400).json({ error: 'Senha deve ter no mínimo 8 caracteres' })
                updateData.password_hash = bcrypt.hashSync(password, 10)
            }
            updateData.nome     = nome     || null
            updateData.email    = email    || null
            updateData.telefone = telefone || null

            await Admin.update(parseInt(id), updateData)
            return res.json({ success: true, message: 'Atualizado' })
        } catch (error) {
            return res.status(500).json({ error: 'Erro ao atualizar' })
        }
    },

    async deleteAdmin(req, res) {
        try {
            const { id } = req.params
            if (parseInt(id) === req.admin.id) return res.status(400).json({ error: 'Não pode se excluir' })

            const count = await Admin.count()
            if (count <= 1) return res.status(400).json({ error: 'Último admin' })

            await Admin.delete(parseInt(id))
            return res.json({ success: true, message: 'Removido' })
        } catch (error) {
            return res.status(500).json({ error: 'Erro ao deletar' })
        }
    },

    // ── Histórico de Pedidos ──────────────────────────────────────────────────

    async listOrders(req, res) {
        try {
            const { status, from, to } = req.query
            const params = []
            const where = []
            if (req.tenant?.id) { where.push(`o.tenant_id = $${params.length + 1}`); params.push(req.tenant.id) }
            if (status) { where.push(`o.status = $${params.length + 1}`); params.push(status) }
            if (from)   { where.push(`o.created_at >= $${params.length + 1}`); params.push(from) }
            if (to)     { where.push(`o.created_at <= $${params.length + 1}`); params.push(to + 'T23:59:59') }

            const sql = `
                SELECT o.id, o.status, o.total_amount, o.payment_method,
                       o.created_at, o.updated_at, o.user_cpf,
                       u.nome AS user_nome, u.telefone AS user_telefone,
                       COUNT(t.id)::int AS ticket_count
                FROM orders o
                LEFT JOIN users u ON u.cpf = o.user_cpf
                LEFT JOIN tickets t ON t.order_id = o.id
                ${where.length ? 'WHERE ' + where.join(' AND ') : ''}
                GROUP BY o.id, u.nome, u.telefone
                ORDER BY o.created_at DESC
                LIMIT 300
            `
            const rows = await query(sql, params)
            return res.json(rows ?? [])
        } catch (err) {
            console.error('[Admin] listOrders:', err.message)
            return res.status(500).json({ error: 'Erro ao listar pedidos' })
        }
    },

    // ── Gestão de Resgates (raffle_claims) ────────────────────────────────────

    async listClaims(req, res) {
        try {
            const { status } = req.query
            const params = []
            const where = []
            if (req.tenant?.id) { where.push(`r.tenant_id = $${params.length + 1}`); params.push(req.tenant.id) }
            if (status)         { where.push(`c.status = $${params.length + 1}`);    params.push(status) }

            let sql = `
                SELECT c.id, c.status, c.delivery_address, c.delivery_notes,
                       c.claimed_at, c.updated_at,
                       r.titulo   AS raffle_titulo,
                       t.numero   AS ticket_numero,
                       u.nome     AS user_nome,
                       u.cpf      AS user_cpf,
                       u.telefone AS user_telefone
                FROM raffle_claims c
                JOIN raffles r ON r.id = c.raffle_id
                JOIN tickets t ON t.id = c.ticket_id
                LEFT JOIN users u ON u.cpf = c.user_cpf
                ${where.length ? 'WHERE ' + where.join(' AND ') : ''}
            `
            const rows = await query(sql, params)
            return res.json(rows ?? [])
        } catch (err) {
            return res.status(500).json({ error: 'Erro ao listar resgates' })
        }
    },

    async updateClaimStatus(req, res) {
        try {
            const { id } = req.params
            const { status } = req.body
            const VALID = ['pending', 'approved', 'delivered']
            if (!VALID.includes(status)) {
                return res.status(400).json({ error: `Status inválido. Use: ${VALID.join(', ')}` })
            }

            const claim = await Claim.getClaimDetails(id)
            if (!claim) return res.status(404).json({ error: 'Resgate não encontrado' })

            await Claim.updateStatus(id, status)

            // Notifica o ganhador sobre a mudança de status
            const user = await queryOne('SELECT nome, telefone FROM users WHERE cpf = $1', [claim.user_cpf])
            if (status === 'approved') {
                NotificationService.notifyClaimApproved(
                    user?.telefone, claim.user_cpf, user?.nome, claim.raffle_titulo
                ).catch(() => {})
            } else if (status === 'delivered') {
                NotificationService.notifyClaimDelivered(
                    user?.telefone, claim.user_cpf, user?.nome, claim.raffle_titulo
                ).catch(() => {})
            }

            return res.json({ ok: true, status })
        } catch (err) {
            return res.status(500).json({ error: 'Erro ao atualizar resgate' })
        }
    },
}

module.exports = adminController
