<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Notification;
use App\Models\User;
use App\Models\Country;
use App\Models\Language;
use App\Models\CountryStore;
use App\Models\Brand;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class NotificationController extends Controller
{
    /**
     * Display a listing of notifications
     */
    public function index(Request $request)
    {
        $query = Notification::with(['deliveries', 'targets']);

        // Search functionality
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('title', 'like', "%{$search}%")
                    ->orWhere('message', 'like', "%{$search}%")
                    ->orWhere('type', 'like', "%{$search}%");
            });
        }

        // Filter by status
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        // Filter by type
        if ($request->filled('type')) {
            $query->where('type', $request->type);
        }

        // Filter by priority
        if ($request->filled('priority')) {
            $query->where('priority', '>=', $request->priority);
        }

        // Get paginated results
        $notifications = $query->latest()->paginate(15)->withQueryString();

        // Get filter options
        $types = ['system', 'promotional', 'offer', 'store', 'brand', 'user'];
        $statuses = ['pending', 'sent', 'failed'];
        $priorities = [1, 5, 8, 10];

        return view('admin.notifications.index', compact(
            'notifications', 
            'types', 
            'statuses', 
            'priorities'
        ));
    }

    /**
     * Show the form for creating a new notification
     */
    public function create()
    {
        $countries = \App\Models\Country::active()->ordered()->get();
        $languages = \App\Models\Language::active()->ordered()->get();
        $stores = \App\Models\CountryStore::with(['store', 'country'])
            ->active()
            ->take(50)
            ->get();
        $brands = \App\Models\Brand::active()->ordered()->take(50)->get();

        return view('admin.notifications.create', compact(
            'countries',
            'languages', 
            'stores',
            'brands'
        ));
    }

    /**
     * Store a newly created notification
     */
    public function store(Request $request)
    {
        $request->validate([
            'type' => 'required|in:system,promotional,offer,store,brand,user',
            'title' => 'required|string|max:255',
            'message' => 'required|string',
            'channels' => 'required|array',
            'channels.*' => 'in:database,push,email',
            'priority' => 'required|integer|min:0|max:10',
            'targets' => 'required|array',
            'targets.*' => 'required|array',
            'targets.*.type' => 'required|in:all,country,language,role,user,store_followers,brand_followers',
            'data' => 'nullable|array',
        ]);

        DB::beginTransaction();
        try {
            // Create notification
            $notification = Notification::create([
                'type' => $request->type,
                'title' => $request->title,
                'message' => $request->message,
                'data' => $request->data ?? [],
                'channels' => $request->channels,
                'priority' => $request->priority,
                'status' => 'pending',
            ]);

            // Add targets
            foreach ($request->targets as $target) {
                $notification->targets()->create([
                    'target_type' => $target['type'],
                    'target_id' => $target['id'] ?? null,
                ]);
            }

            // Queue notification for sending
            $this->queueNotification($notification);

            DB::commit();
            flash_success(admin_trans('notification_created_successfully'));
            return redirect()->route('admin.notifications.index');

        } catch (\Exception $e) {
            DB::rollBack();
            \Log::error('Notification creation failed: ' . $e->getMessage());
            flash_error(admin_trans('error_creating_notification'));
            return back()->withInput();
        }
    }

    /**
     * Display the specified notification
     */
    public function show(Notification $notification)
    {
        $notification->load([
            'deliveries.user',
            'targets'
        ]);

        // Get delivery statistics
        $stats = [
            'total_targets' => $this->getTotalTargets($notification),
            'delivered' => $notification->deliveries()->where('status', 'sent')->count(),
            'read' => $notification->deliveries()->where('status', 'read')->count(),
            'failed' => $notification->deliveries()->where('status', 'failed')->count(),
        ];

        $stats['pending'] = $stats['total_targets'] - $stats['delivered'] - $stats['failed'];
        $stats['delivery_rate'] = $stats['total_targets'] > 0 
            ? round(($stats['delivered'] / $stats['total_targets']) * 100, 2) 
            : 0;
        $stats['read_rate'] = $stats['delivered'] > 0 
            ? round(($stats['read'] / $stats['delivered']) * 100, 2) 
            : 0;

        return view('admin.notifications.show', compact('notification', 'stats'));
    }

    /**
     * Remove the specified notification
     */
    public function destroy(Notification $notification)
    {
        try {
            // Delete related deliveries and targets
            $notification->deliveries()->delete();
            $notification->targets()->delete();
            $notification->delete();

            flash_success(admin_trans('notification_deleted_successfully'));
        } catch (\Exception $e) {
            flash_error(admin_trans('error_deleting_notification'));
        }

        return redirect()->route('admin.notifications.index');
    }

    /**
     * Resend failed notification
     */
    public function resend(Notification $notification)
    {
        try {
            if ($notification->status === 'failed') {
                $notification->update(['status' => 'pending']);
                $this->queueNotification($notification);
                
                flash_success(admin_trans('notification_queued_for_resend'));
            } else {
                flash_warning(admin_trans('notification_cannot_be_resent'));
            }
        } catch (\Exception $e) {
            flash_error(admin_trans('error_resending_notification'));
        }

        return back();
    }

    /**
     * Bulk actions for notifications
     */
    public function bulkAction(Request $request)
    {
        $request->validate([
            'action' => 'required|in:delete,resend',
            'selected' => 'required|array',
            'selected.*' => 'exists:notifications,id',
        ]);

        $notifications = Notification::whereIn('id', $request->selected);
        $count = count($request->selected);

        try {
            switch ($request->action) {
                case 'delete':
                    // Delete related data first
                    foreach ($notifications->get() as $notification) {
                        $notification->deliveries()->delete();
                        $notification->targets()->delete();
                    }
                    $notifications->delete();
                    break;

                case 'resend':
                    $notifications->where('status', 'failed')
                        ->update(['status' => 'pending']);
                    
                    foreach ($notifications->where('status', 'pending')->get() as $notification) {
                        $this->queueNotification($notification);
                    }
                    break;
            }

            return response()->json([
                'success' => true,
                'message' => "$count " . admin_trans('notifications') . " {$request->action}d " . admin_trans('successfully')
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => admin_trans('error_bulk_action')
            ]);
        }
    }

    /**
     * Get notification statistics
     */
    public function stats()
    {
        try {
            $stats = [
                'total' => Notification::count(),
                'pending' => Notification::where('status', 'pending')->count(),
                'sent' => Notification::where('status', 'sent')->count(),
                'failed' => Notification::where('status', 'failed')->count(),
                'today' => Notification::whereDate('created_at', today())->count(),
                'this_week' => Notification::whereBetween('created_at', [
                    now()->startOfWeek(),
                    now()->endOfWeek()
                ])->count(),
                'this_month' => Notification::whereMonth('created_at', now()->month)->count(),
            ];

            return response()->json(['success' => true, 'stats' => $stats]);
        } catch (\Exception $e) {
            \Log::error('Error loading notification stats: ' . $e->getMessage());
            return response()->json(['success' => false, 'stats' => []], 500);
        }
    }

    /**
     * Get delivery report
     */
    public function deliveryReport(Notification $notification)
    {
        $deliveries = $notification->deliveries()
            ->with(['user'])
            ->paginate(50);

        return view('admin.notifications.delivery-report', compact('notification', 'deliveries'));
    }

    /**
     * Private helper methods
     */
    private function queueNotification(Notification $notification)
    {
        // Dispatch the job to send the notification
        \App\Jobs\SendNotificationJob::dispatch($notification);
        
        \Log::info('Notification queued for sending', [
            'notification_id' => $notification->id,
            'type' => $notification->type,
            'channels' => $notification->channels,
        ]);
    }

    private function getTotalTargets(Notification $notification)
    {
        $totalTargets = 0;

        foreach ($notification->targets as $target) {
            $users = $target->getTargetUsers();
            $totalTargets += $users->count();
        }

        return $totalTargets;
    }
}