import { NextRequest, NextResponse } from 'next/server';
import dbConnect from '../../src/lib/mongodb';
import EmailTemplate from '../../src/models/EmailTemplate';

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

// GET
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') || 'asc';

    let query: any = {};

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

    const skip     = (page - 1) * limit;
    const sortObj: any = search
      ? { name: 1 }
      : { [sort]: order === 'asc' ? 1 : -1 };

    const templates = await EmailTemplate.find(query)
      .sort(sortObj)
      .skip(skip)
      .limit(limit);

    const total = await EmailTemplate.countDocuments(query);

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

  } catch (error: any) {
    return NextResponse.json(
      { success: false, error: error.message || 'Failed to fetch templates' },
      { status: 500 }
    );
  }
}

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

    const body = await request.json();
    const { name, subject, content, description, fromName, fromEmail, ccEmail } = body;

    if (!name?.trim()) return NextResponse.json({ success: false, error: 'Name is required' },       { status: 400 });
    if (!subject?.trim()) return NextResponse.json({ success: false, error: 'Subject is required' },    { status: 400 });
    if (!content?.trim()) return NextResponse.json({ success: false, error: 'Content is required' },    { status: 400 });
    if (!fromName?.trim()) return NextResponse.json({ success: false, error: 'From name is required' },  { status: 400 });
    if (!fromEmail?.trim()) return NextResponse.json({ success: false, error: 'From email is required' }, { status: 400 });

    const slug = makeSlug(name);

    // Check duplicate slug
    const existing = await EmailTemplate.findOne({ slug });
    if (existing) {
      return NextResponse.json(
        { success: false, error: 'Template with this name already exists' },
        { status: 400 }
      );
    }

    const template = await EmailTemplate.create({
      name: name.trim(),
      slug,
      subject: subject.trim(),
      content: content.trim(),
      description: description?.trim() || '',
      fromName: fromName.trim(),
      fromEmail: fromEmail.trim().toLowerCase(),
      ccEmail: ccEmail?.trim().toLowerCase() || '',
    });

    return NextResponse.json({ success: true, data: template }, { status: 201 });

  } catch (error: any) {
    if (error.code === 11000) {
      return NextResponse.json(
        { success: false, error: 'Template with this name already exists' },
        { status: 400 }
      );
    }
    return NextResponse.json(
      { success: false, error: error.message || 'Failed to create template' },
      { status: 500 }
    );
  }
}

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

    const existing = await EmailTemplate.findById(id);
    if (!existing) return NextResponse.json({ success: false, error: 'Template not found' }, { status: 404 });

    const body = await request.json();
    const { name, subject, content, description, fromName, fromEmail, ccEmail } = body;

    if (!name?.trim()) return NextResponse.json({ success: false, error: 'Name is required' },       { status: 400 });
    if (!subject?.trim()) return NextResponse.json({ success: false, error: 'Subject is required' },    { status: 400 });
    if (!content?.trim()) return NextResponse.json({ success: false, error: 'Content is required' },    { status: 400 });
    if (!fromName?.trim()) return NextResponse.json({ success: false, error: 'From name is required' },  { status: 400 });
    if (!fromEmail?.trim()) return NextResponse.json({ success: false, error: 'From email is required' }, { status: 400 });

    const slug = makeSlug(name);

    // Check slug not taken by another template
    const slugExists = await EmailTemplate.findOne({ slug, _id: { $ne: id } });
    if (slugExists) {
      return NextResponse.json(
        { success: false, error: 'Template with this name already exists' },
        { status: 400 }
      );
    }

    const updated = await EmailTemplate.findByIdAndUpdate(
      id,
      {
        $set: {
          name: name.trim(),
          slug,
          subject: subject.trim(),
          content: content.trim(),
          description: description?.trim() || '',
          fromName: fromName.trim(),
          fromEmail: fromEmail.trim().toLowerCase(),
          ccEmail: ccEmail?.trim().toLowerCase() || '',
        },
      },
      { new: true, runValidators: true }
    );

    return NextResponse.json({ success: true, data: updated, message: 'Template updated successfully' });

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

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

    const template = await EmailTemplate.findById(id);
    if (!template) {
      return NextResponse.json(
        { success: false, error: 'Template not found' },
        { status: 404 }
      );
    }

    await EmailTemplate.findByIdAndDelete(id);

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

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