<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Mail\NewsletterMail;
use App\Models\Newsletter;
use App\Models\NewsletterSubscriber;
use App\Models\Setting;
use App\Services\MailService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;

class NewsletterController extends Controller
{
    public function __construct(
        protected MailService $mailService
    ) {}

    public function index(Request $request)
    {
        $query = NewsletterSubscriber::query()->where('is_active', true);
        if ($request->filled('search')) {
            $q = $request->search;
            $query->where(function ($qry) use ($q) {
                $qry->where('email', 'like', "%{$q}%")
                    ->orWhere('name', 'like', "%{$q}%");
            });
        }
        $subscribers = $query->orderBy('subscribed_at', 'desc')->paginate(30);

        return view('admin.newsletter.index', compact('subscribers'));
    }

    public function settings()
    {
        $settings = array_merge([
            'newsletter_popup_enabled' => '1',
            'newsletter_popup_mode' => 'auto',
            'newsletter_popup_title' => 'Restez informé',
            'newsletter_popup_content' => 'Inscrivez-vous à notre newsletter pour recevoir nos actualités et offres exclusives.',
            'newsletter_popup_image' => '',
            'newsletter_popup_cta' => "S'inscrire",
            'newsletter_popup_trigger_text' => 'Newsletter',
            'newsletter_popup_delay_seconds' => '3',
            'newsletter_popup_repeat_days' => '7',
        ], Setting::getGroup('newsletter'));

        return view('admin.newsletter.settings', compact('settings'));
    }

    public function settingsStore(Request $request)
    {
        Setting::set('newsletter_popup_enabled', $request->boolean('newsletter_popup_enabled') ? '1' : '0', 'newsletter');
        Setting::set('newsletter_popup_mode', in_array($request->newsletter_popup_mode ?? '', ['auto', 'manual'], true) ? $request->newsletter_popup_mode : 'auto', 'newsletter');
        Setting::set('newsletter_popup_title', trim((string) ($request->newsletter_popup_title ?? '')), 'newsletter');
        Setting::set('newsletter_popup_content', trim((string) ($request->newsletter_popup_content ?? '')), 'newsletter');
        Setting::set('newsletter_popup_cta', trim((string) ($request->newsletter_popup_cta ?? "S'inscrire")), 'newsletter');
        Setting::set('newsletter_popup_trigger_text', trim((string) ($request->newsletter_popup_trigger_text ?? 'Newsletter')), 'newsletter');
        Setting::set('newsletter_popup_delay_seconds', (string)($request->newsletter_popup_delay_seconds ?? 3), 'newsletter');
        Setting::set('newsletter_popup_repeat_days', (string)($request->newsletter_popup_repeat_days ?? 7), 'newsletter');

        if ($request->hasFile('newsletter_popup_image')) {
            $path = $request->file('newsletter_popup_image')->store('newsletter', 'public');
            Setting::set('newsletter_popup_image', $path, 'newsletter');
        } elseif ($request->has('newsletter_popup_image_remove') && $request->newsletter_popup_image_remove) {
            Setting::set('newsletter_popup_image', '', 'newsletter');
        }

        return redirect()->route('admin.newsletter.settings')->with('success', 'Paramètres enregistrés.');
    }

    public function campaigns()
    {
        $campaigns = Newsletter::orderBy('created_at', 'desc')->paginate(20);

        return view('admin.newsletter.campaigns', compact('campaigns'));
    }

    public function createCampaign()
    {
        $campaign = new Newsletter;
        $sendMode = 'now';

        return view('admin.newsletter.campaign-form', compact('campaign', 'sendMode'));
    }

    public function editCampaign(Newsletter $newsletter)
    {
        if ($newsletter->isSent()) {
            return redirect()->route('admin.newsletter.campaigns')->with('error', 'Impossible de modifier une campagne déjà envoyée.');
        }
        $campaign = $newsletter;
        $sendMode = $newsletter->scheduled_at ? 'scheduled' : 'now';

        return view('admin.newsletter.campaign-form', compact('campaign', 'sendMode'));
    }

