// app/api/blogs/route.ts
import { NextRequest, NextResponse } from "next/server";
import dbConnect from "../../src/lib/mongodb";
import Blog from "../../src/models/Blog";

// External upload server configuration (same as banners)
const UPLOAD_SERVER_URL = "http://167.71.224.75:8700";
const UPLOAD_ENDPOINT = `${UPLOAD_SERVER_URL}/upload`;
const DELETE_ENDPOINT = `${UPLOAD_SERVER_URL}/delete`;

// ✅ Helper function to generate unique slug for blog
async function generateUniqueSlug(
  title: string,
  excludeId?: string,
): Promise<string> {
  let baseSlug = title
    .toLowerCase()
    .trim()
    .replace(/[^\w\s-]/g, "")
    .replace(/\s+/g, "-")
    .replace(/--+/g, "-");

  let slug = baseSlug;
  let counter = 1;

  while (true) {
    const existingBlog = await Blog.findOne({
      title: { $regex: new RegExp(`^${slug}$`, "i") },
      ...(excludeId && { _id: { $ne: excludeId } }),
    });

    if (!existingBlog) break;

    slug = `${baseSlug}-${counter}`;
    counter++;
  }

  return slug;
}
function makeSlug(text: string) {
  return text
    .toString()
    .toLowerCase()
    .trim()
    .replace(/[^\w\s-]/g, "")
    .replace(/\s+/g, "-")
    .replace(/--+/g, "-");
}

// Helper function to upload multiple images to external server
async function uploadMultipleToExternalServer(
  files: File[],
): Promise<string[]> {
  const uploadedUrls: string[] = [];

  for (const file of files) {
    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) {
        console.log("Image uploaded successfully:", result.url);
        const imageUrl = `https://quality-web-developer.com/dulhe_sahebimages/uploads/${result.filename}`;
        uploadedUrls.push(imageUrl);
      } else if (result.success && result.filename) {
        const imageUrl = `https://quality-web-developer.com/dulhe_sahebimages/uploads/${result.filename}`;
        uploadedUrls.push(imageUrl);
      } 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");
    }
  }

  return uploadedUrls;
}

// Helper function to upload single image to external server
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) {
      console.log("Image uploaded successfully:", result.url);
      const imageUrl = `https://quality-web-developer.com/dulhe_sahebimages/uploads/${result.filename}`;
      return imageUrl;
    } else if (result.success && result.filename) {
      const imageUrl = `https://quality-web-developer.com/dulhe_sahebimages/uploads/${result.filename}`;
      return imageUrl;
    } 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");
  }
}

// Helper function to delete image from 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("Image deleted successfully:", filename);
    }
  } catch (error) {
    console.error("Error deleting from external server:", error);
  }
}

// Helper function to delete multiple images
async function deleteMultipleFromExternalServer(
  imageUrls: string[],
): Promise<void> {
  for (const imageUrl of imageUrls) {
    await deleteFromExternalServer(imageUrl);
  }
}

// ✅ GET (Fetch blogs with pagination and sorting)
export async function GET(
  request: NextRequest,
  context?: { params: Promise<any> },
) {
  try {
    await dbConnect();

    const { searchParams } = new URL(request.url);
    const page = parseInt(searchParams.get("page") || "1");
    const limit = parseInt(searchParams.get("limit") || "10");
    const search = searchParams.get("search");
    const sort = searchParams.get("sort") || "createdAt";
    const order = searchParams.get("order") || "desc";

    // ✅ Build query safely
    let query: any = {};

    if (search) {
      query.$or = [
        { title: { $regex: search, $options: "i" } },
        { sub_title: { $regex: search, $options: "i" } },
        { short_description: { $regex: search, $options: "i" } },
      ];
    }

    const skip = (page - 1) * limit;

    // Create sort object
    const sortOptions: any = {};
    if (search) {
      sortOptions.title = 1;
    } else if (sort === "createdAt") {
      sortOptions.createdAt = order === "asc" ? 1 : -1;
    } else if (sort === "title") {
      sortOptions.title = order === "asc" ? 1 : -1;
    } else {
      sortOptions.createdAt = -1;
    }

    // ✅ FETCH BLOGS
    const blogs = await Blog.find(query)
      .sort(sortOptions)
      .skip(skip)
      .limit(limit);

    const total = await Blog.countDocuments(query);

    return NextResponse.json({
      success: true,
      data: blogs,
      pagination: {
        page,
        limit,
        total,
        pages: Math.ceil(total / limit),
      },
    });
  } catch (error: any) {
    console.error("Error fetching blogs:", error);

    return NextResponse.json(
      {
        success: false,
        error: error.message || "Failed to fetch blogs",
      },
      { status: 500 },
    );
  }
}

