const API = require("../../../lib/API")
const axios = require('axios')
const https = require('https')
const { v4: uuidv4 } = require('uuid')
const db = require("../../../plugin/DataBase/db")
const Redis = require('../../../plugin/DataBase/Redis')
const config = require('../../../config.json')
const { BaseStdResponse } = require("../../../BaseStdResponse")

class Login extends API {
    constructor() {
        super()

        this.setPath('/UniLogin/Login')
        this.setMethod('POST')
    }

    async onRequest(req, res) {
        let { type, code } = req.body

        if ([code].some(value => value === '' || value === null || value === undefined))
            return res.json({
                ...BaseStdResponse.MISSING_PARAMETER
            })

        const uniConfig = config.unilogin

        let url = `${uniConfig.url}/connect.php?act=callback&appid=${uniConfig.appid}&appkey=${uniConfig.appkey}&type=${type || 'qq'}&code=${code}`
        try {
            const agent = new https.Agent({
                rejectUnauthorized: false
            })

            const r = await axios.get(url, {
                httpsAgent: agent,
                proxy: false
            })

            if (!r || r.data?.code !== 0) {
                this.logger.error(`获取用户信息失败！${r.data?.msg || 'api接口错误'}`)
                return res.json({
                    ...BaseStdResponse.ERR,
                    msg: '获取用户信息失败！'
                })
            }

            let { social_uid, nickname, faceimg, ip } = r.data
            const session = uuidv4()
            const time = new Date().getTime()

            let selectSql = 'SELECT uuid, username, permission FROM users WHERE social_uid = ? AND social_type = ?'
            let selectRows = await db.query(selectSql, [social_uid, type || 'qq'])

            let uuid, username, permission

            // 用户不存在 执行注册操作
            if (selectRows.length == 0) {
                uuid = uuidv4()
                username = `用户${uuid.slice(0, 8)}`

                let regSql = 'INSERT INTO users (uuid, username, registTime, social_uid, social_type, nickname, avatar, email) VALUES (?,?,?,?,?,?,?,?) '
                let regRows = await db.query(regSql, [uuid, username, time, social_uid, type || 'qq', nickname, faceimg, '未设置'])
                if (!regRows || regRows.affectedRows !== 1) {
                    this.logger.error(`聚合登录用户注册失败！数据库错误`)
                    return res.json({
                        ...BaseStdResponse.ERR,
                        msg: '用户注册失败！'
                    })
                }
            }
            else {
                uuid = selectRows[0].uuid
                username = selectRows[0].username
                permission = selectRows[0].permission
            }

            await Redis.set(`userSession:${uuid}`, session, {
                EX: 2592000
            })

            res.json({
                ...BaseStdResponse.OK,
                data: {
                    uuid,
                    username,
                    session,
                    nickname,
                    type: type || 'qq',
                    roles: permission || [],
                    avatar: faceimg,
                }
            })

            // 增加登录记录
            try {
                if (selectRows.length !== 0) {
                    let updateSql = 'UPDATE users SET lastTime = ?, avatar = ?, nickname = ? WHERE social_uid = ? AND social_type = ?'
                    await db.query(updateSql, [time, faceimg, nickname, social_uid, type || 'qq'])
                }

                const userAgent = req.headers['user-agent']
                let insertSql = 'INSERT INTO login_history (uuid, time, deviceInfo, type, ip) VALUES (?, ?, ?, ?, ?)'
                await db.query(insertSql, [uuid, time, { 'ua': userAgent }, type || 'qq', ip])
            } catch (error) {
                this.logger.error(`写入登录记录失败！${error}`)
            }
        } catch (error) {
            this.logger.error(`获取用户信息失败！${error.message || 'api接口错误'}`)
            return res.json({
                ...BaseStdResponse.ERR,
                msg: '获取用户信息失败！'
            })
        }
    }
}

module.exports.Login = Login