<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Client;
use App\Models\ReportSchedule;
use App\Models\ReportTemplate;
use App\Services\Reports\ReportScheduleRunner;
use App\Services\Reports\ReportTemplateDefaults;
use App\Services\Reports\ScheduleNextRunCalculator;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Throwable;

class ReportScheduleController extends Controller
{
    public function __construct(private readonly ReportTemplateDefaults $templateDefaults)
    {
    }

    public function index(): View
    {
        $page_title = 'Otomatik Rapor Planları';
        $page_description = 'Günlük, haftalık ve aylık otomatik gönderim planları';
        $schedules = ReportSchedule::with(['client', 'template'])->latest()->paginate(20);

        return view('admin.report-schedules.index', compact('page_title', 'page_description', 'schedules'));
    }

    public function create(): View
    {
        $page_title = 'Rapor Planı Ekle';
        $page_description = 'Yeni otomatik rapor zamanlaması';
        $clients = Client::orderBy('company_name')->get();
        $templates = ReportTemplate::active()->orderBy('sort_order')->orderBy('name')->get();
        $schedule = new ReportSchedule([
            'frequency' => 'monthly',
            'daily_time' => '09:00',
            'monthly_day' => 1,
            'timezone' => 'Europe/Istanbul',
            'channels' => ['google_ads', 'meta_ads', 'search_console', 'ga4'],
            'include_pdf' => true,
            'include_excel' => true,
            'include_csv' => false,
            'is_active' => true,
        ]);

        return view('admin.report-schedules.create', compact('page_title', 'page_description', 'clients', 'templates', 'schedule'));
    }

    public function store(Request $request, ScheduleNextRunCalculator $nextRunCalculator): RedirectResponse
    {
        $schedule = new ReportSchedule($this->validated($request));
        $schedule->next_run_at = $schedule->is_active ? $nextRunCalculator->calculate($schedule) : null;
        $schedule->save();

        return redirect()->route('admin.report-schedules.index')->with('success', 'Rapor planı oluşturuldu.');
    }

    public function show(ReportSchedule $reportSchedule): View
    {
        $page_title = 'Rapor Planı';
        $page_description = $reportSchedule->client?->company_name ?? '';
        $reportSchedule->load(['client', 'template', 'generatedReports' => fn ($query) => $query->latest()->limit(10)]);

        return view('admin.report-schedules.show', compact('page_title', 'page_description', 'reportSchedule'));
    }

    public function edit(ReportSchedule $reportSchedule): View
    {
        $page_title = 'Rapor Planı Düzenle';
        $page_description = $reportSchedule->client?->company_name ?? '';
        $clients = Client::orderBy('company_name')->get();
        $templates = ReportTemplate::active()->orderBy('sort_order')->orderBy('name')->get();
        $schedule = $reportSchedule;

        return view('admin.report-schedules.edit', compact('page_title', 'page_description', 'clients', 'templates', 'schedule'));
    }

    public function update(Request $request, ReportSchedule $reportSchedule, ScheduleNextRunCalculator $nextRunCalculator): RedirectResponse
    {
        $reportSchedule->fill($this->validated($request));
        $reportSchedule->next_run_at = $reportSchedule->is_active ? $nextRunCalculator->calculate($reportSchedule) : null;
        $reportSchedule->save();

        return redirect()->route('admin.report-schedules.index')->with('success', 'Rapor planı güncellendi.');
    }

    public function destroy(ReportSchedule $reportSchedule): RedirectResponse
    {
        $reportSchedule->delete();

        return redirect()->route('admin.report-schedules.index')->with('success', 'Rapor planı silindi.');
    }

    public function run(ReportSchedule $reportSchedule, ReportScheduleRunner $runner): RedirectResponse
    {
        try {
            $report = $runner->runSchedule($reportSchedule, true);
        } catch (Throwable $exception) {
            report($exception);

            return back()->with('error', 'Plan çalıştırılamadı: ' . $exception->getMessage());
        }

        $reportSchedule->refresh();

        if ($reportSchedule->last_status !== 'success') {
            return redirect()->route('admin.reports.show', $report)->with('error', 'Plan çalıştı fakat mail/rapor süreci tamamlanamadı: ' . $reportSchedule->last_error);
        }

        return redirect()->route('admin.reports.show', $report)->with('success', 'Plan manuel çalıştırıldı ve rapor maili gönderildi.');
    }

    private function validated(Request $request): array
    {
        $data = $request->validate([
            'client_id' => ['required', 'exists:clients,id'],
            'report_template_id' => ['nullable', 'exists:report_templates,id'],
            'frequency' => ['required', 'in:daily,weekly,monthly'],
            'daily_time' => ['nullable', 'date_format:H:i'],
            'weekly_day' => ['nullable', 'integer', 'between:1,7'],
            'monthly_day' => ['nullable', 'integer', 'between:1,31'],
            'timezone' => ['required', 'string', 'max:80'],
            'channels' => ['nullable', 'array'],
            'channels.*' => ['in:google_ads,meta_ads,search_console,ga4'],
            'recipients_raw' => ['nullable', 'string'],
            'cc_raw' => ['nullable', 'string'],
            'bcc_raw' => ['nullable', 'string'],
            'include_pdf' => ['nullable', 'boolean'],
            'include_excel' => ['nullable', 'boolean'],
            'include_csv' => ['nullable', 'boolean'],
            'is_active' => ['nullable', 'boolean'],
        ]);

        foreach (['recipients', 'cc', 'bcc'] as $field) {
            $raw = $data[$field.'_raw'] ?? '';
            $data[$field] = collect(preg_split('/\r\n|\r|\n|,|;/', $raw))
                ->map(fn ($mail) => trim($mail))
                ->filter(fn ($mail) => filter_var($mail, FILTER_VALIDATE_EMAIL))
                ->values()
                ->all();
            unset($data[$field.'_raw']);
        }

        $template = ! empty($data['report_template_id']) ? ReportTemplate::find((int) $data['report_template_id']) : null;
        $data['channels'] = $this->templateDefaults->normalizeChannels($data['channels'] ?? ($template?->channels ?: []));
        $data['include_pdf'] = $request->boolean('include_pdf');
        $data['include_excel'] = $request->boolean('include_excel');
        $data['include_csv'] = $request->boolean('include_csv');
        $data['is_active'] = $request->boolean('is_active');

        return $data;
    }
}
