<?php

namespace Webkul\Recruitment\Filament\Widgets;

use Filament\Widgets\ChartWidget;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Support\Carbon;
use Webkul\Recruitment\Models\Applicant;

class ApplicantChartWidget extends ChartWidget
{
    protected static ?int $sort = 2;

    protected int|string|array $columnSpan = 'full';

    protected ?string $maxHeight = '400px';

    protected static function getPagePermission(): ?string
    {
        return 'widget_recruitment_applicant_chart_widget';
    }

    public function getHeading(): string|Htmlable|null
    {
        return __('recruitments::filament/widgets/applicant.heading.title');
    }

    protected function getData(): array
    {
        $query = Applicant::query();

        if ($this->pageFilters['selectedJobs'] ?? null) {
            $query->whereIn('job_id', $this->pageFilters['selectedJobs']);
        }

        if ($this->pageFilters['selectedDepartments'] ?? null) {
            $query->whereIn('department_id', $this->pageFilters['selectedDepartments']);
        }

        if ($this->pageFilters['selectedCompanies'] ?? null) {
            $query->whereIn('company_id', $this->pageFilters['selectedCompanies']);
        }

        if ($this->pageFilters['selectedStages'] ?? null) {
            $query->whereIn('stage_id', $this->pageFilters['selectedStages']);
        }

        if ($this->pageFilters['selectedRecruiters'] ?? null) {
            $query->whereIn('recruiter_id', $this->pageFilters['selectedRecruiters']);
        }

        if ($this->pageFilters['startDate'] ?? null) {
            $query->where('created_at', '>=', Carbon::parse($this->pageFilters['startDate'])->startOfDay());
        }

        if ($this->pageFilters['endDate'] ?? null) {
            $query->where('created_at', '<=', Carbon::parse($this->pageFilters['endDate'])->endOfDay());
        }

        $stats = $query->selectRaw('
            COUNT(*) as total,
            SUM(CASE WHEN refuse_reason_id IS NOT NULL THEN 1 ELSE 0 END) as refused,
            SUM(CASE WHEN date_closed IS NOT NULL THEN 1 ELSE 0 END) as hired,
            SUM(CASE WHEN is_active = 0 OR deleted_at IS NOT NULL THEN 1 ELSE 0 END) as archived,
            SUM(CASE
                WHEN refuse_reason_id IS NULL
                AND date_closed IS NULL
                AND is_active = 1
                AND deleted_at IS NULL THEN 1
                ELSE 0
            END) as ongoing
        ')->first();

        $data = match ($this->pageFilters['status'] ?? 'all') {
            'ongoing'  => ['Ongoing' => $stats->ongoing ?? 0],
            'hired'    => ['Hired' => $stats->hired ?? 0],
            'refused'  => ['Refused' => $stats->refused ?? 0],
            'archived' => ['Archived' => $stats->archived ?? 0],
            default    => [
                'Ongoing'  => $stats->ongoing ?? 0,
                'Hired'    => $stats->hired ?? 0,
                'Refused'  => $stats->refused ?? 0,
                'Archived' => $stats->archived ?? 0,
            ],
        };

        $colorMap = [
            'Ongoing'  => '#3b82f6',
            'Hired'    => '#22c55e',
            'Refused'  => '#ef4444',
            'Archived' => '#94a3b8',
        ];

        $translatedLabels = array_map(fn ($key) => match ($key) {
            'Ongoing'  => __('recruitments::filament/widgets/applicant.ongoing'),
            'Hired'    => __('recruitments::filament/widgets/applicant.hired'),
            'Refused'  => __('recruitments::filament/widgets/applicant.refused'),
            'Archived' => __('recruitments::filament/widgets/applicant.archived'),
            default    => $key,
        }, array_keys($data));

        return [
            'datasets' => [
                [
                    'label'           => __('recruitments::filament/widgets/applicant.heading.title'),
                    'data'            => array_values($data),
                    'backgroundColor' => array_map(fn ($key) => $colorMap[$key] ?? '#94a3b8', array_keys($data)),
                ],
            ],
            'labels' => $translatedLabels,
        ];
    }

    protected function getType(): string
    {
        return 'bar';
    }
}