// ✅ POST (Create blog)
export async function POST(request: NextRequest) {
  try {
    await dbConnect();

    const contentType = request.headers.get("content-type") || "";

    if (!contentType.includes("multipart/form-data")) {
      return NextResponse.json(
        { success: false, error: "Content-Type must be multipart/form-data" },
        { status: 400 },
      );
    }

    const formData = await request.formData();
    const title = formData.get("title") as string;
    const sub_title = formData.get("sub_title") as string;
    const description = formData.get("description") as string;
    const short_description = formData.get("short_description") as string;
    const images = formData.getAll("images") as File[];

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

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

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

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

    if (short_description.length > 500) {
      return NextResponse.json(
        {
          success: false,
          error: "Short description must not exceed 500 characters",
        },
        { status: 400 },
      );
    }

    // Upload images to external server
    let imageUrls: string[] = [];
    if (images && images.length > 0) {
      // Validate each image
      const allowedTypes = [
        "image/jpeg",
        "image/jpg",
        "image/png",
        "image/webp",
        "image/gif",
      ];
      const maxSize = 5 * 1024 * 1024; // 5MB

      for (const image of images) {
        if (!allowedTypes.includes(image.type)) {
          return NextResponse.json(
            {
              success: false,
              error:
                "Invalid file type. Only JPEG, PNG, WebP, and GIF are allowed.",
            },
            { status: 400 },
          );
        }

        if (image.size > maxSize) {
          return NextResponse.json(
            { success: false, error: "File too large. Maximum size is 5MB." },
            { status: 400 },
          );
        }
      }

      try {
        imageUrls = await uploadMultipleToExternalServer(images);
      } catch (uploadError) {
        console.error("Upload error:", uploadError);
        return NextResponse.json(
          { success: false, error: "Failed to upload images to server" },
          { status: 500 },
        );
      }
    }
    const slug = makeSlug(title);
    // Create blog
    const blog = await Blog.create({
      title: title.trim(),
      sub_title: sub_title.trim(),
      slug: slug,
      description: description.trim(),
      short_description: short_description.trim(),
      images: imageUrls,
    });

    return NextResponse.json({
      success: true,
      data: blog,
      message: "Blog created successfully",
    });
  } catch (error: any) {
    console.error("Error creating blog:", error);

    return NextResponse.json(
      { success: false, error: error.message || "Failed to create blog" },
      { status: 500 },
    );
  }
}

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

    const url = new URL(request.url);
    const id = url.pathname.split("/").pop();

    if (!id) {
      return NextResponse.json(
        { success: false, error: "Blog ID is required" },
        { status: 400 },
      );
    }

    const contentType = request.headers.get("content-type") || "";

    if (!contentType.includes("multipart/form-data")) {
      return NextResponse.json(
        { success: false, error: "Content-Type must be multipart/form-data" },
        { status: 400 },
      );
    }

    const formData = await request.formData();
    const title = formData.get("title") as string;
    const sub_title = formData.get("sub_title") as string;
    const description = formData.get("description") as string;
    const short_description = formData.get("short_description") as string;
    const images = formData.getAll("images") as File[];
    const existingImages = formData.get("existingImages") as string; // JSON string of existing image URLs
    const removeImages = formData.get("removeImages") as string; // JSON string of images to remove

    // Check if blog exists
    const existingBlog = await Blog.findById(id);
    if (!existingBlog) {
      return NextResponse.json(
        { success: false, error: "Blog not found" },
        { status: 404 },
      );
    }

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

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

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

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

    if (short_description.length > 500) {
      return NextResponse.json(
        {
          success: false,
          error: "Short description must not exceed 500 characters",
        },
        { status: 400 },
      );
    }

    // Handle image updates
    let imageUrls: string[] = [];

    // Parse existing images if provided
    let currentImages = existingBlog.images;
    if (existingImages) {
      try {
        currentImages = JSON.parse(existingImages);
      } catch (e) {
        console.error("Error parsing existingImages:", e);
      }
    }

    // Remove specified images
    if (removeImages) {
      let imagesToRemove: string[] = [];
      try {
        imagesToRemove = JSON.parse(removeImages);
        // Delete from external server
        await deleteMultipleFromExternalServer(imagesToRemove);
        // Filter out removed images
        currentImages = currentImages.filter(
          (img: string) => !imagesToRemove.includes(img),
        );
      } catch (e) {
        console.error("Error parsing removeImages:", e);
      }
    }

    // Start with current images
    imageUrls = [...currentImages];

    // Upload new images
    if (images && images.length > 0) {
      const allowedTypes = [
        "image/jpeg",
        "image/jpg",
        "image/png",
        "image/webp",
        "image/gif",
      ];
      const maxSize = 5 * 1024 * 1024;

      for (const image of images) {
        if (!allowedTypes.includes(image.type)) {
          return NextResponse.json(
            {
              success: false,
              error:
                "Invalid file type. Only JPEG, PNG, WebP, and GIF are allowed.",
            },
            { status: 400 },
          );
        }

        if (image.size > maxSize) {
          return NextResponse.json(
            { success: false, error: "File too large. Maximum size is 5MB." },
            { status: 400 },
          );
        }
      }

      try {
        const newImageUrls = await uploadMultipleToExternalServer(images);
        imageUrls.push(...newImageUrls);
      } catch (uploadError) {
        console.error("Upload error:", uploadError);
        return NextResponse.json(
          { success: false, error: "Failed to upload images to server" },
          { status: 500 },
        );
      }
    }
    const slug = makeSlug(title);
    // Update blog
    const updatedBlog = await Blog.findByIdAndUpdate(
      id,
      {
        title: title.trim(),
        sub_title: sub_title.trim(),
        description: description.trim(),
        slug: slug,
        short_description: short_description.trim(),
        images: imageUrls,
      },
      { new: true, runValidators: true },
    );

    return NextResponse.json({
      success: true,
      data: updatedBlog,
      message: "Blog updated successfully",
    });
  } catch (error: any) {
    console.error("Error updating blog:", error);

    return NextResponse.json(
      { success: false, error: error.message || "Failed to update blog" },
      { status: 500 },
    );
  }
}

