<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\ApiSetting;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Schema;
use Illuminate\View\View;
use Throwable;

class SetupGuideController extends Controller
{
    public function index(): View
    {
        return view('admin.setup-guide.index', [
            'mailStatus' => $this->mailStatus(),
            'googleStatus' => $this->googleStatus(),
            'apiStatus' => $this->apiStatus(),
        ]);
    }

    public function sendTestEmail(Request $request): RedirectResponse
    {
        $data = $request->validate([
            'email' => ['required', 'email', 'max:255'],
        ]);

        try {
            Mail::raw(
                "This is a ViZuTrade test email.\n\nIf you received this message, your email sending setup is working.",
                function ($message) use ($data): void {
                    $message
                        ->to($data['email'])
                        ->subject('ViZuTrade Email Test');
                }
            );
        } catch (Throwable $exception) {
            Log::warning('Admin setup guide test email failed.', [
                'message' => $exception->getMessage(),
            ]);

            return back()->with('error', 'Test email failed: '.$this->friendlyMailError($exception));
        }

        return back()->with('success', 'Test email sent. Please check the inbox and spam folder.');
    }

    /**
     * @return array<string,mixed>
     */
    private function mailStatus(): array
    {
        $mailer = (string) config('mail.default');
        $fromAddress = (string) config('mail.from.address');
        $smtp = config('mail.mailers.smtp');
        $issues = [];

        if ($mailer === 'log') {
            $issues[] = 'MAIL_MAILER is set to log, so Laravel writes emails to storage/logs instead of sending them.';
        }

        if ($mailer === 'smtp') {
            if (blank($smtp['host'] ?? null) || in_array($smtp['host'], ['127.0.0.1', 'localhost'], true)) {
                $issues[] = 'SMTP host is not set to your real mail server.';
            }

            if (blank($smtp['username'] ?? null)) {
                $issues[] = 'SMTP username is empty.';
            }

            if (blank($smtp['password'] ?? null)) {
                $issues[] = 'SMTP password is empty.';
            }
        }

        if (blank($fromAddress) || $fromAddress === 'hello@example.com') {
            $issues[] = 'MAIL_FROM_ADDRESS should be a real address from your domain.';
        }

        return [
            'configured' => count($issues) === 0,
            'mailer' => $mailer,
            'host' => $smtp['host'] ?? null,
            'port' => $smtp['port'] ?? null,
            'scheme' => $smtp['scheme'] ?? null,
            'username_present' => filled($smtp['username'] ?? null),
            'password_present' => filled($smtp['password'] ?? null),
            'from_address' => $fromAddress,
            'from_name' => config('mail.from.name'),
            'issues' => $issues,
        ];
    }

    /**
     * @return array<string,mixed>
     */
    private function googleStatus(): array
    {
        $clientId = config('services.google.client_id');
        $clientSecret = config('services.google.client_secret');
        $redirect = config('services.google.redirect');
        $expectedRedirect = route('google.callback');

        $issues = [];

        if (blank($clientId)) {
            $issues[] = 'GOOGLE_CLIENT_ID is empty.';
        }

        if (blank($clientSecret)) {
            $issues[] = 'GOOGLE_CLIENT_SECRET is empty.';
        }

        if (blank($redirect)) {
            $issues[] = 'GOOGLE_REDIRECT_URI is empty.';
        }

        if (filled($redirect) && $redirect !== $expectedRedirect) {
            $issues[] = 'GOOGLE_REDIRECT_URI does not match the app callback URL exactly.';
        }

        return [
            'configured' => count($issues) === 0,
            'client_id_present' => filled($clientId),
            'client_secret_present' => filled($clientSecret),
            'redirect' => $redirect,
            'expected_redirect' => $expectedRedirect,
            'issues' => $issues,
        ];
    }

    /**
     * @return array<string,mixed>
     */
    private function apiStatus(): array
    {
        $tableExists = Schema::hasTable('api_settings');

        $fmpDatabase = $tableExists ? ApiSetting::activeForProvider(ApiSetting::PROVIDER_FMP) : null;
        $metaApiDatabase = $tableExists ? ApiSetting::activeForProvider(ApiSetting::PROVIDER_METAAPI) : null;

        return [
            'table_exists' => $tableExists,
            'fmp' => [
                'database_active' => $fmpDatabase !== null,
                'env_present' => filled(config('services.fmp.key')),
                'configured' => $fmpDatabase !== null || filled(config('services.fmp.key')),
            ],
            'metaapi' => [
                'database_active' => $metaApiDatabase !== null,
                'env_present' => filled(config('services.metaapi.token')),
                'configured' => $metaApiDatabase !== null || filled(config('services.metaapi.token')),
            ],
        ];
    }

    private function friendlyMailError(Throwable $exception): string
    {
        $message = $exception->getMessage();

        if (str_contains($message, 'Connection could not be established')) {
            return 'Laravel could not connect to your SMTP server. Check MAIL_HOST, MAIL_PORT, and MAIL_SCHEME.';
        }

        if (str_contains($message, 'Authentication failed') || str_contains($message, 'Expected response code')) {
            return 'SMTP login failed. Check MAIL_USERNAME and MAIL_PASSWORD.';
        }

        return str($message)->limit(180)->toString();
    }
}
