const db = require("../config/db");
const genCards = require("../middleware/genCards");

class HousesService {
    getListEntrance() {
        return new Promise((res, rej) => {
            let sql = `
                SELECT 
                    entrance.*, 
                    COALESCE((SELECT entrance_history.working FROM entrance_history WHERE entrance_history.entrance_id = entrance.id ORDER BY entrance_history.date_start DESC LIMIT 1), 0) AS working,
                    (SELECT entrance_history.name FROM entrance_history WHERE entrance_history.entrance_id = entrance.id ORDER BY entrance_history.date_start DESC LIMIT 1) AS entrance_history_name,
                    (SELECT entrance_history.group_id FROM entrance_history WHERE entrance_history.entrance_id = entrance.id ORDER BY entrance_history.date_start DESC LIMIT 1) AS entrance_history_group_id,
                    (SELECT entrance_history.sheep_id FROM entrance_history WHERE entrance_history.entrance_id = entrance.id ORDER BY entrance_history.date_start DESC LIMIT 1) AS entrance_history_sheep_id,
                    (SELECT entrance_history.id FROM entrance_history WHERE entrance_history.entrance_id = entrance.id ORDER BY entrance_history.date_start DESC LIMIT 1) AS entrance_history_id,
                    (SELECT entrance_history.date_start FROM entrance_history WHERE entrance_history.entrance_id = entrance.id ORDER BY entrance_history.date_start DESC LIMIT 1) AS entrance_history_date_start,
                    (SELECT entrance_history.date_end FROM entrance_history WHERE entrance_history.entrance_id = entrance.id ORDER BY entrance_history.date_start DESC LIMIT 1) AS entrance_history_date_end,
                    (SELECT house.settlement FROM house WHERE house.id = entrance.house_id) AS house_settlement,
                    (SELECT house.title FROM house WHERE house.id = entrance.house_id) AS house_title,
                    (SELECT house.number FROM house WHERE house.id = entrance.house_id) AS house_number
                FROM 
                    entrance
            `;

            db.all(sql, (err, rows) => {
                if (err) {
                    console.error(err.message);
                    return res(false);
                } else {
                    let data = rows.map((row) => {
                        return {
                            "id": Number(row.id),
                            "house": {
                                "id": Number(row.house_id),
                                "title": row.house_title,
                                "number": row.house_number,
                                "settlement": row.house_settlement
                            },
                            "entrance_number": Number(row.entrance_number),
                            "title": row.title,
                            "floors_quantity": row.floors_quantity,
                            "apartments_quantity": row.apartments_quantity,
                            "description": row.description,
                            "created_at": Number(row.created_at),
                            "updated_at": Number(row.updated_at),
                            "working": Number(row.working) == 0 ? false : true,
                            "history": {
                                "id": row.entrance_history_id ? Number(row.entrance_history_id) : null,
                                "name": row.entrance_history_name,
                                "group_id": row.entrance_history_group_id ? Number(row.entrance_history_group_id) : null,
                                "sheep_id": row.entrance_history_sheep_id ? Number(row.entrance_history_sheep_id) : null,
                                "date": {
                                    "start": row.entrance_history_date_start ? Number(row.entrance_history_date_start) : null,
                                    "end": row.entrance_history_date_end ? Number(row.entrance_history_date_end) : null
                                }
                            }
                        }
                    })

                    return res(data);
                }
            });
        });
    }

    getList(mode, id) {
        return new Promise((res, rej) => {
            let sql = `
                SELECT 
                    house.*,
                    (SELECT COUNT(DISTINCT entrance_history.id) FROM entrance_history JOIN entrance ON entrance.id = entrance_history.entrance_id WHERE entrance.house_id = house.id AND entrance_history.working = 1 ORDER BY entrance_history.date_start DESC) AS working,
                    (SELECT COUNT(*) FROM entrance WHERE entrance.house_id = house.id) AS entrance_quantity
                FROM 
                    house
            `;

            if (mode == "group") {
                sql = `
                    SELECT DISTINCT
                        house.*, 
                        (SELECT COUNT(DISTINCT entrance_history.id) FROM entrance_history JOIN entrance ON entrance.id = entrance_history.entrance_id WHERE entrance.house_id = house.id AND entrance_history.working = 1 ORDER BY entrance_history.date_start DESC) AS working,
                        (SELECT COUNT(*) FROM entrance WHERE entrance.house_id = house.id) AS entrance_quantity
                    FROM 
                        house
                    JOIN 
                        entrance ON entrance.house_id = house.id
                    JOIN 
                        entrance_history ON entrance_history.entrance_id = entrance.id
                    WHERE 
                        entrance_history.working = 1 
                    AND 
                        entrance_history.name = 'Групова'
                    AND 
                        entrance_history.group_id = '${id}'
                `;
            } else if (mode == "sheep" || mode == "admin") {
                sql = `
                    SELECT DISTINCT 
                        house.*,
                        (SELECT COUNT(DISTINCT entrance_history.id) FROM entrance_history JOIN entrance ON entrance.id = entrance_history.entrance_id WHERE entrance.house_id = house.id AND entrance_history.working = 1 ORDER BY entrance_history.date_start DESC) AS working,
                        (SELECT COUNT(*) FROM entrance WHERE entrance.house_id = house.id) AS entrance_quantity
                    FROM 
                        house
                    JOIN 
                        entrance ON entrance.house_id = house.id
                    JOIN 
                        entrance_history ON entrance_history.entrance_id = entrance.id
                    WHERE 
                        entrance_history.working = 1 
                    AND 
                        entrance_history.sheep_id = '${id}'
                `;
            }

            db.all(sql, (err, rows) => {
                if (err) {
                    console.error(err.message);
                    return res(false);
                } else {
                    let data = rows.map((row) => {
                        return {
                            "id": Number(row.id),
                            "title": row.title,
                            "number": row.number,
                            "points": JSON.parse(row.points),
                            "points_number": JSON.parse(row.points_number),
                            "geo": JSON.parse(row.geo),
                            "zoom": Number(row.zoom),
                            "osm_id": JSON.parse(row.osm_id),
                            "settlement": row.settlement,
                            "description": row.description,
                            "created_at": Number(row.created_at),
                            "updated_at": Number(row.updated_at),
                            "entrance": {
                                "quantity": Number(row.entrance_quantity),
                                "working": Number(row.working)
                            }
                        }
                    })

                    return res(data);
                }
            });
        });
    }

