import { NextRequest, NextResponse } from 'next/server';
import { writeFile, mkdir, unlink, stat } from 'fs/promises';
import path from 'path';
import dbConnect from '../../src/lib/mongodb';
import StaticVideo from '../../src/models/StaticVideo';

const MAX_VIDEO_SIZE = 150 * 1024 * 1024; // 150MB
const ALLOWED_VIDEO_TYPES = ['video/mp4'];
const UPLOAD_DIR = path.join(process.cwd(), 'public', 'uploads', 'static-videos');

function getFileName(fileName: string) {
  const timestamp = Date.now();
  const random = Math.random().toString(36).substring(2, 10);
  const extension = path.extname(fileName) || '.mp4';
  return `${timestamp}-${random}${extension}`;
}

async function deleteLocalFile(fileUrl: string) {
  try {
    if (!fileUrl) return;
    const filename = fileUrl.split('/').pop();
    if (!filename) return;
    const fullPath = path.join(UPLOAD_DIR, filename);
    await stat(fullPath);
    await unlink(fullPath);
  } catch (error) {
    // file may not exist, ignore
  }
}

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 status = searchParams.get('status');
    const sort = searchParams.get('sort') || 'createdAt';
    const order = searchParams.get('order') || 'desc';

    const query: any = {};
    if (search) {
      query.$or = [
        { title: { $regex: search, $options: 'i' } },
        { subtitle: { $regex: search, $options: 'i' } }
      ];
    }

    if (status !== null && status !== undefined && status !== 'all') {
      query.status = status === 'true';
    }

    const skip = (page - 1) * limit;
    const sortOptions: any = {};
    if (sort === 'title') {
      sortOptions.title = order === 'asc' ? 1 : -1;
    } else if (sort === 'status') {
      sortOptions.status = order === 'asc' ? 1 : -1;
    } else {
      sortOptions.createdAt = order === 'asc' ? 1 : -1;
    }

    const data = await StaticVideo.find(query)
      .sort(sortOptions)
      .skip(skip)
      .limit(limit);

    const total = await StaticVideo.countDocuments(query);

    return NextResponse.json({
      success: true,
      data,
      pagination: {
        page,
        limit,
        total,
        pages: Math.ceil(total / limit)
      }
    });
  } catch (error: any) {
    console.error('Error fetching static videos:', error);
    return NextResponse.json({ success: false, error: error.message || 'Failed to fetch static videos' }, { status: 500 });
  }
}

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)?.trim();
    const subtitle = (formData.get('subtitle') as string)?.trim();
    const status = formData.get('status') === 'true';
    const videoFile = formData.get('video_file') as File | null;

    if (!title) {
      return NextResponse.json({ success: false, error: 'Title is required' }, { status: 400 });
    }

    if (!subtitle) {
      return NextResponse.json({ success: false, error: 'Subtitle is required' }, { status: 400 });
    }

    if (!videoFile) {
      return NextResponse.json({ success: false, error: 'Video file is required' }, { status: 400 });
    }

    if (!ALLOWED_VIDEO_TYPES.includes(videoFile.type)) {
      return NextResponse.json({ success: false, error: 'Invalid file type. Only MP4 is allowed.' }, { status: 400 });
    }

    if (videoFile.size > MAX_VIDEO_SIZE) {
      return NextResponse.json({ success: false, error: 'Video file too large. Maximum size is 150MB.' }, { status: 400 });
    }

    await mkdir(UPLOAD_DIR, { recursive: true });
    const filename = getFileName(videoFile.name);
    const filePath = path.join(UPLOAD_DIR, filename);
    const buffer = Buffer.from(await videoFile.arrayBuffer());
    await writeFile(filePath, buffer);

    const video_url = `/uploads/static-videos/${filename}`;

    const staticVideo = await StaticVideo.create({
      title,
      subtitle,
      video_url,
      status
    });

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

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: 'Static video 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 existing = await StaticVideo.findById(id);
    if (!existing) {
      return NextResponse.json({ success: false, error: 'Static video not found' }, { status: 404 });
    }

    const formData = await request.formData();
    const title = (formData.get('title') as string)?.trim();
    const subtitle = (formData.get('subtitle') as string)?.trim();
    const status = formData.get('status') === 'true';
    const videoFile = formData.get('video_file') as File | null;

    if (!title) {
      return NextResponse.json({ success: false, error: 'Title is required' }, { status: 400 });
    }

    if (!subtitle) {
      return NextResponse.json({ success: false, error: 'Subtitle is required' }, { status: 400 });
    }

    let video_url = existing.video_url;
    if (videoFile && videoFile.size > 0) {
      if (!ALLOWED_VIDEO_TYPES.includes(videoFile.type)) {
        return NextResponse.json({ success: false, error: 'Invalid file type. Only MP4 is allowed.' }, { status: 400 });
      }
      if (videoFile.size > MAX_VIDEO_SIZE) {
        return NextResponse.json({ success: false, error: 'Video file too large. Maximum size is 150MB.' }, { status: 400 });
      }

      await deleteLocalFile(existing.video_url);
      await mkdir(UPLOAD_DIR, { recursive: true });
      const filename = getFileName(videoFile.name);
      const filePath = path.join(UPLOAD_DIR, filename);
      const buffer = Buffer.from(await videoFile.arrayBuffer());
      await writeFile(filePath, buffer);
      video_url = `/uploads/static-videos/${filename}`;
    }

    const updated = await StaticVideo.findByIdAndUpdate(
      id,
      {
        title,
        subtitle,
        video_url,
        status
      },
      { new: true, runValidators: true }
    );

    return NextResponse.json({ success: true, data: updated, message: 'Static video updated successfully' });
  } catch (error: any) {
    console.error('Error updating static video:', error);
    return NextResponse.json({ success: false, error: error.message || 'Failed to update static video' }, { 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: 'Static video ID is required' }, { status: 400 });
    }

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

    await deleteLocalFile(existing.video_url);
    await StaticVideo.findByIdAndDelete(id);

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