import { db } from "@/lib/db"
import { getCurrentUser } from "@/lib/session"
import { NextResponse } from "next/server"
import { z } from "zod"

/**
 * @swagger
 * /api/users/follow:
 *   get:
 *     description: Get Followers for signed in User
 *     responses:
 *       200:
 *         description: fetched follows!
 *       500:
 *          description: Error    
 *   
 *   put:
 *     description: Creates Following Record from one User to another
 *     requestBody:
 *        content:
 *         application/json:
 *           schema:      # Request body contents
 *             type: object
 *             properties:
 *               follwerid:
 *                 type: string
 *               followingid:
 *                 type: string
 *             example:   # Sample object
 *               follwerid:: 10
 *               followingid:: 12
 *     responses:
 *       200:
 *         description: Follow handled!
 *       401:
 *         description: Unauthorized
 *       500:
 *          description: Error
 *           
 */


// get following or followers information
export async function GET(request: Request) {
    const { searchParams } = new URL(request.url)
    const userId = searchParams.get("userId") || undefined
    const type = searchParams.get("type") || undefined

    const userIdSchema = z.string().cuid().optional()
    const zod = userIdSchema.safeParse(userId)

    if (!zod.success) {
        return NextResponse.json(zod.error, { status: 400 })
    }

    try {
        if (type === "followers") {
            const followers = await db.user
                .findUnique({
                    where: {
                        id: userId,
                    },
                })
                .followers()
            return NextResponse.json(followers, { status: 200 })
        } else if (type === "following") {
            const following = await db.user
                .findUnique({
                    where: {
                        id: userId,
                    },
                })
                .following()

            return NextResponse.json(following, { status: 200 })
        }
    } catch (error: any) {
        return NextResponse.json(error.message, { status: 500 })
    }
}

// follow a user
export async function PUT(request: Request) {
    const session = await getCurrentUser()
    const { userId } = await request.json()

    const followerIdSchema = z
        .object({
            userId: z.string().cuid(),
        })
        .strict()

    const zod = followerIdSchema.safeParse({ userId })

    if (!zod.success) {
        return NextResponse.json(zod.error, { status: 400 })
    }

    try {
        await db.user.update({
            where: {
                id: userId,
            },

            data: {
                followers: {
                    connect: {
                        id: session?.id,
                    },
                },
            },
        })

        return NextResponse.json(
            {
                message: "followed",
            }, { status: 200 }
        )
    } catch (error: any) {
        return NextResponse.json(error.message, { status: 500 })
    }
}

// unfollow a user
export async function DELETE(request: Request) {
    const session = await getCurrentUser()
    const { userId } = await request.json()

    const followerIdSchema = z
        .object({
            userId: z.string().cuid(),
        })
        .strict()

    const zod = followerIdSchema.safeParse({ userId })

    if (!zod.success) {
        return NextResponse.json(zod.error, { status: 400 })
    }

    try {
        await db.user.update({
            where: {
                id: userId,
            },

            data: {
                followers: {
                    disconnect: {
                        id: session?.id,
                    },
                },
            },
        })

        return NextResponse.json(
            {
                message: "unfollowed",
            }, { status: 200 },
        )
    } catch (error: any) {
        return NextResponse.json(error.message, { status: 500 })
    }
}