<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\BrandKit;
use App\Models\Client;
use App\Models\ReportTemplate;
use App\Services\Reports\ReportTemplateDefaults;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class ReportTemplateController extends Controller
{
    public function __construct(private readonly ReportTemplateDefaults $defaults)
    {
    }

    public function index(Request $request): View
    {
        $page_title = 'Rapor Şablonları';
        $page_description = 'PDF, Excel ve mail raporlarında kullanılacak markalı şablonlar';
        $clients = Client::orderBy('company_name')->get();

        $templates = ReportTemplate::with(['client', 'brandKit'])
            ->withCount(['schedules', 'generatedReports'])
            ->when($request->filled('client_id'), fn ($query) => $query->where('client_id', $request->integer('client_id')))
            ->when($request->filled('type'), fn ($query) => $query->where('type', $request->string('type')))
            ->when($request->filled('status'), fn ($query) => $query->where('is_active', $request->string('status') === 'active'))
            ->orderByRaw('client_id IS NOT NULL')
            ->orderBy('sort_order')
            ->orderBy('name')
            ->paginate(20)
            ->withQueryString();

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

    public function create(): View
    {
        $page_title = 'Rapor Şablonu Ekle';
        $page_description = 'Müşteri veya genel kullanım için yeni rapor tasarımı';
        $clients = Client::orderBy('company_name')->get();
        $brandKits = BrandKit::active()->with('client')->orderByRaw('client_id IS NOT NULL')->orderBy('sort_order')->orderBy('name')->get();
        $template = new ReportTemplate([
            'type' => 'monthly',
            'channels' => array_keys($this->defaults->channels()),
            'sections' => $this->defaults->defaultSections('monthly'),
            'settings' => $this->defaults->defaultSettings(),
            'is_active' => true,
            'sort_order' => 100,
        ]);

        return view('admin.report-templates.create', $this->formData($page_title, $page_description, $clients, $brandKits, $template));
    }

    public function store(Request $request): RedirectResponse
    {
        $data = $this->validated($request);
        $template = ReportTemplate::create($data);
        $this->resetOtherDefaults($template);

        return redirect()->route('admin.report-templates.show', $template)->with('success', 'Rapor şablonu oluşturuldu.');
    }

    public function show(ReportTemplate $reportTemplate): View
    {
        $page_title = 'Rapor Şablonu Detayı';
        $page_description = $reportTemplate->name;
        $reportTemplate->load(['client', 'brandKit', 'schedules.client']);

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

    public function edit(ReportTemplate $reportTemplate): View
    {
        $page_title = 'Rapor Şablonu Düzenle';
        $page_description = $reportTemplate->name;
        $clients = Client::orderBy('company_name')->get();
        $brandKits = BrandKit::active()->with('client')->orderByRaw('client_id IS NOT NULL')->orderBy('sort_order')->orderBy('name')->get();
        $template = $reportTemplate;

        return view('admin.report-templates.edit', $this->formData($page_title, $page_description, $clients, $brandKits, $template));
    }

    public function update(Request $request, ReportTemplate $reportTemplate): RedirectResponse
    {
        $reportTemplate->fill($this->validated($request));
        $reportTemplate->save();
        $this->resetOtherDefaults($reportTemplate);

        return redirect()->route('admin.report-templates.show', $reportTemplate)->with('success', 'Rapor şablonu güncellendi.');
    }

    public function destroy(ReportTemplate $reportTemplate): RedirectResponse
    {
        $reportTemplate->delete();

        return redirect()->route('admin.report-templates.index')->with('success', 'Rapor şablonu silindi.');
    }

    public function duplicate(ReportTemplate $reportTemplate): RedirectResponse
    {
        $copy = $reportTemplate->replicate();
        $copy->name = 'Kopya - ' . $reportTemplate->name;
        $copy->is_default = false;
        $copy->is_active = true;
        $copy->sort_order = ((int) $reportTemplate->sort_order) + 1;
        $copy->save();

        return redirect()->route('admin.report-templates.edit', $copy)->with('success', 'Şablon kopyalandı. Üzerinde düzenleme yapabilirsiniz.');
    }

    public function preview(ReportTemplate $reportTemplate): View
    {
        $page_title = 'Şablon Önizleme';
        $page_description = $reportTemplate->name;
        $reportTemplate->load(['client', 'brandKit']);
        $templateSettings = $this->defaults->settingsFor($reportTemplate, $reportTemplate->client);
        $templateSections = $this->defaults->sectionsFor($reportTemplate);
        $channels = $reportTemplate->effectiveChannels();

        return view('admin.report-templates.preview', compact('page_title', 'page_description', 'reportTemplate', 'templateSettings', 'templateSections', 'channels'));
    }

    public function seedDefaults(): RedirectResponse
    {
        $count = $this->defaults->seedDefaults();

        return redirect()->route('admin.report-templates.index')->with('success', $count . ' varsayılan şablon güncellendi/oluşturuldu.');
    }

    private function formData(string $page_title, string $page_description, $clients, $brandKits, ReportTemplate $template): array
    {
        return [
            'page_title' => $page_title,
            'page_description' => $page_description,
            'clients' => $clients,
            'brandKits' => $brandKits,
            'template' => $template,
            'channelOptions' => $this->defaults->channels(),
            'sectionGroups' => $this->defaults->sectionGroups(),
            'defaultSettings' => $this->defaults->defaultSettings(),
            'templateSettings' => $this->defaults->settingsFor($template, $template->client),
            'templateSections' => $this->defaults->sectionsFor($template),
        ];
    }

    /** @return array<string, mixed> */
    private function validated(Request $request): array
    {
        $data = $request->validate([
            'client_id' => ['nullable', 'exists:clients,id'],
            'brand_kit_id' => ['nullable', 'exists:brand_kits,id'],
            'name' => ['required', 'string', 'max:180'],
            'description' => ['nullable', 'string', 'max:2000'],
            'type' => ['required', 'in:daily,weekly,monthly,custom'],
            'channels' => ['nullable', 'array'],
            'channels.*' => ['in:google_ads,meta_ads,search_console,ga4'],
            'sections' => ['nullable', 'array'],
            'settings' => ['nullable', 'array'],
            'settings.agency_name' => ['nullable', 'string', 'max:160'],
            'settings.agency_logo_url' => ['nullable', 'string', 'max:500'],
            'settings.client_logo_url' => ['nullable', 'string', 'max:500'],
            'settings.primary_color' => ['nullable', 'string', 'max:20'],
            'settings.accent_color' => ['nullable', 'string', 'max:20'],
            'settings.secondary_color' => ['nullable', 'string', 'max:20'],
            'settings.text_color' => ['nullable', 'string', 'max:20'],
            'settings.muted_color' => ['nullable', 'string', 'max:20'],
            'settings.cover_style' => ['nullable', 'in:gradient,minimal,image,dark'],
            'settings.cover_background_url' => ['nullable', 'string', 'max:500'],
            'settings.cover_title' => ['nullable', 'string', 'max:220'],
            'settings.cover_subtitle' => ['nullable', 'string', 'max:400'],
            'settings.intro_text' => ['nullable', 'string', 'max:2000'],
            'settings.footer_note' => ['nullable', 'string', 'max:600'],
            'settings.contact_email' => ['nullable', 'string', 'max:180'],
            'settings.contact_phone' => ['nullable', 'string', 'max:80'],
            'settings.website_url' => ['nullable', 'string', 'max:220'],
            'settings.table_limit' => ['nullable', 'integer', 'between:5,100'],
            'settings.show_client_logo' => ['nullable', 'boolean'],
            'settings.show_agency_logo' => ['nullable', 'boolean'],
            'settings.show_data_timestamp' => ['nullable', 'boolean'],
            'settings.compact_mode' => ['nullable', 'boolean'],
            'settings.include_pdf_cover' => ['nullable', 'boolean'],
            'settings.include_excel_summary' => ['nullable', 'boolean'],
            'is_default' => ['nullable', 'boolean'],
            'is_active' => ['nullable', 'boolean'],
            'sort_order' => ['nullable', 'integer', 'between:0,9999'],
        ]);

        $settings = $request->input('settings', []);
        foreach (['show_client_logo', 'show_agency_logo', 'show_data_timestamp', 'compact_mode', 'include_pdf_cover', 'include_excel_summary'] as $key) {
            $settings[$key] = $request->boolean('settings.' . $key);
        }

        $sections = [];
        foreach ($this->defaults->sectionKeys() as $key) {
            $sections[$key] = $request->boolean('sections.' . $key);
        }

        return [
            'client_id' => $data['client_id'] ?? null,
            'brand_kit_id' => $data['brand_kit_id'] ?? null,
            'name' => $data['name'],
            'description' => $data['description'] ?? null,
            'type' => $data['type'],
            'channels' => $this->defaults->normalizeChannels($data['channels'] ?? []),
            'sections' => $this->defaults->normalizeSections($sections, $data['type']),
            'settings' => $this->defaults->normalizeSettings($settings),
            'is_default' => $request->boolean('is_default'),
            'is_active' => $request->boolean('is_active'),
            'sort_order' => (int) ($data['sort_order'] ?? 100),
        ];
    }

    private function resetOtherDefaults(ReportTemplate $template): void
    {
        if (! $template->is_default) {
            return;
        }

        ReportTemplate::query()
            ->where('id', '!=', $template->id)
            ->where('type', $template->type)
            ->where(function ($query) use ($template) {
                $template->client_id
                    ? $query->where('client_id', $template->client_id)
                    : $query->whereNull('client_id');
            })
            ->update(['is_default' => false]);
    }
}