    getHouse(house_id) {
        return new Promise((res, rej) => {
            let sql = `
                SELECT 
                    house.*,
                    (SELECT COUNT(DISTINCT entrance_history.id) FROM entrance_history JOIN entrance ON entrance.id = entrance_history.entrance_id WHERE entrance.house_id = house.id AND entrance_history.working = 1 ORDER BY entrance_history.date_start DESC) AS working,
                    (SELECT COUNT(*) FROM entrance WHERE entrance.house_id = house.id) AS entrance_quantity
                FROM 
                    house
                WHERE 
                    house.id = '${house_id}'
            `;

            db.get(sql, (err, row) => {
                if (err) {
                    console.error(err.message);
                    return res(false);
                } else if (!row) {
                    console.log({ "error": "house not found" });
                    return res(false);
                } else {
                    let data = {
                        "id": Number(row.id),
                        "title": row.title,
                        "number": row.number,
                        "points": JSON.parse(row.points),
                        "points_number": JSON.parse(row.points_number),
                        "geo": JSON.parse(row.geo),
                        "zoom": Number(row.zoom),
                        "osm_id": JSON.parse(row.osm_id),
                        "settlement": row.settlement,
                        "description": row.description,
                        "updated_at": Number(row.updated_at),
                        "entrance": {
                            "quantity": Number(row.entrance_quantity),
                            "working": Number(row.working) == 0 ? false : true
                        }
                    }

                    res(data);
                }
            });
        });
    }

    createHouse(data) {
        return new Promise((res, rej) => {
            let sql = `
                INSERT INTO 
                    house(
                    title,
                    number,
                    points,
                    points_number,
                    geo,
                    zoom
                    osm_id,
                    settlement,
                    description,
                    created_at,
                    updated_at
                    ) 
                VALUES 
                    (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            `;

            db.run(sql, [
                data.title,
                data.number,
                JSON.stringify(data.points),
                JSON.stringify(data.points_number),
                JSON.stringify(data.geo),
                Number(data.zoom),
                JSON.stringify(data.osm_id),
                data.settlement,
                data.description,
                Math.floor(new Date(Date.now()).getTime()),
                Math.floor(new Date(Date.now()).getTime()),
            ], function (err) {
                if (err) {
                    console.error(err.message);
                    return res(false);
                } else if (this.changes === 0) {
                    return res(false);
                } else {
                    res({ "status": "ok", "id": this.lastID });
                    genCards({type: "house", id: this.lastID});
                }
            });
        });
    }

    updateHouse(house_id, data) {
        return new Promise((res, rej) => {
            let sql = `
                UPDATE 
                    house
                SET 
                    title = ?,
                    number = ?,
                    points = ?,
                    points_number = ?,
                    geo = ?,
                    zoom = ?,
                    osm_id = ?,
                    settlement = ?,
                    description = ?,
                    updated_at = ?
                WHERE 
                    id = ?
            `;
            db.run(sql, [
                data.title,
                data.number,
                JSON.stringify(data.points),
                JSON.stringify(data.points_number),
                JSON.stringify(data.geo),
                Number(data.zoom),
                JSON.stringify(data.osm_id),
                data.settlement,
                data.description,
                Math.floor(new Date(Date.now()).getTime()),
                house_id
            ], function (err) {
                if (err) {
                    console.error(err.message);
                    return res(false);
                } else if (this.changes === 0) {
                    return res(false);
                } else {
                    res({ "status": "ok", "id": house_id });

                    genCards({type: "house", id: house_id});
                }
            });
        });
    }

    deleteHouse(house_id) {
        return new Promise((res, rej) => {
            db.run('DELETE FROM house WHERE id = ?', [house_id], function (err) {
                if (err) {
                    console.error(err.message);
                    return res(false);
                } else if (this.changes === 0) {
                    return res(false);
                } else {
                    res({ "status": "ok", "id": house_id });
                }
            });
        });
    }
}

module.exports = new HousesService();