// ✅ DELETE (Delete blog)
export async function DELETE(
  request: NextRequest,
  context?: { params: Promise<any> },
) {
  try {
    await dbConnect();

    const url = new URL(request.url);
    const id = url.pathname.split("/").pop();

    if (!id) {
      return NextResponse.json(
        { success: false, error: "Blog ID is required" },
        { status: 400 },
      );
    }

    // Check if blog exists
    const blog = await Blog.findById(id);
    if (!blog) {
      return NextResponse.json(
        { success: false, error: "Blog not found" },
        { status: 404 },
      );
    }

    // Delete all images from external server
    if (blog.images && blog.images.length > 0) {
      await deleteMultipleFromExternalServer(blog.images);
    }

    await Blog.findByIdAndDelete(id);

    return NextResponse.json({
      success: true,
      message: "Blog deleted successfully",
    });
  } catch (error: any) {
    console.error("Error deleting blog:", error);
    return NextResponse.json(
      { success: false, error: error.message || "Failed to delete blog" },
      { status: 500 },
    );
  }
}

// ✅ GET single blog by ID (optional - separate endpoint)
export async function getBlogById(id: string) {
  try {
    await dbConnect();
    const blog = await Blog.findById(id);

    if (!blog) {
      return null;
    }

    return blog;
  } catch (error) {
    console.error("Error fetching blog by ID:", error);
    return null;
  }
}
