<?php

namespace App\Services\Auth;

use App\Models\Configuration;
use App\Models\ParentModel;
use App\Models\Role;
use App\Models\User;
use App\Models\UserRole;
use App\Services\EmailService;
use App\Services\SchoolIdService;
use Illuminate\Support\Facades\DB;

class RegistrationService
{
    public function __construct(
        private EmailService $emailService,
        private SchoolIdService $schoolIdService,
        private RegistrationFormatterService $formatter,
        private RegistrationCaptchaService $captchaService
    ) {
    }

    public function register(array $payload): array
    {
        $captcha = (string) ($payload['captcha'] ?? '');
        if (!$this->captchaService->verify($captcha)) {
            return [
                'ok' => false,
                'code' => 'captcha_invalid',
                'message' => 'Incorrect CAPTCHA answer. Please try again.',
            ];
        }

        $isParent = !empty($payload['is_parent']);
        $noSecondInfo = !empty($payload['no_second_parent_info']);

        $formatted = $this->formatter->format($payload);
        $email = (string) ($formatted['email'] ?? '');

        $existing = User::query()->where('email', $email)->first();
        if ($existing) {
            $pending = !empty($existing->token) && (int) ($existing->is_verified ?? 0) === 0;
            if ($pending) {
                return [
                    'ok' => false,
                    'code' => 'pending_activation',
                    'message' => 'This email address is already registered and pending activation.',
                ];
            }

            return [
                'ok' => false,
                'code' => 'email_exists',
                'message' => 'The email address you entered is already in use.',
            ];
        }

        $roleName = $isParent ? 'parent' : 'guest';
        $role = Role::query()->where('name', $roleName)->first();
        if (!$role) {
            return [
                'ok' => false,
                'code' => 'role_missing',
                'message' => 'Role not found.',
            ];
        }

        $token = bin2hex(random_bytes(48));
        $schoolYear = Configuration::getConfig('school_year');
        $semester = Configuration::getConfig('semester');

        $userData = [
            'firstname' => (string) ($formatted['firstname'] ?? ''),
            'lastname' => (string) ($formatted['lastname'] ?? ''),
            'gender' => (string) ($formatted['gender'] ?? ''),
            'email' => $email,
            'cellphone' => (string) ($formatted['cellphone'] ?? ($payload['cellphone'] ?? '')),
            'address_street' => (string) ($formatted['address_street'] ?? ''),
            'apt' => $formatted['apt'] ?? null,
            'city' => (string) ($formatted['city'] ?? ''),
            'state' => (string) ($formatted['state'] ?? ''),
            'zip' => (string) ($formatted['zip'] ?? ''),
            'token' => $token,
            'is_verified' => 0,
            'accept_school_policy' => (int) ($formatted['accept_school_policy'] ?? 0),
            'status' => 'Inactive',
            'school_id' => $this->schoolIdService->generateUserSchoolId(),
            'semester' => (string) ($semester ?? ''),
            'school_year' => $schoolYear,
            'password' => pbkdf2_hash(bin2hex(random_bytes(8))),
        ];

        $user = null;

        DB::transaction(function () use (
            $userData,
            $role,
            $isParent,
            $noSecondInfo,
            $formatted,
            $schoolYear,
            $semester,
            &$user
        ) {
            $user = User::query()->create($userData);

            UserRole::query()->create([
                'user_id' => (int) $user->id,
                'role_id' => (int) $role->id,
                'created_at' => now(),
            ]);

            if ($isParent && !$noSecondInfo && !empty($formatted['second_firstname'])) {
                ParentModel::query()->create([
                    'secondparent_firstname' => $formatted['second_firstname'] ?? null,
                    'secondparent_lastname' => $formatted['second_lastname'] ?? null,
                    'secondparent_gender' => $formatted['second_gender'] ?? null,
                    'secondparent_email' => $formatted['second_email'] ?? null,
                    'secondparent_phone' => $formatted['second_cellphone'] ?? null,
                    'firstparent_id' => (int) $user->id,
                    'semester' => $semester,
                    'school_year' => $schoolYear,
                ]);
            }
        });

        $activationLink = url('/user/confirm/' . $token);
        $recipientName = trim((string) ($formatted['firstname'] ?? '') . ' ' . (string) ($formatted['lastname'] ?? ''));

        $emailData = [
            'recipientName' => $recipientName,
            'activationLink' => $activationLink,
            'orgName' => 'Al Rahma Sunday School',
            'contactInfo' => 'alrahma.isgl@gmail.com',
            'logoUrl' => 'https://alrahmaisgl.org/assets/images/alrahma_logo.png',
            'subject' => 'Email Confirmation',
        ];

        if (view()->exists($isParent ? 'emails.welcome_parent' : 'emails.welcome_staff')) {
            $html = view($isParent ? 'emails.welcome_parent' : 'emails.welcome_staff', $emailData);
        } else {
            $html = '<p>Hello ' . e($recipientName !== '' ? $recipientName : 'there') . ',</p>'
                . '<p>Please confirm your email by clicking the link below:</p>'
                . '<p><a href="' . e($activationLink) . '">Activate your account</a></p>'
                . '<p>Thank you.</p>';
        }

        $sent = $this->emailService->send($email, 'Email Confirmation', $html, 'general');
        $this->captchaService->clear();

        return [
            'ok' => true,
            'user' => $user,
            'role' => $roleName,
            'activation_sent' => $sent,
        ];
    }
}
