/*
 *     The Peacock Project - a HITMAN server replacement.
 *     Copyright (C) 2021-2023 The Peacock Project Team
 *
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Affero General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU Affero General Public License for more details.
 *
 *     You should have received a copy of the GNU Affero General Public License
 *     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

import type {
    ChallengeProgressionData,
    CompiledChallengeIngameData,
    RequestWithJwt,
} from "../types/types"
import { log, LogLevel } from "../loggingInterop"
import { getConfig } from "../configSwizzleManager"

import { Router } from "express"
import { controller } from "../controller"
import { getPlatformEntitlements } from "../platformEntitlements"
import { json as jsonMiddleware } from "body-parser"
import { uuidRegex } from "../utils"
import { menuSystemDatabase } from "../menus/menuSystem"
import { compileRuntimeChallenge } from "../candle/challengeHelpers"
import { LegacyGetProgressionBody } from "../types/gameSchemas"

const legacyProfileRouter = Router()

// /authentication/api/userchannel/

legacyProfileRouter.post(
    "/ProfileService/GetPlatformEntitlements",
    jsonMiddleware(),
    getPlatformEntitlements,
)

legacyProfileRouter.post(
    "/AuthenticationService/GetBlobOfflineCacheDatabaseDiff",
    (req: RequestWithJwt, res) => {
        const configs = []

        menuSystemDatabase.hooks.getDatabaseDiff.call(configs, req.gameVersion)

        res.json(configs)
    },
)

legacyProfileRouter.post(
    "/ChallengesService/GetActiveChallenges",
    jsonMiddleware(),
    (req: RequestWithJwt, res) => {
        if (!uuidRegex.test(req.body.contractId)) {
            return res.status(404).send("invalid contract")
        }

        const legacyGlobalChallenges = getConfig<CompiledChallengeIngameData[]>(
            "LegacyGlobalChallenges",
            false,
        )

        const json = controller.resolveContract(req.body.contractId)

        if (!json) {
            log(
                LogLevel.ERROR,
                `Unknown contract in LGAC: ${req.body.contractId}`,
            )
            return res.status(404).send("contract not found")
        }

        if (json.Metadata.Type === "creation") {
            return res.json([])
        }

        const challenges: CompiledChallengeIngameData[] = legacyGlobalChallenges

        challenges.push(
            ...Object.values(
                controller.challengeService.getChallengesForContract(
                    json.Metadata.Id,
                    req.gameVersion,
                    req.jwt.unique_name,
                ),
            )
                .flat()
                .map(
                    (challengeData) =>
                        compileRuntimeChallenge(
                            challengeData,
                            controller.challengeService.getPersistentChallengeProgression(
                                req.jwt.unique_name,
                                challengeData.Id,
                                req.gameVersion,
                            ),
                        ).Challenge,
                ),
        )

        res.json(challenges)
    },
)

legacyProfileRouter.post(
    "/ChallengesService/GetProgression",
    jsonMiddleware(),
    (req: RequestWithJwt<never, LegacyGetProgressionBody>, res) => {
        const legacyGlobalChallenges = getConfig<CompiledChallengeIngameData[]>(
            "LegacyGlobalChallenges",
            false,
        )

        const challenges: ChallengeProgressionData[] =
            legacyGlobalChallenges.map((challenge) => ({
                ChallengeId: challenge.Id,
                ProfileId: req.jwt.unique_name,
                Completed: false,
                // Here we don't care about "Ticked" and the client will ignore it
                Ticked: false,
                State: {},
                ETag: `W/"datetime'${encodeURIComponent(
                    new Date().toISOString(),
                )}'"`,
                CompletedAt: null,
                MustBeSaved: false,
            }))

        /*
        for (const challengeId of req.body.challengeids) {
            const challenge =
                controller.challengeService.getChallengeById(challengeId)

            if (!challenge) {
                log(
                    LogLevel.ERROR,
                    `Unknown challenge in LCSGP: ${challengeId}`,
                )
                continue
            }

            const progression =
                controller.challengeService.getChallengeProgression(
                    req.jwt.unique_name,
                    challengeId,
                    req.gameVersion,
                )

            challenges.push({
                ChallengeId: challengeId,
                ProfileId: req.jwt.unique_name,
                Completed: progression.Completed,
                State: progression.State,
                ETag: `W/"datetime'${encodeURIComponent(
                    new Date().toISOString(),
                )}'"`,
                CompletedAt: progression.CompletedAt,
                MustBeSaved: false,
            })
        }
         */
        // TODO: atampy broke this - please fix
        //      update(RD) nov 18 '22: fixed but still missing challenges in
        //      2016 engine (e.g. showstopper is missing 9, 5 of which are the
        //      classics I think, not sure about the other 4)

        res.json(challenges)
    },
)

export { legacyProfileRouter }