<?php

namespace App\Http\Controllers;

use App\Models\WinningTicket;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;

class WinningTicketController extends Controller
{
    /**
     * Get all approved winning tickets (public gallery)
     */
    public function index(Request $request)
    {
        $limit = $request->query('limit', 20);
        $page = $request->query('page', 1);

        $tickets = WinningTicket::with('user:id,name')
            ->approved()
            ->orderBy('created_at', 'desc')
            ->paginate($limit, ['*'], 'page', $page);

        return response()->json([
            'tickets' => $tickets->items(),
            'pagination' => [
                'page' => $tickets->currentPage(),
                'limit' => $tickets->perPage(),
                'total' => $tickets->total(),
                'pages' => $tickets->lastPage()
            ]
        ]);
    }

    /**
     * Get current user's winning tickets
     */
    public function myTickets(Request $request)
    {
        $user = Auth::user();
        $limit = $request->query('limit', 20);

        $tickets = WinningTicket::where('user_id', $user->id)
            ->orderBy('created_at', 'desc')
            ->paginate($limit);

        return response()->json([
            'tickets' => $tickets->items(),
            'pagination' => [
                'page' => $tickets->currentPage(),
                'limit' => $tickets->perPage(),
                'total' => $tickets->total(),
                'pages' => $tickets->lastPage()
            ]
        ]);
    }

