<?php

declare(strict_types=1);

namespace App\Http\Controllers\User;

use App\Http\Controllers\Controller;
use App\Models\Expert;
use App\Models\Order;
use App\Models\Producer;
use App\Models\Project;
use App\Models\User;
use App\Support\ApiResponse;
use App\Support\FileUrl;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class DashboardController extends Controller
{
    public function __invoke(Request $request): JsonResponse
    {
        /** @var User $user */
        $user = $request->user()->load(['roles', 'producer', 'expert']);

        $userProjects = function ($query) use ($user): void {
            $query->where(function ($q) use ($user): void {
                $q->where('user_id', $user->id)
                    ->orWhere('created_by', $user->id);

                if ($user->producer?->id) {
                    $q->orWhere('producer_id', $user->producer->id);
                }
            });
        };

        $activeStatuses = [
            Project::STATUS_ACTIVE,
            Project::STATUS_APPROVED,
            Project::STATUS_UNSIGNED,
            Project::STATUS_WAITING,
        ];

        $activeProjectsCount = Project::query()
            ->where($userProjects)
            ->whereIn('status', $activeStatuses)
            ->count();

        $completedProjectsCount = Project::query()
            ->where($userProjects)
            ->where('status', Project::STATUS_COMPLETED)
            ->count();

        $totalInvestment = (int) Project::query()
            ->where($userProjects)
            ->sum('budget');

        $walletBalance = (int) ($user->wallet ?? 0);

        return ApiResponse::success(
            [
                'user' => $this->userPayload($user),
                'stats' => [
                    'active_projects_count' => $activeProjectsCount,
                    'completed_projects_count' => $completedProjectsCount,
                    'total_investment' => $totalInvestment,
                    'wallet_balance' => $walletBalance,
                    'unread_notifications' => $user->unreadNotifications()->count(),
                ],
                'alerts' => $this->alerts($user),
                'notification_settings' => $user->notificationSettings(),
                'profile_cta' => $this->profileCta($user),
            ],
            'اطلاعات داشبورد با موفقیت دریافت شد.'
        );
    }

    /**
     * @return array<string, mixed>
     */
    private function userPayload(User $user): array
    {
        $roles = $user->roles->pluck('name')->values()->all();

        return [
            'id' => $user->id,
            'first_name' => $user->first_name,
            'last_name' => $user->last_name,
            'name' => $user->username ?: $user->name,
            'cellphone' => $user->cellphone,
            'email' => $user->email,
            'national_code' => $user->national_code,
            'phone' => $user->phone,
            'address' => $user->address,
            'dob' => $user->dob?->toDateString(),
            'avatar' => FileUrl::url($user->avatar),
            'wallet' => (int) ($user->wallet ?? 0),
            'roles' => $roles,
            'account_type' => $user->resolveAccountType(),
            'producer_id' => $user->producer?->id,
            'expert_id' => $user->expert?->id,
            'producer' => $this->profileSummary($user->producer),
            'expert' => $this->profileSummary($user->expert),
        ];
    }

    /**
     * @return array{id: int, status: string|null, admin_reason: string|null}|null
     */
    private function profileSummary(Producer|Expert|null $profile): ?array
    {
        if (! $profile) {
            return null;
        }

        return [
            'id' => $profile->id,
            'status' => $profile->status,
            'admin_reason' => $profile->admin_reason,
        ];
    }

    /**
     * @return list<array{type: string, title: string, body: string}>
     */
    private function alerts(User $user): array
    {
        $alerts = [];

        $hasPendingOrders = Order::query()
            ->where('user_id', $user->id)
            ->where('status', 'pending')
            ->exists();

        if ($hasPendingOrders) {
            $alerts[] = [
                'type' => 'order_finalize',
                'title' => 'ثبت نهایی سفارش',
                'body' => 'پس از ثبت سفارش، تا ۲۴ ساعت فرصت دارید سفارش خود را نهایی کنید.',
            ];
        }

        if ($user->producer?->status === Producer::STATUS_NEEDS_EDIT) {
            $alerts[] = [
                'type' => 'producer_needs_edit',
                'title' => 'تکمیل پروفایل تولیدکننده',
                'body' => $user->producer->admin_reason
                    ?: 'پروفایل تولیدکننده شما نیاز به ویرایش دارد.',
            ];
        }

        if ($user->expert?->status === Expert::STATUS_NEEDS_EDIT) {
            $alerts[] = [
                'type' => 'expert_needs_edit',
                'title' => 'تکمیل پروفایل خدمات‌دهنده',
                'body' => $user->expert->admin_reason
                    ?: 'پروفایل خدمات‌دهنده شما نیاز به ویرایش دارد.',
            ];
        }

        return $alerts;
    }

    /**
     * @return array{type: string|null, status: string|null, required: bool}
     */
    private function profileCta(User $user): array
    {
        $actionable = [
            Producer::STATUS_PENDING,
            Producer::STATUS_NEEDS_EDIT,
            Producer::STATUS_REJECTED,
        ];

        if ($user->producer && in_array($user->producer->status, $actionable, true)) {
            return [
                'type' => 'producer',
                'status' => $user->producer->status,
                'required' => true,
            ];
        }

        if ($user->expert && in_array($user->expert->status, $actionable, true)) {
            return [
                'type' => 'expert',
                'status' => $user->expert->status,
                'required' => true,
            ];
        }

        if (
            ($user->hasRole(User::ROLE_PRODUCER) || $user->resolveAccountType() === User::ACCOUNT_PRODUCER)
            && ! $user->producer
        ) {
            return [
                'type' => 'producer',
                'status' => null,
                'required' => true,
            ];
        }

        if (
            ($user->hasRole(User::ROLE_EXPERT) || $user->resolveAccountType() === User::ACCOUNT_EXPERT)
            && ! $user->expert
        ) {
            return [
                'type' => 'expert',
                'status' => null,
                'required' => true,
            ];
        }

        if ($user->producer) {
            return [
                'type' => 'producer',
                'status' => $user->producer->status,
                'required' => false,
            ];
        }

        if ($user->expert) {
            return [
                'type' => 'expert',
                'status' => $user->expert->status,
                'required' => false,
            ];
        }

        return [
            'type' => null,
            'status' => null,
            'required' => false,
        ];
    }
}
