import { NextRequest, NextResponse } from 'next/server';
import dbConnect from '../../src/lib/mongodb';
import Category from '../../src/models/Category';
import Product from '../../src/models/Product';
import path from 'path';
import fs from 'fs/promises';

// External upload server configuration
const UPLOAD_SERVER_URL = 'http://167.71.224.75:8700';
const UPLOAD_ENDPOINT = `${UPLOAD_SERVER_URL}/upload`;
const DELETE_ENDPOINT = `${UPLOAD_SERVER_URL}/delete`;

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

// Helper function to upload 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) {
      // Construct URL if only filename is returned
      const imageUrl = `https://quality-web-developer.com/dulhe_sahebimages/${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 {
    // Extract filename from URL
    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);
  }
}
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 parent = searchParams.get('parent');
    const level = searchParams.get('level');
    const isActive = searchParams.get('isActive');
    const isEvent = searchParams.get('isEvent');
    const searchParam = searchParams.get('search');
    const sort = searchParams.get('sort') || 'name';
    const order = searchParams.get('order') || 'asc';

    let query: any = {};

    if (parent === 'null' || parent === '') {
      query.parent = null;
    } else if (parent) {
      query.parent = parent;
    }

    if (level) {
      query.level = parseInt(level);
    }

    if (isActive !== null) {
      query.isActive = isActive === 'true';
    }

    if (isEvent !== null) {
      query.isevent = isEvent === 'true';
    }

    if (searchParam) {
      query.$or = [
        { name: { $regex: searchParam, $options: 'i' } },
        { slug: { $regex: searchParam, $options: 'i' } },
        { categories: { $regex: searchParam, $options: 'i' } },
        { description: { $regex: searchParam, $options: 'i' } }
      ];
    }

    const skip = (page - 1) * limit;

    // Create sort object - support sorting by name or createdAt
    const sortOptions: any = {};
    if (searchParam) {
      // Always sort alphabetically when searching
      sortOptions.name = 1;
    }
    else if (sort === 'createdAt') {
      sortOptions.createdAt = order === 'asc' ? 1 : -1;
    } else {
      sortOptions.name = order === 'asc' ? 1 : -1;
    }

    const categories = await Category.find(query)
      .populate('parent', 'name slug')
      .sort(sortOptions)
      .skip(skip)
      .limit(limit);

    const total = await Category.countDocuments(query);

    return NextResponse.json({
      success: true,
      data: categories,
      pagination: {
        page,
        limit,
        total,
        pages: Math.ceil(total / limit)
      }
    });

  } catch (error: any) {
    console.error('Error fetching categories:', error);
    return NextResponse.json(
      { success: false, error: error.message },
      { status: 500 }
    );
  }
}

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

    const formData = await request.formData();

    const name = formData.get("name") as string;
    const description = formData.get("description") as string;
    const parent = formData.get("parent") as string;
    const isActive = formData.get("isActive") === "true";
    const isEvent = formData.get("isEvent") === "true";
    const file = formData.get("image") as File;

    let imageUrl = "";

    if (file && file.size > 0) {
      // Upload to external server
      imageUrl = await uploadToExternalServer(file);
    }

    const slug = makeSlug(name);

    // Check duplicate name or slug
    const existing = await Category.findOne({
      $or: [
        { name: { $regex: `^${name}$`, $options: 'i' } }, // case insensitive name match
        { slug }
      ]
    });

    if (existing) {
      return NextResponse.json(
        { success: false, error: `${parent ? 'Subcategory' : 'Category'} with this name already exists` },
        { status: 400 }
      );
    }

    const category = await Category.create({
      name,
      description,
      slug,
      parent: parent || null,
      isActive,
      isevent: isEvent,
      image: imageUrl,
    });

    return NextResponse.json({ success: true, data: category });
  } catch (error: any) {
    console.error('Error creating category:', error);
    return NextResponse.json(
      { success: false, error: error.message || 'Failed to create category' },
      { status: 500 }
    );
  }
}

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

    const pathname = request.nextUrl.pathname;
    const id = pathname.split('/').pop();
    
    if (!id) {
      return NextResponse.json(
        { success: false, error: 'Category ID is required' },
        { status: 400 }
      );
    }

    const formData = await request.formData();

    const name = formData.get("name") as string;
    const description = formData.get("description") as string;
    const parent = formData.get("parent") as string;
    const isActive = formData.get("isActive") === "true";
    const isEvent = formData.get("isEvent") === "true";
    const file = formData.get("image") as File;
    
    // Check if category exists
    const existing = await Category.findById(id);
    if (!existing) {
      return NextResponse.json(
        { success: false, error: 'Category not found' },
        { status: 404 }
      );
    }

    let imageUrl = existing.image;

    // Handle new image upload
    if (file && file.size > 0) {
      // Delete old image from external server if exists
      if (existing.image && existing.image.includes('quality-web-developer.com/dulhe_sahebimages')) {
        await deleteFromExternalServer(existing.image);
      }
      
      // Upload new image to external server
      imageUrl = await uploadToExternalServer(file);
    }

    const slug = makeSlug(name);

    // Check duplicate name or slug — exclude current document
    const _existing = await Category.findOne({
      $or: [
        { name: { $regex: `^${name}$`, $options: 'i' } },
        { slug }
      ],
      _id: { $ne: id } // exclude current category
    });

    if (_existing) {
      return NextResponse.json(
        { success: false, error: 'Category with this name already exists' },
        { status: 400 }
      );
    }
    
    const updated = await Category.findByIdAndUpdate(
      id,
      {
        name,
        description,
        slug,
        parent: parent || null,
        image: imageUrl || null,
        isActive,
        isevent: isEvent,
      },
      { new: true, runValidators: true }
    ).populate('parent', 'name slug');

    return NextResponse.json({ success: true, data: updated });

  } catch (error: any) {
    console.error('Error updating category:', error);
    return NextResponse.json(
      { success: false, error: error.message || 'Failed to update category' },
      { status: 500 }
    );
  }
}

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: 'Category ID is required' },
        { status: 400 }
      );
    }

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

    // Check if category has subcategories
    const hasSubcategories = await Category.findOne({ parent: id });
    if (hasSubcategories) {
      return NextResponse.json(
        { success: false, error: 'Cannot delete category with subcategories. Please delete or reassign subcategories first.' },
        { status: 400 }
      );
    }

    const isUsedInProduct = await Product.exists({
      $or: [
        { category: id },
        { subcategory: id }
      ]
    });
    if (isUsedInProduct) {
      return NextResponse.json(
        { success: false, error: 'Cannot delete category because it is used by one or more products' },
        { status: 400 }
      );
    }

    // Delete image from external server if exists
    if (category.image && category.image.includes('quality-web-developer.com/dulhe_sahebimages')) {
      await deleteFromExternalServer(category.image);
    }

    await Category.findByIdAndDelete(id);

    return NextResponse.json({
      success: true,
      message: 'Category deleted successfully'
    });

  } catch (error: any) {
    console.error('Error deleting category:', error);
    return NextResponse.json(
      { success: false, error: error.message },
      { status: 500 }
    );
  }
}