import { FastifyInstance } from "fastify"
import bcrypt from "bcrypt"
import { eq } from "drizzle-orm"
import jwt from "jsonwebtoken"
import { secrets } from "../../utils/secrets"

import { authUsers } from "../../../db/schema"  // wichtig: Drizzle Schema importieren!

export default async function authRoutesAuthenticated(server: FastifyInstance) {

    server.post("/auth/refresh", {
        schema: {
            tags: ["Auth"],
            summary: "Refresh JWT for current authenticated user",
            response: {
                200: {
                    type: "object",
                    properties: {
                        token: { type: "string" },
                    },
                    required: ["token"],
                },
                401: {
                    type: "object",
                    properties: {
                        error: { type: "string" },
                    },
                    required: ["error"],
                },
            },
        },
    }, async (req, reply) => {
        if (!req.user?.user_id) {
            return reply.code(401).send({ error: "Unauthorized" })
        }

        const token = jwt.sign(
            {
                user_id: req.user.user_id,
                email: req.user.email,
                tenant_id: req.user.tenant_id,
            },
            secrets.JWT_SECRET!,
            { expiresIn: "6h" }
        )

        reply.setCookie("token", token, {
            path: "/",
            httpOnly: true,
            sameSite: process.env.NODE_ENV === "production" ? "none" : "lax",
            secure: process.env.NODE_ENV === "production",
            maxAge: 60 * 60 * 6,
        })

        return { token }
    })

    server.post("/auth/password/change", {
        schema: {
            tags: ["Auth"],
            summary: "Change password (after login or forced reset)",
            body: {
                type: "object",
                required: ["old_password", "new_password"],
                properties: {
                    old_password: { type: "string" },
                    new_password: { type: "string" },
                },
            },
            response: {
                200: {
                    type: "object",
                    properties: {
                        success: { type: "boolean" },
                    },
                },
            },
        },
    }, async (req, reply) => {

        try {
            const { old_password, new_password } = req.body as {
                old_password: string
                new_password: string
            }

            const userId = req.user?.user_id
            if (!userId) {
                //@ts-ignore
                return reply.code(401).send({ error: "Unauthorized" })
            }

            // -----------------------------------------------------
            // 1) User laden
            // -----------------------------------------------------
            const [user] = await server.db
                .select({
                    id: authUsers.id,
                    passwordHash: authUsers.passwordHash,
                    mustChangePassword: authUsers.must_change_password
                })
                .from(authUsers)
                .where(eq(authUsers.id, userId))
                .limit(1)

            if (!user) {
                //@ts-ignore
                return reply.code(404).send({ error: "User not found" })
            }

            // -----------------------------------------------------
            // 2) Altes PW prüfen
            // -----------------------------------------------------
            const valid = await bcrypt.compare(old_password, user.passwordHash)
            if (!valid) {
                //@ts-ignore
                return reply.code(401).send({ error: "Old password incorrect" })
            }

            // -----------------------------------------------------
            // 3) Neues PW hashen
            // -----------------------------------------------------
            const newHash = await bcrypt.hash(new_password, 10)

            // -----------------------------------------------------
            // 4) Updaten
            // -----------------------------------------------------
            await server.db
                .update(authUsers)
                .set({
                    passwordHash: newHash,
                    must_change_password: false,
                    updatedAt: new Date(),
                })
                .where(eq(authUsers.id, userId))

            return { success: true }

        } catch (err) {
            console.error("POST /auth/password/change ERROR:", err)
            //@ts-ignore
            return reply.code(500).send({ error: "Internal Server Error" })
        }
    })
}
