import { NextFunction, Request, Response } from "express";
import { CatchAsyncError } from "../../middleware/Catch";
import { verifyWebhook } from '@clerk/express/webhooks'
import { AuthService } from "./auth.service";
import { ApiError } from "../../middleware/ApiError";
import { ApiResponse } from "../../middleware/ApiResponse";
import jwt, { JwtPayload } from 'jsonwebtoken'

export const ClerkAuthentication = CatchAsyncError(async (req: Request, res: Response, next: NextFunction) => {

    const secret = process.env.CLERK_WEBHOOK_SIGNING_SECRET as string;
    if (!secret) {
        throw new Error("CLERK_WEBHOOK_SIGNING_SECRET is missing!");
    }
    const evt = await verifyWebhook(req, { signingSecret: secret })


    const eventType = evt.type


    if (!evt.data.id) {
        throw new ApiError("Missing User ID", 400)
    }




    if (eventType === "user.created") {
        const { data } = evt
        const checker = await AuthService.findAuthByIdService(data.id);

        if (checker) {
            throw new ApiError("Invalid Credentials try with Different Email", 400)
        }

        const findEmail = await AuthService.findAuthEmailService(data.email_addresses[0].email_address)

        if (findEmail?.email) {
            throw new ApiError("Invalid Credentials try with Different Email", 400)
        }


        await AuthService.createAuthService({
            clerkId: data.id,
            firstName: data.first_name,
            lastName: data.last_name,
            email: data.email_addresses[0].email_address

        })

    }


    if (eventType === "user.updated") {

        const { data } = evt
        const checker = await AuthService.findAuthByIdService(data.id);


        if (!checker) {
            throw new ApiError("Invalid Credentials try with Different Email", 400)
        }
        await AuthService.updateAuthService({
            firstName: data?.first_name,
            lastName: data?.last_name
        },
            data.id)



    }


    if (eventType === "user.deleted") {


        const { data } = evt

        const checker = await AuthService.findAuthByIdService(data.id as string);


        if (!checker) {
            throw new ApiError("Invalid Credentials try with Different Email", 400)
        }


        await AuthService.deleteAuthService(evt.data.id)

    }


    return res.status(200).json(
        new ApiResponse("Validate Successfully !!", 200, [])
    )

})



export const SignUpTokenValidate = CatchAsyncError(async (req: Request, res: Response, next: NextFunction) => {


    const token = req.query.ticket as string



    if (!token || typeof token !== "string") {
        throw new ApiError("Missing or invalid token", 400); // 400 Bad Request
    }



    const decoded = jwt.verify(token, process.env.CLERK_JWT_KEY!, { algorithms: ["RS256"] });


    

    const verifyJWT = decoded as JwtPayload;

    console.log(verifyJWT)

    if (verifyJWT.st !== "invitation" || verifyJWT.rurl !== `${process.env.ACCESS_DOMAIN}/register`) {
        throw new ApiError("Invalid invitation token", 403); // 403 Forbidden
    }


    res.status(200).json(
        new ApiResponse("Invitation valid", 200, { valid: true })
    );


})