    public function storeCampaign(Request $request)
    {
        $validated = $request->validate([
            'subject' => 'required|string|max:255',
            'content' => 'required|string',
            'send_mode' => 'nullable|in:now,scheduled',
            'scheduled_date' => 'required_if:send_mode,scheduled|nullable|date',
            'scheduled_time' => 'required_if:send_mode,scheduled|nullable|date_format:H:i',
        ]);

        $scheduledAt = null;
        if (($validated['send_mode'] ?? '') === 'scheduled' && ! empty($validated['scheduled_date'] ?? '') && ! empty($validated['scheduled_time'] ?? '')) {
            $scheduledAt = $validated['scheduled_date'].' '.$validated['scheduled_time'].':00';
        }

        Newsletter::create([
            'subject' => $validated['subject'],
            'content' => $validated['content'],
            'scheduled_at' => $scheduledAt,
        ]);

        $msg = $scheduledAt ? 'Campagne programmée pour le '.date('d/m/Y à H:i', strtotime($scheduledAt)).'.' : 'Newsletter créée.';

        return redirect()->route('admin.newsletter.campaigns')->with('success', $msg);
    }

    public function updateCampaign(Request $request, Newsletter $newsletter)
    {
        if ($newsletter->isSent()) {
            return redirect()->route('admin.newsletter.campaigns')->with('error', 'Impossible de modifier une campagne déjà envoyée.');
        }

        $validated = $request->validate([
            'subject' => 'required|string|max:255',
            'content' => 'required|string',
            'send_mode' => 'nullable|in:now,scheduled',
            'scheduled_date' => 'required_if:send_mode,scheduled|nullable|date',
            'scheduled_time' => 'required_if:send_mode,scheduled|nullable|date_format:H:i',
        ]);

        $scheduledAt = null;
        if (($validated['send_mode'] ?? '') === 'scheduled' && ! empty($validated['scheduled_date'] ?? '') && ! empty($validated['scheduled_time'] ?? '')) {
            $scheduledAt = $validated['scheduled_date'].' '.$validated['scheduled_time'].':00';
        }

        $newsletter->update([
            'subject' => $validated['subject'],
            'content' => $validated['content'],
            'scheduled_at' => $scheduledAt,
        ]);

        $msg = $scheduledAt ? 'Campagne mise à jour. Envoi programmé pour le '.date('d/m/Y à H:i', strtotime($scheduledAt)).'.' : 'Campagne mise à jour.';

        return redirect()->route('admin.newsletter.campaigns')->with('success', $msg);
    }

    public function sendCampaign(Request $request, Newsletter $newsletter)
    {
        if ($newsletter->isSent()) {
            return redirect()->route('admin.newsletter.campaigns')->with('error', 'Cette newsletter a déjà été envoyée.');
        }

        if (! $this->mailService->isConfigured()) {
            return redirect()->route('admin.newsletter.campaigns')->with('error', 'Configurez l\'email dans Paramètres > Email avant d\'envoyer.');
        }

        $subscribers = NewsletterSubscriber::where('is_active', true)->get();
        $count = 0;

        foreach ($subscribers as $subscriber) {
            $mailable = new NewsletterMail(
                $newsletter->subject,
                $newsletter->content,
                $subscriber->email,
                $subscriber->name
            );
            if ($this->mailService->send($mailable)) {
                $count++;
            }
        }

        $newsletter->update([
            'sent_at' => now(),
            'recipients_count' => $count,
        ]);

        return redirect()->route('admin.newsletter.campaigns')->with('success', "Newsletter envoyée à {$count} abonné(s).");
    }

    public function exportCsv(): StreamedResponse
    {
        $headers = [
            'Content-Type' => 'text/csv; charset=UTF-8',
            'Content-Disposition' => 'attachment; filename="newsletter-'.date('Y-m-d').'.csv"',
        ];

        return Response::stream(function () {
            $handle = fopen('php://output', 'w');
            fputcsv($handle, ['Email', 'Nom', 'Date d\'inscription'], ';');
            NewsletterSubscriber::where('is_active', true)
                ->orderBy('subscribed_at', 'desc')
                ->chunk(500, function ($subscribers) use ($handle) {
                    foreach ($subscribers as $s) {
                        fputcsv($handle, [
                            $s->email,
                            $s->name ?? '',
                            $s->subscribed_at?->format('d/m/Y H:i') ?? $s->created_at->format('d/m/Y H:i'),
                        ], ';');
                    }
                });
            fclose($handle);
        }, 200, $headers);
    }

    public function destroy(NewsletterSubscriber $newsletterSubscriber)
    {
        $newsletterSubscriber->update(['is_active' => false]);

        return redirect()->route('admin.newsletter.index')->with('success', 'Abonné désinscrit.');
    }
}
