import { NextRequest, NextResponse } from "next/server";
import dbConnect from "../../src/lib/mongodb";
import User from "../../src/models/User";
import jwt from "jsonwebtoken";
import bcrypt from "bcryptjs";

const UPLOAD_SERVER_URL = "http://167.71.224.75:8700";
const UPLOAD_ENDPOINT = `${UPLOAD_SERVER_URL}/upload`;
const DELETE_ENDPOINT = `${UPLOAD_SERVER_URL}/delete`;

const JWT_SECRET = process.env.JWT_SECRET || "your-secret-key";

function getUserIdFromToken(request: NextRequest): string | null {
  try {
    const token = request.cookies.get("token")?.value;
    if (!token) return null;

    const decoded = jwt.verify(token, JWT_SECRET) as { userId: string };

    return decoded.userId;
  } catch (err) {
    console.log("JWT error:", err);
    return null;
  }
}

async function uploadToExternalServer(file: File): Promise<string> {
  try {
    const formData = new FormData();
    formData.append("file", file);

    const response = await fetch(UPLOAD_ENDPOINT, {
      method: "POST",
      body: formData,
    });

    if (!response.ok) {
      const errorText = await response.text();
      console.error("Upload failed:", response.status, errorText);
      throw new Error(`Upload failed: ${response.statusText}`);
    }

    const result = await response.json();

    if (result.success && result.url) {
      return `https://quality-web-developer.com/dulhe_sahebimages/uploads/${result.filename}`;
    } else if (result.success && result.filename) {
      return `https://quality-web-developer.com/dulhe_sahebimages/uploads/${result.filename}`;
    } else {
      throw new Error(result.error || "Invalid response from upload server");
    }
  } catch (error) {
    console.error("Error uploading to external server:", error);
    throw new Error("Failed to upload image to external server");
  }
}

async function deleteFromExternalServer(imageUrl: string): Promise<void> {
  try {
    const filename = imageUrl.split("/").pop();
    if (!filename) return;

    const response = await fetch(DELETE_ENDPOINT, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ filename }),
    });

    if (!response.ok) {
      console.error("Failed to delete image from external server");
    } else {
      console.log("Avatar deleted successfully:", filename);
    }
  } catch (error) {
    console.error("Error deleting from external server:", error);
  }
}

// GET (Fetch admin profile)
export async function GET(
  request: NextRequest,
  context?: { params: Promise<any> },
) {
  try {
    await dbConnect();

    const adminId = getUserIdFromToken(request);

    if (!adminId) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    const admin = await User.findById(adminId).select(
      "name email phone username bio avatar passwordChangedAt",
    );

    if (!admin) {
      return NextResponse.json(
        { success: false, error: "User not found" },
        { status: 404 },
      );
    }

    return NextResponse.json({ success: true, data: admin });
  } catch (error: any) {
    console.error("Error fetching profile:", error);
    return NextResponse.json(
      { success: false, error: error.message || "Failed to fetch profile" },
      { status: 500 },
    );
  }
}

// PUT (Update admin profile)
export async function PUT(
  request: NextRequest,
  context?: { params: Promise<any> },
) {
  try {
    await dbConnect();

    const adminId = getUserIdFromToken(request);

    if (!adminId) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    const existingUser = await User.findById(adminId);

    if (!existingUser) {
      return NextResponse.json(
        { success: false, error: "User not found" },
        { status: 404 },
      );
    }

    const formData = await request.formData();

    const name = formData.get("name") as string;
    const email = formData.get("email") as string;
    const phone = formData.get("phone") as string;
    const username = formData.get("username") as string;
    const bio = formData.get("bio") as string;
    const file = formData.get("avatar") as File;

    // Validation
    if (!name?.trim()) {
      return NextResponse.json(
        { success: false, error: "Name is required" },
        { status: 400 },
      );
    }

    if (!email?.trim()) {
      return NextResponse.json(
        { success: false, error: "Email is required" },
        { status: 400 },
      );
    }

    // Check email not taken by another user
    const emailExists = await User.findOne({
      email: email.trim().toLowerCase(),
      _id: { $ne: adminId },
    });

    if (emailExists) {
      return NextResponse.json(
        { success: false, error: "Email is already in use" },
        { status: 400 },
      );
    }

    // Check username not taken by another user
    if (username?.trim()) {
      const usernameExists = await User.findOne({
        username: username.trim(),
        _id: { $ne: adminId },
      });

      if (usernameExists) {
        return NextResponse.json(
          { success: false, error: "Username is already taken" },
          { status: 400 },
        );
      }
    }

    // Handle avatar upload — same pattern as productController
    let avatarUrl = existingUser.avatar;

    if (file && file.size > 0) {
      if (file.size > 2 * 1024 * 1024) {
        return NextResponse.json(
          { success: false, error: "Avatar must be under 2MB" },
          { status: 400 },
        );
      }

      // Delete old avatar from external server if exists
      if (
        existingUser.avatar &&
        existingUser.avatar.includes(
          "quality-web-developer.com/dulhe_sahebimages",
        )
      ) {
        await deleteFromExternalServer(existingUser.avatar);
      }

      // Upload new avatar to external server
      avatarUrl = await uploadToExternalServer(file);
    }

    const updateData = {
      name: name.trim(),
      email: email.trim().toLowerCase(),
      phone: phone?.trim() || "",
      username: username?.trim() || "",
      bio: bio?.trim() || "",
      avatar: avatarUrl || "",
    };

    const updatedUser = await User.findByIdAndUpdate(
      adminId,
      { $set: updateData },
      { new: true, runValidators: true },
    ).select("name email phone username bio avatar");

    return NextResponse.json({
      success: true,
      data: updatedUser,
      message: "Profile updated successfully",
    });
  } catch (error: any) {
    console.error("Error updating profile:", error);
    return NextResponse.json(
      { success: false, error: error.message || "Failed to update profile" },
      { status: 500 },
    );
  }
}

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

    const adminId = getUserIdFromToken(request);

    if (!adminId) {
      return NextResponse.json(
        { success: false, error: "Unauthorized" },
        { status: 401 },
      );
    }

    const { currentPassword, newPassword } = await request.json();

    if (!currentPassword || !newPassword) {
      return NextResponse.json(
        { success: false, error: "Both fields are required" },
        { status: 400 },
      );
    }

    if (newPassword.length < 6) {
      return NextResponse.json(
        { success: false, error: "New password must be at least 6 characters" },
        { status: 400 },
      );
    }

    // Get user with password field (select: false override)
    const user = await User.findById(adminId).select("+password");

    if (!user) {
      return NextResponse.json(
        { success: false, error: "User not found" },
        { status: 404 },
      );
    }

    // Verify current password
    const isMatch = await bcrypt.compare(currentPassword, user.password);

    if (!isMatch) {
      return NextResponse.json(
        { success: false, error: "Current password is incorrect" },
        { status: 400 },
      );
    }

    // Hash and save new password
    const hashedPassword = await bcrypt.hash(newPassword, 12);

    user.password = hashedPassword;
    await user.save();

    return NextResponse.json({
      success: true,
      message: "Password updated successfully",
    });
  } catch (error: any) {
    console.error("Error changing password:", error);
    return NextResponse.json(
      { success: false, error: error.message || "Failed to change password" },
      { status: 500 },
    );
  }
}
