const API = require("../../lib/API");
const { BaseStdResponse } = require("../../BaseStdResponse");
const db = require("../../plugin/DataBase/db");
const AccessControl = require("../../lib/AccessControl");

class AddAttendanceRecord extends API {
    constructor() {
        super();

        this.setPath('/AddAttendanceRecord');
        this.setMethod('GET');
    }

    async onRequest(req, res) {
        let {
            uuid,
            session,
            project_id
        } = req.query;

        // 检查必需的参数是否缺失
        if ([uuid, session, project_id].some(value => value === '' || value === null || value === undefined)) {
            res.json({
                ...BaseStdResponse.MISSING_PARAMETER,
                endpoint: 1513123
            });
            return;
        }

        // 检查 session 是否有效
        if (!await AccessControl.checkSession(uuid, session)) {
            res.json({
                ...BaseStdResponse.ACCESS_DENIED,
                endpoint: 48153145
            });
            return;
        }

        // 获取考勤项目
        const sqlGetProject = 'SELECT user, createTime, day_of_week, loopy, begintime, endtime FROM kq_items WHERE id = ?';
        let projectResult = await db.query(sqlGetProject, [project_id]);

        if (!projectResult || projectResult.length === 0) {
            res.json({
                ...BaseStdResponse.DATABASE_ERR,
                endpoint: 154754511
            });
            return;
        }

        let projectData = projectResult[0];
        let users = projectData.user;

        if (!users.includes(uuid)) {
            res.json({
                ...BaseStdResponse.ERR,
                endpoint: 481454,
                msg: '用户不在考勤名单中'
            });
            return;
        }

        const isWithinTime = this.isWithinAttendanceTime(projectData);
        if (!isWithinTime) {
            return res.json({
                ...BaseStdResponse.ERR,
                endpoint: 513513,
                msg: '未在打卡时间段内'
            });
        }

        // 检查是否已存在考勤记录
        const sqlCheckRecord = 'SELECT id, uuid, time FROM kq_records WHERE project_id = ? AND uuid = ?';
        let recordsResult = await db.query(sqlCheckRecord, [project_id, uuid]);

        if (!recordsResult) {
            return res.json({
                ...BaseStdResponse.DATABASE_ERR,
                endpoint: 513513
            });
        }

        if (recordsResult.length !== 0 && this.hasRecord(projectData, recordsResult, uuid)) {
            return res.json({
                ...BaseStdResponse.ERR,
                endpoint: 513513,
                msg: '用户在本考勤周期已有考勤记录！'
            });
        }

        // 插入考勤记录
        const sqlInsertRecord = 'INSERT INTO kq_records (project_id, uuid, time) VALUES (?, ?, ?)';
        let insertResult = await db.query(sqlInsertRecord, [project_id, uuid, new Date().getTime()]);

        if (!insertResult || insertResult.affectedRows !== 1) {
            return res.json({
                ...BaseStdResponse.DATABASE_ERR,
                endpoint: 513513
            });
        }

        res.json({
            ...BaseStdResponse.OK
        });
    }

    isWithinAttendanceTime(attendanceTimes) {
        const now = new Date();
        const dayOfWeek = now.getDay();
        const nowTime = now.getTime();

        function timeToTodayTimestamp(timeStr) {
            const [hours, minutes, seconds] = timeStr.split(':').map(Number);
            const todayWithTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), hours, minutes, seconds);
            return todayWithTime.getTime();
        }

        const { createTime, day_of_week, begintime, endtime, loopy } = attendanceTimes
        if (dayOfWeek === day_of_week && (loopy || (Number(createTime) + 604800000 - nowTime > 0)) && timeToTodayTimestamp(begintime) <= nowTime && timeToTodayTimestamp(endtime) >= nowTime) {
            return true;
        }
        return false
    }

    hasRecord(attendanceData, records, uuid) {
        const { day_of_week, begintime, endtime, loopy } = attendanceData;
        if (!loopy) {
            return records.some(record => record.uuid === uuid);
        }
        const now = new Date();
        const dayOfWeek = now.getDay();
        const nowTime = now.getTime();

        function getTimestamp(time) {
            const daysUntilTarget = (day_of_week - dayOfWeek + 7) % 7;
            const targetDate = new Date(now);
            targetDate.setDate(now.getDate() + daysUntilTarget);
            const [hours, minutes, seconds] = time.split(':').map(Number);
            targetDate.setHours(hours, minutes, seconds, 0);
            return targetDate.getTime();
        }

        const begin = getTimestamp(begintime);
        const end = getTimestamp(endtime);

        if (nowTime >= begin) {
            return records.some(record => record.time >= begin && record.time <= end && record.uuid === uuid);
        }
    }
}

module.exports.AddAttendanceRecord = AddAttendanceRecord;
