import { NextRequest, NextResponse } from "next/server";
import mongoose from "mongoose";
import states from "@/models/State";

import dbConnect from "@/lib/mongodb";
import { authenticate } from "@/lib/authenticate";

import UserAddress from "@/models/useDetails";

export async function GET(request: NextRequest) {
  try {
    await dbConnect();

    const authUser = await authenticate(request);

    const addresses = await UserAddress.find({
      user: authUser.userId,
    })
     .populate({
            path: "state",
            model: "states",
            })
      .sort({
        isDefault: -1,
        createdAt: -1,
      });

    return NextResponse.json(
      {
        success: true,
        data: addresses,
      },
      { status: 200 }
    );
  } catch (error: any) {
    return NextResponse.json(
      {
        success: false,
        message: error.message || "Unauthorized",
      },
      { status: 401 }
    );
  }
}

export async function POST(request: NextRequest) {
  try {
    await dbConnect();

    const authUser = await authenticate(request);

    const body = await request.json();

    const {
      name,
      phone,
      addressLine1,
      addressLine2,
      city,
      state,
      pincode,
      isDefault,
    } = body;

    if (!name) {
      return NextResponse.json(
        {
          success: false,
          message: "Name is required",
        },
        { status: 400 }
      );
    }

    if (!phone) {
      return NextResponse.json(
        {
          success: false,
          message: "Phone is required",
        },
        { status: 400 }
      );
    }

    if (!addressLine1) {
      return NextResponse.json(
        {
          success: false,
          message: "Address is required",
        },
        { status: 400 }
      );
    }

    if (!city) {
      return NextResponse.json(
        {
          success: false,
          message: "City is required",
        },
        { status: 400 }
      );
    }

    if (!state) {
      return NextResponse.json(
        {
          success: false,
          message: "State is required",
        },
        { status: 400 }
      );
    }

    if (!pincode) {
      return NextResponse.json(
        {
          success: false,
          message: "Pincode is required",
        },
        { status: 400 }
      );
    }

    if (isDefault) {
      await UserAddress.updateMany(
        {
          user: authUser.userId,
        },
        {
          isDefault: false,
        }
      );
    }

    const address = await UserAddress.create({
      user: authUser.userId,
      name,
      phone,
      addressLine1,
      addressLine2,
      city,
      state,
      pincode,
      isDefault: isDefault || false,
    });

    return NextResponse.json(
      {
        success: true,
        message: "Address added successfully",
        data: address,
      },
      { status: 201 }
    );
  } catch (error: any) {
    return NextResponse.json(
      {
        success: false,
        message: error.message,
      },
      { status: 500 }
    );
  }
}

export async function PUT (request: NextRequest) {
  try {
    await dbConnect();

    const authUser = await authenticate(request);

    const body = await request.json();

    const {
      addressId,
      name,
      phone,
      addressLine1,
      addressLine2,
      city,
      state,
      pincode,
      isDefault,
    } = body;

    if (!addressId) {
      return NextResponse.json(
        {
          success: false,
          message: "Address ID is required",
        },
        { status: 400 }
      );
    }

    const address = await UserAddress.findOne({
      _id: addressId,
      user: authUser.userId,
    });

    if (!address) {
      return NextResponse.json(
        {
          success: false,
          message: "Address not found",
        },
        { status: 404 }
      );
    }

    if (isDefault === true) {
      await UserAddress.updateMany(
        {
          user: authUser.userId,
        },
        {
          isDefault: false,
        }
      );
    }

    const updatedAddress = await UserAddress.findByIdAndUpdate(
      addressId,
      {
        name,
        phone,
        addressLine1,
        addressLine2,
        city,
        state,
        pincode,
        isDefault,
      },
      {
        new: true,
        runValidators: true,
      }
    );

    return NextResponse.json(
      {
        success: true,
        message: "Address updated successfully",
        data: updatedAddress,
      },
      { status: 200 }
    );
  } catch (error: any) {
    return NextResponse.json(
      {
        success: false,
        message: error.message,
      },
      { status: 500 }
    );
  }
}

export async function DELETE(request: NextRequest) {
  try {
    await dbConnect();

    const authUser = await authenticate(request);

    const { searchParams } = new URL(request.url);

    const addressId = searchParams.get("addressId");

    if (!addressId) {
      return NextResponse.json(
        {
          success: false,
          message: "Address ID is required",
        },
        { status: 400 }
      );
    }

    const address = await UserAddress.findOne({
      _id: addressId,
      user: authUser.userId,
    });

    if (!address) {
      return NextResponse.json(
        {
          success: false,
          message: "Address not found",
        },
        { status: 404 }
      );
    }

    await UserAddress.findByIdAndDelete(addressId);

    return NextResponse.json(
      {
        success: true,
        message: "Address deleted successfully",
      },
      { status: 200 }
    );
  } catch (error: any) {
    return NextResponse.json(
      {
        success: false,
        message: error.message,
      },
      { status: 500 }
    );
  }
}