<?php

declare(strict_types=1);

namespace App\Modules\Workspace;

/**
 * WorkspaceValidator — Form Input Validator for Workspace & Owner Provisioning
 */
class WorkspaceValidator
{
    /**
     * Slugs that must never be used as workspace identifiers.
     *
     * These strings occupy the root public URL namespace and would collide
     * with application routes, infrastructure paths, or future feature segments.
     *
     * @ref G014.2 — Routing Architecture Audit
     */
    private const RESERVED_SLUGS = [
        // Application portal paths
        'admin', 'app', 'api', 'couple', 'crew', 'developer',
        // Auth paths
        'login', 'logout', 'register', 'reset', 'support',
        // Public invitation namespace
        'i', 'media', 'preview',
        // Live Preview and planned public feature segments
        'livepreview', 'share', 'gallery', 'story',
        'guestbook', 'checkin', 'qr', 'validation', 'validate',
        // Infrastructure & server paths
        'assets', 'storage', 'uploads', 'static', 'vendor',
        'sitemap', 'robots', 'favicon', 'health', 'status', 'index',
    ];

    /**
     * Validate workspace inputs.
     *
     * @param array $data Input parameters.
     * @return array<string, string> Keyed error messages; empty if valid.
     */
    public function validate(array $data): array
    {
        $errors = [];

        // 1. Groom Name
        $groomName = isset($data['groom_name']) ? trim((string) $data['groom_name']) : '';
        if ($groomName === '') {
            $errors['groom_name'] = 'Groom name is required.';
        } elseif (mb_strlen($groomName) > 100) {
            $errors['groom_name'] = 'Groom name must not exceed 100 characters.';
        }

        // 2. Bride Name
        $brideName = isset($data['bride_name']) ? trim((string) $data['bride_name']) : '';
        if ($brideName === '') {
            $errors['bride_name'] = 'Bride name is required.';
        } elseif (mb_strlen($brideName) > 100) {
            $errors['bride_name'] = 'Bride name must not exceed 100 characters.';
        }

        // 3. Wedding Date
        $weddingDate = isset($data['wedding_date']) ? trim((string) $data['wedding_date']) : '';
        if ($weddingDate === '') {
            $errors['wedding_date'] = 'Wedding date is required.';
        } else {
            // Check YYYY-MM-DD format
            if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $weddingDate)) {
                $errors['wedding_date'] = 'Wedding date must be in YYYY-MM-DD format.';
            } else {
                [$y, $m, $d] = explode('-', $weddingDate);
                if (!checkdate((int) $m, (int) $d, (int) $y)) {
                    $errors['wedding_date'] = 'Wedding date is not a valid date.';
                }
            }
        }

        // 4. Slug
        $slug = isset($data['slug']) ? trim((string) $data['slug']) : '';
        if ($slug === '') {
            $errors['slug'] = 'URL slug is required.';
        } elseif (mb_strlen($slug) < 5) {
            $errors['slug'] = 'URL slug must be at least 5 characters (e.g., john-jane).';
        } elseif (mb_strlen($slug) > 60) {
            $errors['slug'] = 'URL slug must not exceed 60 characters.';
        } elseif (!preg_match('/^[a-z0-9]+(?:-[a-z0-9]+)*$/', $slug)) {
            $errors['slug'] = 'URL slug must be lowercase, alphanumeric, and separated by single dashes (e.g., john-jane).';
        } elseif (in_array($slug, self::RESERVED_SLUGS, true)) {
            $errors['slug'] = "The URL slug \"{$slug}\" is reserved and cannot be used.";
        }


        // 5. Commercial Plan
        $planId = isset($data['commercial_plan_id']) ? (string) $data['commercial_plan_id'] : '';
        if ($planId === '') {
            $errors['commercial_plan_id'] = 'Commercial plan is required.';
        } else {
            $planVal = filter_var($planId, FILTER_VALIDATE_INT);
            if ($planVal === false || !in_array($planVal, [1, 2, 3], true)) {
                $errors['commercial_plan_id'] = 'Please select a valid commercial plan.';
            } else {
                // If custom plan (3), check custom guest limit
                if ($planVal === 3) {
                    $customLimit = isset($data['custom_guest_limit']) ? trim((string) $data['custom_guest_limit']) : '';
                    if ($customLimit === '') {
                        $errors['custom_guest_limit'] = 'Custom guest limit is required for Custom plans.';
                    } else {
                        $limitVal = filter_var($customLimit, FILTER_VALIDATE_INT);
                        if ($limitVal === false || $limitVal <= 0) {
                            $errors['custom_guest_limit'] = 'Please specify a positive number for custom guest limit.';
                        }
                    }
                }
            }
        }

        // 6. Event Type
        $eventTypeId = isset($data['event_type_id']) ? (string) $data['event_type_id'] : '';
        if ($eventTypeId === '') {
            $errors['event_type_id'] = 'Event type is required.';
        } else {
            $eventTypeVal = filter_var($eventTypeId, FILTER_VALIDATE_INT);
            if ($eventTypeVal === false || !in_array($eventTypeVal, [1, 2], true)) {
                $errors['event_type_id'] = 'Please select a valid event type.';
            }
        }

        return $errors;
    }

    /**
     * Validate Couple Owner inputs.
     *
     * @param array $data Input parameters.
     * @return array<string, string> Keyed error messages; empty if valid.
     */
    public function validateOwner(array $data): array
    {
        $errors = [];

        // 1. Display Name
        $displayName = isset($data['display_name']) ? trim((string) $data['display_name']) : '';
        if ($displayName === '') {
            $errors['display_name'] = 'Display Name is required.';
        } elseif (mb_strlen($displayName) < 3) {
            $errors['display_name'] = 'Display Name must be at least 3 characters.';
        }

        // 2. Username
        $username = isset($data['username']) ? trim((string) $data['username']) : '';
        if ($username === '') {
            $errors['username'] = 'Username is required.';
        } elseif (!preg_match('/^[a-zA-Z0-9_\-]+$/', $username)) {
            $errors['username'] = 'Username can only contain letters, numbers, dashes, and underscores.';
        } elseif (mb_strlen($username) < 4) {
            $errors['username'] = 'Username must be at least 4 characters.';
        }

        // 3. Email
        $email = isset($data['email']) ? trim((string) $data['email']) : '';
        if ($email === '') {
            $errors['email'] = 'Email is required.';
        } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $errors['email'] = 'Please enter a valid email address.';
        }

        // 4. Password
        $password = isset($data['password']) ? (string) $data['password'] : '';
        if ($password === '') {
            $errors['password'] = 'Password is required.';
        } elseif (mb_strlen($password) < 6) {
            $errors['password'] = 'Password must be at least 6 characters.';
        }

        return $errors;
    }
}
