import ScammerGuard from '#models/scammer_guard'
import ScammerKeyword from '#models/scammer_keyword'
import ScammerWhitelist from '#models/scammer_whitelist'
import Device from '#models/device'
import db from '@adonisjs/lucid/services/db'
import vine, { errors as vineErrors } from '@vinejs/vine'
import { DateTime } from 'luxon'

export default class ScammerGuardController {

    // Bug #8 fix: Validate device token for write operations
    async #requireToken(request, response) {
        const token = request.input('token') || request.header('x-api-token')
        if (!token) {
            response.unauthorized({ message: 'API token diperlukan.' })
            return false
        }
        const device = await Device.query()
            .preload('accessTokens')
            .whereHas('accessTokens', (q) => q.where('token', token))
            .first()
        if (!device) {
            response.unauthorized({ message: 'Token tidak sah.' })
            return false
        }
        return true
    }

    async index({ response }) {
        const now = DateTime.now().toISO()
        const scammers = await ScammerGuard.query()
            .where('is_active', true)
            .orderBy('created_at', 'desc')
        // Filter out expired
        const active = scammers.filter(s => !s.expiresAt || s.expiresAt > now)
        return response.ok({ data: active.map(s => s.serialize()) })
    }

    async check({ request, response }) {
        const phone = request.input('phone', '').replace(/[\s\-\+]/g, '')
        if (!phone) return response.badRequest({ message: 'Phone number is required.' })
        const now = DateTime.now().toISO()
        const scammer = await ScammerGuard.query()
            .where('phone', phone)
            .where('is_active', true)
            .first()
        const isScammer = !!scammer && (!scammer.expiresAt || scammer.expiresAt > now)
        return response.ok({
            is_scammer: isScammer,
            data: isScammer ? scammer.serialize() : null,
        })
    }

    async store({ request, response }) {
        if (!await this.#requireToken(request, response)) return
        try {
            const data = await request.validateUsing(vine.compile(vine.object({
                phone: vine.string().trim().maxLength(30),
                name: vine.string().trim().maxLength(100).optional(),
                reason: vine.string().trim().maxLength(500).optional(),
                action: vine.enum(['log', 'warn', 'kick', 'block']),
            })))
            const phone = data.phone.replace(/[\s\-\+]/g, '')
            const existing = await ScammerGuard.query().where('phone', phone).first()
            if (existing) return response.unprocessableEntity({ message: 'Phone number already blacklisted.' })
            const scammer = await ScammerGuard.create({
                phone,
                name: data.name || null,
                reason: data.reason || null,
                action: data.action,
                isActive: true,
                hitCount: 0,
            })
            return response.created({ message: 'Added to blacklist.', data: scammer.serialize() })
        } catch (error) {
            if (error instanceof vineErrors.E_VALIDATION_ERROR) return response.unprocessableEntity({ errors: error.messages })
            return response.internalServerError({ message: error.message })
        }
    }

    async destroy({ params, request, response }) {
        if (!await this.#requireToken(request, response)) return
        const scammer = await ScammerGuard.find(params.id)
        if (!scammer) return response.notFound({ message: 'Record not found.' })
        await scammer.delete()
        return response.ok({ message: 'Removed from blacklist.' })
    }

    async keywords({ response }) {
        const keywords = await ScammerKeyword.query().where('is_active', true).orderBy('created_at', 'desc')
        return response.ok({ data: keywords.map(k => k.serialize()) })
    }

    async whitelistIndex({ response }) {
        const whitelist = await ScammerWhitelist.query().orderBy('created_at', 'desc')
        return response.ok({ data: whitelist.map(w => w.serialize()) })
    }

    async whitelistCheck({ request, response }) {
        const phone = request.input('phone', '').replace(/[\s\-\+]/g, '')
        if (!phone) return response.badRequest({ message: 'Phone number is required.' })
        const entry = await ScammerWhitelist.query().where('phone', phone).first()
        return response.ok({ is_whitelisted: !!entry, data: entry ? entry.serialize() : null })
    }

    async logs({ request, response }) {
        const limit = Math.min(parseInt(request.input('limit', '50')), 500)
        const offset = parseInt(request.input('offset', '0'))
        const logs = await db.from('scammer_logs').orderBy('created_at', 'desc').limit(limit).offset(offset)
        const total = await db.from('scammer_logs').count('id as total').first()
        return response.ok({ data: logs, total: parseInt(total?.total || 0) })
    }
}
