<?php

namespace App\Reports;

abstract class BaseReport implements ReportInterface
{
    protected array $filters = [];

    protected array $data = [];

    protected ?array $chartData = null;

    /**
     * Rapor verilerini işle ve döndür
     */
    public function process(array $filters = []): array
    {
        $this->filters = $filters;
        $this->data = $this->getData($filters);

        if ($this->hasChart()) {
            $this->chartData = $this->getChartData($filters);
        }

        return [
            'success' => true,
            'data' => $this->data,
            'columns' => $this->getColumns(),
            'filters' => $this->getFilters(),
            'chart' => $this->chartData ? [
                'type' => $this->getChartType(),
                'data' => $this->chartData,
            ] : null,
            'summary' => $this->getSummary(),
            'meta' => [
                'name' => $this->getName(),
                'description' => $this->getDescription(),
                'category' => $this->getCategory(),
                'icon' => $this->getIcon(),
                'has_chart' => $this->hasChart(),
            ],
        ];
    }

    /**
     * Rapor özetini döndür
     */
    protected function getSummary(): array
    {
        return [
            'total_records' => count($this->data),
            'generated_at' => now()->toISOString(),
            'filters_applied' => $this->filters,
        ];
    }

    /**
     * Tarih filtresi uygula
     */
    protected function applyDateFilter($query, string $dateField = 'created_at'): void
    {
        if (isset($this->filters['start_date'])) {
            $query->where($dateField, '>=', $this->filters['start_date']);
        }

        if (isset($this->filters['end_date'])) {
            $query->where($dateField, '<=', $this->filters['end_date']);
        }
    }

    /**
     * Periyot filtresi uygula
     */
    protected function applyPeriodFilter($query, string $dateField = 'created_at'): void
    {
        $period = $this->filters['period'] ?? 'monthly';

        switch ($period) {
            case 'daily':
                $query->selectRaw("DATE($dateField) as period, COUNT(*) as count")
                    ->groupBy('period')
                    ->orderBy('period');
                break;
            case 'weekly':
                $query->selectRaw("YEARWEEK($dateField) as period, COUNT(*) as count")
                    ->groupBy('period')
                    ->orderBy('period');
                break;
            case 'monthly':
                $query->selectRaw("DATE_FORMAT($dateField, '%Y-%m') as period, COUNT(*) as count")
                    ->groupBy('period')
                    ->orderBy('period');
                break;
            case 'quarterly':
                $query->selectRaw("CONCAT(YEAR($dateField), '-Q', QUARTER($dateField)) as period, COUNT(*) as count")
                    ->groupBy('period')
                    ->orderBy('period');
                break;
            case 'yearly':
                $query->selectRaw("YEAR($dateField) as period, COUNT(*) as count")
                    ->groupBy('period')
                    ->orderBy('period');
                break;
        }
    }

    /**
     * Sütun tanımlarını döndür (varsayılan)
     */
    public function getColumns(): array
    {
        return [
            'id' => [
                'title' => __('admin/reports.base_column_id'),
                'type' => 'number',
                'sortable' => true,
            ],
            'created_at' => [
                'title' => __('admin/reports.base_column_created_at'),
                'type' => 'date',
                'sortable' => true,
            ],
        ];
    }

    /**
     * Filtre tanımlarını döndür
     */
    public function getFilters(): array
    {
        return [
            'start_date' => [
                'type' => 'date',
                'label' => __('admin/reports.base_filter_start_date'),
                'required' => false,
                'default' => now()->subMonth()->format('Y-m-d'),
            ],
            'end_date' => [
                'type' => 'date',
                'label' => __('admin/reports.base_filter_end_date'),
                'required' => false,
                'default' => now()->format('Y-m-d'),
            ],
            'period' => [
                'type' => 'select',
                'label' => __('admin/reports.base_filter_period'),
                'required' => false,
                'options' => [
                    'daily' => __('admin/reports.base_period_daily'),
                    'weekly' => __('admin/reports.base_period_weekly'),
                    'monthly' => __('admin/reports.base_period_monthly'),
                    'yearly' => __('admin/reports.base_period_yearly'),
                ],
                'default' => 'monthly',
            ],
        ];
    }

    /**
     * Varsayılan filtreleri döndür
     */
    public function getDefaultFilters(): array
    {
        return [
            'start_date' => now()->subMonth()->format('Y-m-d'),
            'end_date' => now()->format('Y-m-d'),
            'period' => 'monthly',
        ];
    }

    /**
     * Filtreleri validate et
     */
    public function validateFilters(array $filters): array
    {
        $rules = [
            'start_date' => 'nullable|date',
            'end_date' => 'nullable|date|after_or_equal:start_date',
            'period' => 'nullable|in:daily,weekly,monthly,quarterly,yearly',
            'year' => 'nullable|integer|min:2020|max:'.(date('Y') + 1),
            'month' => 'nullable|integer|min:1|max:12',
            'cohort_size' => 'nullable|integer|min:1|max:365',
            'currency' => 'nullable|string|in:all,TRY,USD,EUR',
            'product_category' => 'nullable|string',
            'suspension_reason' => 'nullable|string',
            'limit' => 'nullable|integer|min:1|max:100',
            'country' => 'nullable|string',
            'source' => 'nullable|string',
            'payment_method' => 'nullable|string',
            'min_mrr' => 'nullable|numeric|min:0',
            'max_mrr' => 'nullable|numeric|min:0',
            'client_id' => 'nullable|integer|exists:clients,id',
            'transaction_type' => 'nullable|string',
            'min_clients' => 'nullable|integer|min:0',
            'min_services' => 'nullable|integer|min:0',
            'min_registrations' => 'nullable|integer|min:0',
        ];

        $validator = validator($filters, $rules);

        if ($validator->fails()) {
            throw new \InvalidArgumentException($validator->errors()->first());
        }

        return $filters;
    }
}
