"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GTFSStopTimesModel = void 0;
const const_1 = require("../../../schema-definitions/const");
const ropid_gtfs_1 = require("../../../schema-definitions/ropid-gtfs");
const StopTimesDto_1 = require("../../../schema-definitions/ropid-gtfs/models/StopTimesDto");
const output_gateway_1 = require("@golemio/core/dist/output-gateway");
const ioc_1 = require("@golemio/core/dist/output-gateway/ioc/");
const golemio_errors_1 = require("@golemio/core/dist/shared/golemio-errors");
const sequelize_1 = __importDefault(require("@golemio/core/dist/shared/sequelize"));
class GTFSStopTimesModel extends output_gateway_1.SequelizeModel {
    constructor() {
        super(ropid_gtfs_1.RopidGTFS.stop_times.name, ropid_gtfs_1.RopidGTFS.stop_times.pgTableName, StopTimesDto_1.StopTimesDto.attributeModel, {
            schema: const_1.PG_SCHEMA,
        });
        this.Associate = (models) => {
            this.sequelizeModel.belongsTo(models.GTFSTripsModel.sequelizeModel, {
                foreignKey: "trip_id",
            });
            this.sequelizeModel.belongsTo(models.GTFSStopModel.sequelizeModel, {
                as: "stop",
                foreignKey: "stop_id",
                targetKey: "stop_id",
            });
        };
        /** Retrieves all gtfs stop times for specific stop id
         * @param {object} options Options object with params
         * @param {string} options.stopId Filter by specific stop id
         * @param {number} [options.limit] Limit
         * @param {number} [options.offset] Offset
         * @param {string} [options.from] Filter records since specific time in the 'H:mm:ss' format
         * @param {string} [options.to] Filter records until specific time in the 'H:mm:ss' format
         * @param {string} [options.date] Filter by specific date in the 'YYYY-MM-DD' format
         * @returns Array of the retrieved records
         */
        this.GetAll = async (options) => {
            const { limit, offset, to, from, date, stopId, stop } = options;
            const include = [];
            const where = {
                stop_id: stopId,
                [sequelize_1.default.Op.and]: [],
            };
            if (from) {
                where[sequelize_1.default.Op.and].push(GTFSStopTimesModel.arrivalTimeComparison(from, "<="));
            }
            if (to) {
                where[sequelize_1.default.Op.and].push(GTFSStopTimesModel.arrivalTimeComparison(to, ">="));
            }
            if (date) {
                include.push({
                    attributes: [],
                    include: [
                        {
                            as: "service",
                            attributes: [],
                            model: this.dbConnector.getConnection().models[ropid_gtfs_1.RopidGTFS.calendar.pgTableName].scope({
                                method: ["forDate", date],
                            }),
                        },
                    ],
                    model: this.dbConnector.getConnection().models[ropid_gtfs_1.RopidGTFS.trips.pgTableName],
                    required: true,
                });
            }
            if (stop) {
                include.push({
                    as: "stop",
                    model: this.dbConnector.getConnection().models[ropid_gtfs_1.RopidGTFS.stops.pgTableName],
                });
            }
            try {
                return await this.sequelizeModel.findAll({
                    attributes: {
                        // Exclude computed fields from the response
                        exclude: ["computed_dwell_time_seconds", "arrival_time_seconds", "departure_time_seconds", "timepoint"],
                    },
                    include,
                    limit,
                    offset,
                    order: [
                        ["stop_id", "ASC"],
                        ["departure_time", "ASC"],
                    ],
                    where,
                });
            }
            catch (err) {
                throw new golemio_errors_1.GeneralError("Database error", "GTFSStopTimesModel", err, 500);
            }
        };
        this.GetOne = (id) => {
            throw new golemio_errors_1.FatalError("Method not implemented");
        };
        this.dbConnector = ioc_1.OutputGatewayContainer.resolve(ioc_1.ContainerToken.PostgresDatabase);
    }
}
exports.GTFSStopTimesModel = GTFSStopTimesModel;
GTFSStopTimesModel.arrivalTimeComparison = (time, operator) => {
    // arrival_time 25:45:20 -> 01:45:20
    return sequelize_1.default.literal(`'${time}'::time ${operator} cast(arrival_time as interval)::time`);
};
//# sourceMappingURL=GTFSStopTimesModel.js.map