    /**
     * Upload winning ticket(s) - supports single (image) or multiple (images[]) uploads
     */
    public function store(Request $request)
    {
        // Log upload attempt
        Log::info('Winning ticket upload attempt', [
            'has_single' => $request->hasFile('image'),
            'has_multiple' => $request->hasFile('images'),
            'content_type' => $request->header('Content-Type'),
            'all_files' => array_keys($request->allFiles()),
            'php_upload_max' => ini_get('upload_max_filesize'),
            'php_post_max' => ini_get('post_max_size'),
        ]);

        try {
            // Determine if single or multiple upload
            $hasMultiple = $request->hasFile('images');
            $hasSingle = $request->hasFile('image');

            // Check if file key exists but hasFile returns false
            $allFiles = array_keys($request->allFiles());
            if (!$hasMultiple && !$hasSingle) {
                // Try to get the file directly to check error
                $rawFile = $request->file('image');
                $errorCode = $rawFile ? $rawFile->getError() : null;
                
                Log::error('File detection failed', [
                    'all_files' => $allFiles,
                    'raw_file_exists' => $rawFile ? true : false,
                    'error_code' => $errorCode,
                    'upload_max_filesize' => ini_get('upload_max_filesize'),
                    'post_max_size' => ini_get('post_max_size'),
                ]);

                // If file exists but has error, provide specific message
                if ($rawFile && $errorCode !== UPLOAD_ERR_OK) {
                    $errorMessages = [
                        UPLOAD_ERR_INI_SIZE => 'File exceeds server upload limit (' . ini_get('upload_max_filesize') . ')',
                        UPLOAD_ERR_FORM_SIZE => 'File exceeds form limit',
                        UPLOAD_ERR_PARTIAL => 'File was only partially uploaded',
                        UPLOAD_ERR_NO_FILE => 'No file was uploaded',
                        UPLOAD_ERR_NO_TMP_DIR => 'Missing temp folder on server',
                        UPLOAD_ERR_CANT_WRITE => 'Failed to write to disk',
                        UPLOAD_ERR_EXTENSION => 'Upload blocked by PHP extension',
                    ];
                    $errorMsg = $errorMessages[$errorCode] ?? "Unknown upload error (code: {$errorCode})";
                    return response()->json(['error' => $errorMsg], 400);
                }

                if (in_array('image', $allFiles) || in_array('images', $allFiles)) {
                    return response()->json([
                        'error' => "File upload failed. Your file may exceed the server limit. Please use a smaller image.",
                    ], 400);
                }
                return response()->json(['error' => 'No image file(s) received. Use "image" for single or "images[]" for multiple.'], 400);
            }

            // Validate based on upload type
            if ($hasMultiple) {
                $request->validate([
                    'images' => 'required|array|max:10',
                    'images.*' => 'image|mimes:jpeg,png,jpg,gif,webp|max:5120',
                    'title' => 'nullable|string|max:255',
                    'description' => 'nullable|string|max:1000',
                    'amount_won' => 'nullable|numeric|min:0',
                ]);
                $images = $request->file('images');
            } else {
                $request->validate([
                    'image' => 'required|image|mimes:jpeg,png,jpg,gif,webp|max:5120',
                    'title' => 'nullable|string|max:255',
                    'description' => 'nullable|string|max:1000',
                    'amount_won' => 'nullable|numeric|min:0',
                ]);
                $images = [$request->file('image')];
            }

            $user = Auth::user();
            $uploadPath = public_path('uploads/winning-tickets');
            
            // Create directory if it doesn't exist
            if (!file_exists($uploadPath)) {
                mkdir($uploadPath, 0755, true);
            }

            // Check if directory is writable
            if (!is_writable($uploadPath)) {
                Log::error('Upload directory not writable', ['path' => $uploadPath]);
                return response()->json(['error' => 'Upload directory not writable'], 500);
            }

            // Auto-approve if user is admin
            $isAdmin = $user->role === 'admin';
            $status = $isAdmin ? 'approved' : 'pending';

            $createdTickets = [];
            $errors = [];

            foreach ($images as $index => $image) {
                if (!$image || !$image->isValid()) {
                    $errors[] = "Image " . ($index + 1) . " failed to upload";
                    continue;
                }

                $fileName = uniqid('ticket_') . '_' . $user->id . '_' . $index . '.' . $image->getClientOriginalExtension();
                
                try {
                    $image->move($uploadPath, $fileName);
                    $fileUrl = url('uploads/winning-tickets/' . $fileName);

                    $ticket = WinningTicket::create([
                        'user_id' => $user->id,
                        'image_path' => $fileUrl,
                        'title' => $request->title,
                        'description' => $request->description,
                        'amount_won' => $request->amount_won,
                        'status' => $status,
                        'reviewed_at' => $isAdmin ? now() : null
                    ]);

                    $createdTickets[] = $ticket;
                    Log::info('File uploaded successfully', ['url' => $fileUrl]);
                } catch (\Exception $e) {
                    $errors[] = "Image " . ($index + 1) . ": " . $e->getMessage();
                }
            }

            if (empty($createdTickets)) {
                return response()->json(['error' => 'All uploads failed', 'details' => $errors], 400);
            }

            $message = $isAdmin 
                ? count($createdTickets) . ' winning ticket(s) uploaded and approved.' 
                : count($createdTickets) . ' winning ticket(s) uploaded successfully. Awaiting admin approval.';

            return response()->json([
                'success' => true,
                'tickets' => $createdTickets,
                'errors' => $errors,
                'message' => $message
            ], 201);

        } catch (\Exception $e) {
            Log::error('Error uploading winning ticket: ' . $e->getMessage());
            return response()->json(['error' => 'Failed to upload winning ticket: ' . $e->getMessage()], 500);
        }
    }

    /**
     * Delete user's own ticket (only if pending)
     */
    public function destroyOwn($id)
    {
        try {
            $user = Auth::user();
            $ticket = WinningTicket::where('id', $id)
                ->where('user_id', $user->id)
                ->first();

            if (!$ticket) {
                return response()->json(['error' => 'Ticket not found'], 404);
            }

            // Only allow deletion of pending tickets
            if ($ticket->status !== 'pending') {
                return response()->json(['error' => 'Cannot delete ticket that has been reviewed'], 403);
            }

            // Delete the image file
            $this->deleteImageFile($ticket->image_path);

            $ticket->delete();

            return response()->json([
                'success' => true,
                'message' => 'Ticket deleted successfully'
            ]);

        } catch (\Exception $e) {
            Log::error('Error deleting winning ticket: ' . $e->getMessage());
            return response()->json(['error' => 'Failed to delete ticket'], 500);
        }
    }

