import { NextResponse } from 'next/server';
import pool from '../../../../lib/db/db';
import type { ResultSetHeader } from 'mysql2';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';

// ---------- LOCAL generateS3Key FUNCTION ----------
function generateS3Key(folder: string, fileName: string): string {
  const timestamp = Date.now();
  const sanitizedFileName = fileName.replace(/\s+/g, '_');
  return `${folder}/${timestamp}_${sanitizedFileName}`;
}

// ---------- S3 CLIENT ----------
const s3 = new S3Client({
  region: process.env.AWS_DEFAULT_REGION,
credentials: {
  accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
forcePathStyle: process.env.AWS_USE_PATH_STYLE_ENDPOINT === 'true',
});

// ---------- GET: Fetch reviews with pagination and filters ----------
export async function GET(req: Request) {
  try {
    const { searchParams } = new URL(req.url);
    const page = parseInt(searchParams.get('page') || '1');
    const limit = parseInt(searchParams.get('limit') || '15');
    const search = searchParams.get('search') || '';
    const startDate = searchParams.get('startDate') || '';
    const endDate = searchParams.get('endDate') || '';

    const offset = (page - 1) * limit;
    let whereConditions = ` WHERE 1=1`;
    const params: any[] = [];

    if (search) {
      whereConditions += ` AND (review_name LIKE ? OR review LIKE ?)`;
      params.push(`%${search}%`, `%${search}%`);
    }

    if (startDate) {
      whereConditions += ` AND created_at >= ?`;
      params.push(startDate);
    }

    if (endDate) {
      whereConditions += ` AND created_at <= ?`;
      params.push(endDate + ' 23:59:59');
    }

    const countQuery = `SELECT COUNT(*) as total FROM tbl_review ${whereConditions}`;
    const [countResult]: any = await pool.query(countQuery, params);
    const totalItems = countResult[0].total;
    const totalPages = Math.ceil(totalItems / limit);

    const dataQuery = `
      SELECT * FROM tbl_review 
      ${whereConditions} 
      ORDER BY created_at DESC 
      LIMIT ? OFFSET ?
    `;
    const [rows]: any = await pool.query(dataQuery, [...params, limit, offset]);

    return NextResponse.json({
      success: true,
      data: rows,
      meta: {
        currentPage: page,
        itemsPerPage: limit,
        totalItems,
        totalPages,
      },
    });
  } catch (error: any) {
    console.error('Fetch error:', error);
    return NextResponse.json(
      { success: false, message: 'Failed to fetch reviews', error: error.message },
      { status: 500 }
    );
  }
}

// ---------- POST: Create new review with file upload ----------
export async function POST(req: Request) {
  try {
    const formData = await req.formData();
    const review_name = formData.get('review_name') as string;
    const review = formData.get('review') as string;
    const file = formData.get('profile_pic') as File | null;

    if (!review_name || !review) {
      return NextResponse.json(
        { success: false, message: 'Review name and review text are required' },
        { status: 400 }
      );
    }

    let profile_pic_url = null;

    if (file && file.size > 0) {
      try {
        const fileName = file.name || 'profile.jpg';
        const s3Key = generateS3Key('reviews', fileName);
        const buffer = Buffer.from(await file.arrayBuffer());
        const bucket = process.env.AWS_BUCKET!;

        await s3.send(
          new PutObjectCommand({
            Bucket: bucket,
            Key: s3Key,
            Body: buffer,
            ContentType: file.type || 'image/jpeg',
          })
        );

        profile_pic_url = `https://${bucket}.s3.${process.env.AWS_DEFAULT_REGION}.amazonaws.com/${s3Key}`;
      } catch (uploadError) {
        console.error('File upload error:', uploadError);
        return NextResponse.json(
          { success: false, message: 'Failed to upload profile picture' },
          { status: 500 }
        );
      }
    }

    const now = new Date();
    const [result] = await pool.query<ResultSetHeader>(
      `INSERT INTO tbl_review (review_name, review, profile_pic, created_at, updated_at) 
       VALUES (?, ?, ?, ?, ?)`,
      [review_name, review, profile_pic_url, now, now]
    );

    const [newReview] = await pool.query('SELECT * FROM tbl_review WHERE id = ?', [result.insertId]);

    return NextResponse.json({
      success: true,
      data: newReview[0],
      message: 'Review created successfully',
    });
  } catch (error: any) {
    console.error('Create error:', error);
    return NextResponse.json(
      { success: false, message: 'Failed to create review', error: error.message },
      { status: 500 }
    );
  }
}

// ---------- PUT: Update review ----------
export async function PUT(req: Request) {
  try {
    const formData = await req.formData();
    const id = formData.get('id') as string;
    const review_name = formData.get('review_name') as string;
    const review = formData.get('review') as string;
    const file = formData.get('profile_pic') as File | null;
    const removeImage = formData.get('removeImage') as string;

    if (!id) {
      return NextResponse.json({ success: false, message: 'Review ID is required' }, { status: 400 });
    }

    if (!review_name || !review) {
      return NextResponse.json(
        { success: false, message: 'Review name and review text are required' },
        { status: 400 }
      );
    }

    const [currentReview]: any = await pool.query('SELECT * FROM tbl_review WHERE id = ?', [id]);
    if (currentReview.length === 0) {
      return NextResponse.json({ success: false, message: 'Review not found' }, { status: 404 });
    }

    let profile_pic_url = currentReview[0].profile_pic;

    if (removeImage === 'true') {
      profile_pic_url = null;
    } else if (file && file.size > 0) {
      try {
        const fileName = file.name || 'profile.jpg';
        const s3Key = generateS3Key('reviews', fileName);
        const buffer = Buffer.from(await file.arrayBuffer());
        const bucket = process.env.AWS_BUCKET!;

        await s3.send(
          new PutObjectCommand({
            Bucket: bucket,
            Key: s3Key,
            Body: buffer,
            ContentType: file.type || 'image/jpeg',
          })
        );

        profile_pic_url = `https://${bucket}.s3.${process.env.AWS_DEFAULT_REGION}.amazonaws.com/${s3Key}`;
      } catch (uploadError) {
        console.error('File upload error:', uploadError);
        return NextResponse.json(
          { success: false, message: 'Failed to upload profile picture' },
          { status: 500 }
        );
      }
    }

    const now = new Date();
    const [result] = await pool.query<ResultSetHeader>(
      `UPDATE tbl_review 
       SET review_name = ?, review = ?, profile_pic = ?, updated_at = ? 
       WHERE id = ?`,
      [review_name, review, profile_pic_url, now, id]
    );

    if (result.affectedRows === 0) {
      return NextResponse.json({ success: false, message: 'Review not found' }, { status: 404 });
    }

    const [updatedReview] = await pool.query('SELECT * FROM tbl_review WHERE id = ?', [id]);
    return NextResponse.json({
      success: true,
      data: updatedReview[0],
      message: 'Review updated successfully',
    });
  } catch (error: any) {
    console.error('Update error:', error);
    return NextResponse.json(
      { success: false, message: 'Failed to update review', error: error.message },
      { status: 500 }
    );
  }
}

// ---------- DELETE: Remove review ----------
export async function DELETE(req: Request) {
  try {
    const { searchParams } = new URL(req.url);
    const id = searchParams.get('id');

    if (!id) {
      return NextResponse.json({ success: false, message: 'Review ID is required' }, { status: 400 });
    }

    const [result] = await pool.query<ResultSetHeader>('DELETE FROM tbl_review WHERE id = ?', [id]);

    if (result.affectedRows === 0) {
      return NextResponse.json({ success: false, message: 'Review not found' }, { status: 404 });
    }

    return NextResponse.json({ success: true, message: 'Review deleted successfully' });
  } catch (error: any) {
    console.error('Delete error:', error);
    return NextResponse.json(
      { success: false, message: 'Failed to delete review', error: error.message },
      { status: 500 }
    );
  }
}
