<?php

declare(strict_types=1);

namespace App\Admin;

/**
 * Declarative CRUD module definitions. Each module drives the generic
 * list/create/edit/delete admin screens.
 *
 * Field types: text, textarea, richtext, number, checkbox, date, datetime,
 *              image (URL + upload widget), json (raw JSON textarea),
 *              select (static options), fk (foreign key dropdown).
 *
 * Layout keys, all optional — a module that sets none renders as one flat list
 * of fields, which is what most of them still do:
 *   'groups'     module-level map of key => ['label', 'hint']. Fields carrying a
 *                matching 'group' render inside that section, in the order the
 *                groups are declared here.
 *   'group'      field-level section key, as above.
 *   'advanced'   field sits in the collapsed "Advanced" block at the foot of the
 *                form — for things the client rarely touches (slugs, SEO).
 *   'bar'        field rides in the sticky save bar instead of the form body.
 *   'showWhen'   field is only revealed once the named sibling field has a value.
 *   'autoFrom'   field self-fills by slugifying the named sibling until the user
 *                types in it directly.
 *   'row'        consecutive fields sharing a row key render side by side.
 */
final class Modules
{
    /** @return array<string, array<string, mixed>> */
    public static function all(): array
    {
        return [
            'treatments' => [
                'label'   => 'Treatments',
                'table'   => 'treatments',
                'icon'    => '💆',
                'order'   => 'sort_order, id',
                'columns' => ['name', 'duration', 'price', 'featured', 'status'],
                'fields'  => [
                    'name'        => ['type' => 'text', 'required' => true],
                    'slug'        => ['type' => 'text', 'required' => true, 'help' => 'URL identifier, e.g. wadadli-massage'],
                    'category_id' => ['type' => 'fk', 'table' => 'treatment_categories', 'label' => 'Category'],
                    'description' => ['type' => 'textarea', 'required' => true],
                    'duration'    => ['type' => 'text', 'required' => true],
                    'price'       => ['type' => 'number', 'required' => true, 'step' => '0.01'],
                    'image'       => ['type' => 'image'],
                    'featured'    => ['type' => 'checkbox', 'help' => 'Show on the homepage'],
                    'status'      => ['type' => 'checkbox', 'label' => 'Visible on website', 'default' => 1],
                    'sort_order'  => ['type' => 'number', 'default' => 0],
                ],
            ],
            'treatment_categories' => [
                'label'   => 'Treatment Categories',
                'table'   => 'treatment_categories',
                'icon'    => '🏷️',
                'hidden'  => true,
                'columns' => ['name'],
                'fields'  => ['name' => ['type' => 'text', 'required' => true]],
            ],
            'packages' => [
                'label'   => 'Packages',
                'table'   => 'packages',
                'icon'    => '🌴',
                'order'   => 'sort_order, id',
                'columns' => ['name', 'tag', 'price', 'active'],
                'fields'  => [
                    'name'        => ['type' => 'text', 'required' => true],
                    'slug'        => ['type' => 'text', 'required' => true],
                    'tag'         => ['type' => 'text', 'help' => 'Badge text, e.g. dates'],
                    'dates_label' => ['type' => 'text'],
                    'description' => ['type' => 'textarea', 'required' => true],
                    'included'    => ['type' => 'json', 'shape' => 'list', 'help' => 'One item per line, e.g. Accommodation'],
                    'price'       => ['type' => 'number', 'required' => true, 'step' => '0.01'],
                    'price_label' => ['type' => 'text'],
                    'promo_price' => ['type' => 'number', 'step' => '0.01'],
                    'promo_label' => ['type' => 'text'],
                    'image'       => ['type' => 'image'],
                    'active'      => ['type' => 'checkbox', 'default' => 1],
                    'sort_order'  => ['type' => 'number', 'default' => 0],
                ],
            ],
            'gallery_images' => [
                'label'   => 'Gallery',
                'table'   => 'gallery_images',
                'icon'    => '🖼️',
                'order'   => 'sort_order, id',
                'columns' => ['src', 'alt', 'size', 'active'],
                'fields'  => [
                    'gallery_id' => ['type' => 'fk', 'table' => 'gallery', 'label' => 'Album / Category'],
                    'src'        => ['type' => 'image', 'required' => true, 'label' => 'Image'],
                    'alt'        => ['type' => 'text', 'label' => 'Alt text', 'required' => true],
                    'size'       => ['type' => 'select', 'options' => ['' => 'Normal', 'tall' => 'Tall', 'wide' => 'Wide']],
                    'active'     => ['type' => 'checkbox', 'default' => 1],
                    'sort_order' => ['type' => 'number', 'default' => 0],
                ],
            ],
            'gallery' => [
                'label'   => 'Gallery Albums',
                'table'   => 'gallery',
                'icon'    => '📁',
                'hidden'  => true,
                'columns' => ['name'],
                'fields'  => ['name' => ['type' => 'text', 'required' => true]],
            ],
            'testimonials' => [
                'label'   => 'Testimonials',
                'table'   => 'testimonials',
                'icon'    => '⭐',
                'order'   => 'sort_order, id',
                'columns' => ['client_name', 'location', 'rating', 'approved'],
                'fields'  => [
                    'client_name' => ['type' => 'text', 'required' => true],
                    'location'    => ['type' => 'text'],
                    'review'      => ['type' => 'textarea', 'required' => true],
                    'rating'      => ['type' => 'select', 'options' => ['5' => '★★★★★', '4' => '★★★★', '3' => '★★★', '2' => '★★', '1' => '★'], 'default' => '5'],
                    'photo'       => ['type' => 'image'],
                    'date'        => ['type' => 'date'],
                    'approved'    => ['type' => 'checkbox', 'default' => 1],
                    'sort_order'  => ['type' => 'number', 'default' => 0],
                ],
            ],
            'team_members' => [
                'label'   => 'Team',
                'table'   => 'team_members',
                'icon'    => '👥',
                'order'   => 'sort_order, id',
                'columns' => ['name', 'position', 'active'],
                'fields'  => [
                    'name'       => ['type' => 'text', 'required' => true],
                    'position'   => ['type' => 'text', 'required' => true],
                    'bio'        => ['type' => 'textarea'],
                    'photo'      => ['type' => 'image'],
                    'socials'    => ['type' => 'json', 'help' => 'e.g. {"instagram":"https://...","facebook":"https://..."}'],
                    'active'     => ['type' => 'checkbox', 'default' => 1],
                    'sort_order' => ['type' => 'number', 'default' => 0],
                ],
            ],
            'blogs' => [
                'label'   => 'Blog',
                'table'   => 'blogs',
                'icon'    => '📝',
                'order'   => 'published_at DESC',
                'columns' => ['title', 'status', 'published_at'],
                'fields'  => [
                    'title'            => ['type' => 'text', 'required' => true],
                    'slug'             => ['type' => 'text', 'required' => true],
                    'category_id'      => ['type' => 'fk', 'table' => 'blog_categories', 'label' => 'Category'],
                    'excerpt'          => ['type' => 'textarea'],
                    'body'             => ['type' => 'richtext', 'required' => true],
                    'image'            => ['type' => 'image', 'label' => 'Featured image'],
                    'tags'             => ['type' => 'json', 'shape' => 'list', 'help' => 'One tag per line, e.g. wellness'],
                    'status'           => ['type' => 'select', 'options' => ['draft' => 'Draft', 'published' => 'Published'], 'default' => 'draft'],
                    'published_at'     => ['type' => 'datetime', 'help' => 'Future date = scheduled publishing'],
                    'meta_title'       => ['type' => 'text', 'help' => 'SEO title (optional)'],
                    'meta_description' => ['type' => 'textarea', 'help' => 'SEO description (optional)'],
                ],
            ],
            'blog_categories' => [
                'label'   => 'Blog Categories',
                'table'   => 'blog_categories',
                'icon'    => '🏷️',
                'hidden'  => true,
                'columns' => ['name'],
                'fields'  => ['name' => ['type' => 'text', 'required' => true]],
            ],
            'bookings' => [
                'label'     => 'Bookings',
                'table'     => 'bookings',
                'icon'      => '💳',
                'order'     => 'created_at DESC, id DESC',
                'canCreate' => false,
                'columns'   => ['reference', 'name', 'item_name', 'slot_date', 'amount', 'provider', 'status', 'created_at'],
                'fields'    => [
                    'reference'       => ['type' => 'text', 'readonly' => true],
                    'name'            => ['type' => 'text', 'required' => true],
                    'email'           => ['type' => 'text', 'required' => true],
                    'phone'           => ['type' => 'text'],
                    'item_type'       => ['type' => 'select', 'options' => ['treatment' => 'Treatment', 'package' => 'Package']],
                    'item_name'       => ['type' => 'text', 'required' => true, 'label' => 'Treatment / package'],
                    'room_id'         => ['type' => 'fk', 'table' => 'rooms', 'label' => 'Room'],
                    'slot_date'       => ['type' => 'date', 'label' => 'Booking date'],
                    'slot_time'       => ['type' => 'time', 'label' => 'Booking time'],
                    'preferred_date'  => ['type' => 'text', 'help' => 'Legacy free-text date (older bookings)'],
                    'notes'           => ['type' => 'textarea'],
                    'amount'          => ['type' => 'text', 'readonly' => true, 'label' => 'Deposit (USD)'],
                    'provider'        => ['type' => 'text', 'readonly' => true, 'label' => 'Paid via'],
                    'provider_ref'    => ['type' => 'text', 'readonly' => true, 'label' => 'Gateway reference'],
                    'status'          => ['type' => 'select', 'options' => ['pending' => 'Pending', 'paid' => 'Paid', 'failed' => 'Failed', 'cancelled' => 'Cancelled'], 'default' => 'pending'],
                    'gateway_message' => ['type' => 'text', 'readonly' => true],
                ],
            ],
            'rooms' => [
                'label'    => 'Rooms',
                'table'    => 'rooms',
                'icon'     => '🚪',
                'order'    => 'sort_order, id',
                'template' => true, // enable "start from an existing room" + Duplicate
                'columns'  => ['name', 'slug', 'active'],
                'fields'   => [
                    'name'        => ['type' => 'text', 'required' => true],
                    'slug'        => ['type' => 'text', 'required' => true, 'help' => 'URL identifier, e.g. ocean-room'],
                    'description' => ['type' => 'textarea'],
                    'image'       => ['type' => 'image'],
                    'active'      => ['type' => 'checkbox', 'label' => 'Bookable', 'default' => 1],
                    'sort_order'  => ['type' => 'number', 'default' => 0],
                ],
            ],
            'availability_rules' => [
                'label'   => 'Availability',
                'table'   => 'availability_rules',
                'icon'    => '📅',
                'order'   => 'weekday, start_time',
                'columns' => ['weekday', 'start_time', 'end_time', 'active'],
                'fields'  => [
                    'weekday'    => ['type' => 'select', 'required' => true, 'options' => [
                        '0' => 'Sunday', '1' => 'Monday', '2' => 'Tuesday', '3' => 'Wednesday',
                        '4' => 'Thursday', '5' => 'Friday', '6' => 'Saturday',
                    ]],
                    'start_time' => ['type' => 'time', 'required' => true, 'help' => 'Opening time for this window'],
                    'end_time'   => ['type' => 'time', 'required' => true, 'help' => 'Closing time for this window'],
                    'active'     => ['type' => 'checkbox', 'default' => 1],
                ],
            ],
            'blackout_dates' => [
                'label'   => 'Blackout Dates',
                'table'   => 'blackout_dates',
                'icon'    => '🚫',
                'order'   => 'date',
                'columns' => ['date', 'room_id', 'reason'],
                'fields'  => [
                    'date'    => ['type' => 'date', 'required' => true],
                    'room_id' => ['type' => 'fk', 'table' => 'rooms', 'label' => 'Room', 'help' => 'Leave blank to close the whole spa that day'],
                    'reason'  => ['type' => 'text', 'help' => 'Shown to staff only, e.g. Public holiday'],
                ],
            ],
            'stay_blackouts' => [
                'label'   => 'Guest House Blackouts',
                'table'   => 'stay_blackouts',
                'icon'    => '🛑',
                'order'   => 'date',
                'columns' => ['date', 'unit_id', 'reason'],
                'fields'  => [
                    'date'    => ['type' => 'date', 'required' => true, 'help' => 'A night the unit is closed to bookings.'],
                    'unit_id' => ['type' => 'fk', 'table' => 'guesthouse_units', 'label' => 'Unit', 'help' => 'Leave blank to close every unit that night'],
                    'reason'  => ['type' => 'text', 'help' => 'Shown to staff only, e.g. Maintenance, Owner stay'],
                ],
            ],
            'faqs' => [
                'label'   => 'FAQs',
                'table'   => 'faqs',
                'icon'    => '❓',
                'order'   => 'sort_order, id',
                'columns' => ['question', 'active'],
                'fields'  => [
                    'question'   => ['type' => 'text', 'required' => true],
                    'answer'     => ['type' => 'textarea', 'required' => true],
                    'active'     => ['type' => 'checkbox', 'default' => 1],
                    'sort_order' => ['type' => 'number', 'default' => 0],
                ],
            ],
            'pages' => [
                'label'         => 'Pages',
                'table'         => 'pages',
                'icon'          => '📄',
                'template'      => true, // enable "start from an existing page" + Duplicate
                'templateLabel' => 'title', // picker/duplicate label column (default is 'name')
                'columns'       => ['slug', 'title', 'active'],
                // Sections mirror what a visitor scrolls through on the rendered
                // page (frontend Page.tsx uses the About template), so the form
                // reads top-to-bottom in the same order as the result.
                'groups'        => [
                    'banner'  => ['label' => 'The banner', 'hint' => 'The green header across the top of the page.'],
                    'content' => ['label' => 'The page content', 'hint' => 'Everything below the banner.'],
                ],
                'fields'  => [
                    'title'            => ['type' => 'text', 'required' => true, 'group' => 'banner'],
                    'subtitle'         => ['type' => 'text', 'label' => 'Lead', 'group' => 'banner', 'help' => 'One line under the title. Optional.'],
                    'image'            => ['type' => 'image', 'label' => 'Photo', 'group' => 'banner', 'help' => 'Tints the banner background, and appears in the page body unless you turn that off below. Optional.'],
                    'image_layout'     => ['type' => 'select', 'label' => 'Photo sits', 'group' => 'content', 'showWhen' => 'image', 'row' => 'photo', 'options' => ['' => 'Left of the text', 'right' => 'Right of the text', 'top' => 'Above the text', 'banner' => 'In the banner only']],
                    'image_size'       => ['type' => 'select', 'label' => 'Photo size', 'group' => 'content', 'showWhen' => 'image', 'row' => 'photo', 'options' => ['' => 'Medium', 'small' => 'Small', 'large' => 'Large']],
                    'body'             => ['type' => 'richtext', 'required' => true, 'label' => 'Text', 'group' => 'content'],
                    'slug'             => ['type' => 'text', 'required' => true, 'advanced' => true, 'autoFrom' => 'title', 'label' => 'Web address', 'help' => 'The page lives at /pages/<slug> and joins the site menu while active (privacy and terms stay footer-only). Fills itself in from the title.'],
                    'meta_title'       => ['type' => 'text', 'advanced' => true, 'label' => 'Search result title', 'help' => 'Falls back to the page title when blank.'],
                    'meta_description' => ['type' => 'textarea', 'advanced' => true, 'label' => 'Search result description'],
                    'active'           => ['type' => 'checkbox', 'default' => 1, 'bar' => true, 'label' => 'Live on the site'],
                ],
            ],
            'guesthouse' => [
                'label'     => 'Guest House',
                'table'     => 'guesthouse',
                'icon'      => '🏝️',
                'columns'   => ['title', 'active'],
                'canCreate' => false, // a single shared intro — edit the one row
                'canDelete' => false,
                'fields'    => [
                    'title'       => ['type' => 'text', 'required' => true, 'label' => 'Heading', 'help' => 'Shown above the list of units.'],
                    'subtitle'    => ['type' => 'text', 'label' => 'Tagline', 'help' => 'One line under the heading in the banner. Optional.'],
                    'image'       => ['type' => 'image', 'label' => 'Hero photo', 'help' => 'Banner background. Falls back to the first unit\'s photo. Optional.'],
                    'gallery'     => ['type' => 'json', 'shape' => 'imageList', 'label' => 'General photos', 'rows' => 6, 'help' => 'Optional extra photos of the property/grounds shared by every unit.'],
                    'description' => ['type' => 'richtext', 'required' => true, 'label' => 'Intro text'],
                    'active'      => ['type' => 'checkbox', 'label' => 'Show on the site', 'default' => 1],
                ],
            ],
            'guesthouse_units' => [
                'label'         => 'Guest House Units',
                'table'         => 'guesthouse_units',
                'icon'          => '🛏️',
                'order'         => 'sort_order, id',
                'template'      => true, // enable "start from an existing unit" + Duplicate
                'columns'       => ['name', 'price_per_night', 'active'],
                'groups'        => [
                    'listing' => ['label' => 'The listing', 'hint' => 'Photos and write-up shown on the page.'],
                    'details' => ['label' => 'Specs & pricing', 'hint' => 'Used for the specs and each unit\'s own booking calendar.'],
                ],
                'fields'        => [
                    'name'            => ['type' => 'text', 'required' => true, 'label' => 'Unit name', 'group' => 'listing', 'help' => 'e.g. "Garden Studio" or "Ocean View Apartment".'],
                    'subtitle'        => ['type' => 'text', 'label' => 'Tagline', 'group' => 'listing', 'help' => 'One line shown under the unit name. Optional.'],
                    'image'           => ['type' => 'image', 'label' => 'Hero photo', 'group' => 'listing', 'help' => 'Falls back to the first gallery photo. Optional.'],
                    'gallery'         => ['type' => 'json', 'shape' => 'imageList', 'label' => 'Photo gallery', 'group' => 'listing', 'rows' => 6, 'help' => 'The photos shown for this unit. Use "+ Add photo" to upload more.'],
                    'description'     => ['type' => 'richtext', 'required' => true, 'label' => 'Description', 'group' => 'listing'],
                    'amenities'       => ['type' => 'json', 'label' => "What's included", 'group' => 'listing', 'rows' => 6, 'help' => 'A list of amenities, e.g. "Full kitchen".'],
                    'price_per_night' => ['type' => 'number', 'required' => true, 'label' => 'Price per night (USD)', 'group' => 'details'],
                    'min_nights'      => ['type' => 'number', 'label' => 'Minimum nights', 'default' => 1, 'group' => 'details', 'row' => 'nums'],
                    'max_guests'      => ['type' => 'number', 'label' => 'Sleeps (max guests)', 'default' => 1, 'group' => 'details', 'row' => 'nums'],
                    'bedrooms'        => ['type' => 'number', 'label' => 'Bedrooms', 'default' => 1, 'group' => 'details', 'row' => 'rooms'],
                    'bathrooms'       => ['type' => 'number', 'label' => 'Bathrooms', 'default' => 1, 'group' => 'details', 'row' => 'rooms'],
                    'active'          => ['type' => 'checkbox', 'label' => 'Bookable', 'default' => 1, 'group' => 'details'],
                    'sort_order'      => ['type' => 'number', 'label' => 'Sort order', 'default' => 0, 'group' => 'details'],
                ],
            ],
            'homepage_sections' => [
                'label'   => 'Homepage',
                'table'   => 'homepage_sections',
                'icon'    => '🏠',
                'columns' => ['section', 'active'],
                'canCreate' => false,
                'canDelete' => false,
                'fields'  => [
                    'section' => ['type' => 'text', 'readonly' => true],
                    'content' => ['type' => 'json', 'required' => true, 'rows' => 16, 'help' => 'Structured content for this homepage section'],
                    'active'  => ['type' => 'checkbox', 'default' => 1],
                ],
            ],
            'users' => [
                'label'   => 'Users',
                'table'   => 'users',
                'icon'    => '🔐',
                'columns' => ['name', 'email', 'active'],
                'fields'  => [
                    'name'          => ['type' => 'text', 'required' => true],
                    'email'         => ['type' => 'text', 'required' => true],
                    'password_hash' => ['type' => 'password', 'label' => 'Password', 'help' => 'Leave blank to keep the current password'],
                    'role_id'       => ['type' => 'fk', 'table' => 'roles', 'label' => 'Role', 'default' => 1],
                    'active'        => ['type' => 'checkbox', 'default' => 1],
                ],
            ],
        ];
    }

    /** @return array<string, mixed>|null */
    public static function get(string $key): ?array
    {
        return self::all()[$key] ?? null;
    }
}