    // ============ ADMIN METHODS ============

    /**
     * Get all tickets for admin (with filters)
     */
    public function adminIndex(Request $request)
    {
        $status = $request->query('status', 'all');
        $limit = $request->query('limit', 20);
        $page = $request->query('page', 1);

        $query = WinningTicket::with('user:id,name,email');

        if ($status !== 'all') {
            $query->where('status', $status);
        }

        $tickets = $query->orderBy('created_at', 'desc')
            ->paginate($limit, ['*'], 'page', $page);

        return response()->json([
            'tickets' => $tickets->items(),
            'pagination' => [
                'page' => $tickets->currentPage(),
                'limit' => $tickets->perPage(),
                'total' => $tickets->total(),
                'pages' => $tickets->lastPage()
            ]
        ]);
    }

    /**
     * Get pending tickets count for admin dashboard
     */
    public function pendingCount()
    {
        $count = WinningTicket::pending()->count();
        return response()->json(['pending_count' => $count]);
    }

    /**
     * Approve a winning ticket
     */
    public function approve(Request $request, $id)
    {
        try {
            $ticket = WinningTicket::find($id);

            if (!$ticket) {
                return response()->json(['error' => 'Ticket not found'], 404);
            }

            $ticket->update([
                'status' => 'approved',
                'admin_notes' => $request->admin_notes ?? null,
                'reviewed_at' => now()
            ]);

            return response()->json([
                'success' => true,
                'ticket' => $ticket->fresh()->load('user:id,name'),
                'message' => 'Ticket approved successfully'
            ]);

        } catch (\Exception $e) {
            Log::error('Error approving winning ticket: ' . $e->getMessage());
            return response()->json(['error' => 'Failed to approve ticket'], 500);
        }
    }

    /**
     * Reject a winning ticket
     */
    public function reject(Request $request, $id)
    {
        try {
            $request->validate([
                'admin_notes' => 'nullable|string|max:1000'
            ]);

            $ticket = WinningTicket::find($id);

            if (!$ticket) {
                return response()->json(['error' => 'Ticket not found'], 404);
            }

            $ticket->update([
                'status' => 'rejected',
                'admin_notes' => $request->admin_notes ?? 'Rejected by admin',
                'reviewed_at' => now()
            ]);

            return response()->json([
                'success' => true,
                'ticket' => $ticket->fresh()->load('user:id,name'),
                'message' => 'Ticket rejected successfully'
            ]);

        } catch (\Exception $e) {
            Log::error('Error rejecting winning ticket: ' . $e->getMessage());
            return response()->json(['error' => 'Failed to reject ticket'], 500);
        }
    }

    /**
     * Admin delete any ticket
     */
    public function adminDestroy($id)
    {
        try {
            $ticket = WinningTicket::find($id);

            if (!$ticket) {
                return response()->json(['error' => 'Ticket not found'], 404);
            }

            // Delete the image file
            $this->deleteImageFile($ticket->image_path);

            $ticket->delete();

            return response()->json([
                'success' => true,
                'message' => 'Ticket deleted successfully'
            ]);

        } catch (\Exception $e) {
            Log::error('Error deleting winning ticket: ' . $e->getMessage());
            return response()->json(['error' => 'Failed to delete ticket'], 500);
        }
    }

    /**
     * Get tickets by specific user (admin)
     */
    public function getByUser($userId)
    {
        $tickets = WinningTicket::where('user_id', $userId)
            ->with('user:id,name,email')
            ->orderBy('created_at', 'desc')
            ->get();

        return response()->json($tickets);
    }

    /**
     * Helper method to delete image file
     */
    private function deleteImageFile($imageUrl)
    {
        try {
            // Extract filename from URL
            $path = parse_url($imageUrl, PHP_URL_PATH);
            $fullPath = public_path($path);
            
            if (file_exists($fullPath)) {
                unlink($fullPath);
            }
        } catch (\Exception $e) {
            Log::warning('Could not delete image file: ' . $e->getMessage());
        }
    }
}
