<?php

namespace Config;

use CodeIgniter\Config\BaseConfig;

/**
 * Single source of truth for every "small fixed set of options" in the
 * schema that's stored as a plain VARCHAR rather than a DB ENUM (booking
 * status/source, room status, folio line-item category, payment method,
 * guest ID type, staff role). Views build dropdowns/badges from these
 * arrays instead of hard-coding <option> lists, and models validate
 * against them — so adding a new value (e.g. Phase 3's `pending_deposit`
 * booking status) is a one-line change here, never a migration or a
 * template edit scattered across views.
 */
class Lookups extends BaseConfig
{
    /**
     * value => ['label' => ..., 'badge' => Bootstrap color class suffix]
     */
    public array $bookingStatuses = [
        'pending_deposit' => ['label' => 'Pending Deposit', 'badge' => 'warning'],
        'confirmed'        => ['label' => 'Confirmed', 'badge' => 'primary'],
        'checked_in'       => ['label' => 'Checked In', 'badge' => 'success'],
        'checked_out'      => ['label' => 'Checked Out', 'badge' => 'secondary'],
        'cancelled'        => ['label' => 'Cancelled', 'badge' => 'danger'],
        'no_show'          => ['label' => 'No Show', 'badge' => 'dark'],
    ];

    public array $bookingSources = [
        'walk_in'   => ['label' => 'Walk-in'],
        'phone'     => ['label' => 'Phone'],
        'online'    => ['label' => 'Online'],
        'corporate' => ['label' => 'Corporate'],
        'group'     => ['label' => 'Group Booking'],
    ];

    public array $roomStatuses = [
        'clean'           => ['label' => 'Clean', 'badge' => 'success'],
        'dirty'           => ['label' => 'Dirty', 'badge' => 'warning'],
        'occupied'        => ['label' => 'Occupied', 'badge' => 'primary'],
        'out_of_service'  => ['label' => 'Out of Service', 'badge' => 'danger'],
    ];

    /**
     * Phase 1 wrote room_charge/other. Phase 2 adds restaurant/event —
     * still just new strings, no ALTER TABLE, per the Phase 1 design note.
     */
    public array $folioCategories = [
        'room_charge' => ['label' => 'Room Charge'],
        'restaurant'  => ['label' => 'Restaurant'],
        'event'       => ['label' => 'Event'],
        'other'       => ['label' => 'Other'],
    ];

    /**
     * Services/Extras catalog (New Booking wizard's Add Services step) —
     * see CreateHotelServicesTable's doc comment.
     */
    public array $serviceCategories = [
        'meal'      => ['label' => 'Meal', 'icon' => 'bi-cup-hot'],
        'transport' => ['label' => 'Transport', 'icon' => 'bi-car-front'],
        'equipment' => ['label' => 'Equipment', 'icon' => 'bi-box-seam'],
        'laundry'   => ['label' => 'Laundry', 'icon' => 'bi-basket'],
        'other'     => ['label' => 'Other', 'icon' => 'bi-plus-circle'],
    ];

    public array $serviceUnits = [
        'flat'               => 'Flat rate',
        'per_person'         => 'Per person',
        'per_person_per_day' => 'Per person / day',
        'per_night'          => 'Per night',
        'one_way'            => 'One way',
        'per_load'           => 'Per load',
    ];

    public array $restaurantReservationStatuses = [
        'booked'    => ['label' => 'Booked', 'badge' => 'primary'],
        'seated'    => ['label' => 'Seated', 'badge' => 'success'],
        'completed' => ['label' => 'Completed', 'badge' => 'secondary'],
        'no_show'   => ['label' => 'No Show', 'badge' => 'dark'],
        'cancelled' => ['label' => 'Cancelled', 'badge' => 'danger'],
    ];

    public array $eventStatuses = [
        'inquiry'   => ['label' => 'Inquiry', 'badge' => 'secondary'],
        'confirmed' => ['label' => 'Confirmed', 'badge' => 'primary'],
        'completed' => ['label' => 'Completed', 'badge' => 'success'],
        'cancelled' => ['label' => 'Cancelled', 'badge' => 'danger'],
    ];

    /** Extra questions staff/organizers can add to an event's public registration form — see EventRegistrationFieldModel. */
    public array $eventRegistrationFieldTypes = [
        'text'     => ['label' => 'Short Text'],
        'textarea' => ['label' => 'Long Text'],
        'select'   => ['label' => 'Dropdown (single choice)'],
        'radio'    => ['label' => 'Radio (single choice)'],
        'checkbox' => ['label' => 'Checkboxes (multiple choice)'],
        'number'   => ['label' => 'Number'],
        'date'     => ['label' => 'Date'],
    ];

    /** field_types whose form control needs a list of choices (options column) rather than free entry. */
    public function eventRegistrationFieldTypesRequiringOptions(): array
    {
        return ['select', 'radio', 'checkbox'];
    }

    /** Employment documents attached to a staff profile — see CreateStaffDocumentsTable. */
    public array $staffDocumentTypes = [
        'id_card'     => ['label' => 'ID Card'],
        'passport'    => ['label' => 'Passport'],
        'contract'    => ['label' => 'Employment Contract'],
        'certificate' => ['label' => 'Certificate'],
        'other'       => ['label' => 'Other'],
    ];

    /** payslip_line_items.type — see CreatePayslipLineItemsTable. */
    public array $payslipLineItemTypes = [
        'allowance' => ['label' => 'Allowance', 'badge' => 'success'],
        'deduction' => ['label' => 'Deduction', 'badge' => 'danger'],
    ];

    /** payroll_runs.status — see CreatePayrollRunsTable. */
    public array $payrollRunStatuses = [
        'draft'     => ['label' => 'Draft', 'badge' => 'secondary'],
        'finalized' => ['label' => 'Finalized', 'badge' => 'info'],
        'paid'      => ['label' => 'Paid', 'badge' => 'success'],
    ];

    public array $posOrderStatuses = [
        'open'           => ['label' => 'Open', 'badge' => 'secondary'],
        'sent_to_kitchen' => ['label' => 'Sent to Kitchen', 'badge' => 'warning'],
        'served'         => ['label' => 'Served', 'badge' => 'primary'],
        'paid'           => ['label' => 'Paid', 'badge' => 'success'],
    ];

    public array $posOrderTypes = [
        'dine_in'  => ['label' => 'Dine-in'],
        'takeaway' => ['label' => 'Takeaway'],
    ];

    /**
     * Per-message-type channel choice (Phase 3): not every hotel wants to
     * pay for both WhatsApp and SMS for every message type.
     */
    public array $messagingChannels = [
        'whatsapp' => ['label' => 'WhatsApp only'],
        'sms'      => ['label' => 'SMS only'],
        'both'     => ['label' => 'Both'],
    ];

    public array $paymentAttemptStatuses = [
        'pending' => ['label' => 'Pending', 'badge' => 'secondary'],
        'success' => ['label' => 'Success', 'badge' => 'success'],
        'failed'  => ['label' => 'Failed', 'badge' => 'danger'],
    ];

    public array $paymentMethods = [
        'cash'           => ['label' => 'Cash'],
        'mobile_money'   => ['label' => 'Mobile Money'],
        'card'           => ['label' => 'Card'],
        'bank_transfer'  => ['label' => 'Bank Transfer'],
        // Phase 3 — written by the Hubtel webhook only, never picked from
        // the manual "record payment" dropdown (front desk still uses the
        // four methods above for cash/offline payments).
        'hubtel_momo'    => ['label' => 'Hubtel Mobile Money'],
        'hubtel_card'    => ['label' => 'Hubtel Card'],
    ];

    public array $guestIdTypes = [
        'ghana_card' => ['label' => 'Ghana Card'],
        'passport'   => ['label' => 'Passport'],
        'other'      => ['label' => 'Other'],
    ];

    /**
     * Free-form guest tag for the Guest CRM's stat cards/tabs (a user-
     * supplied mockup showed VIP/Business/Leisure) — same "plain string,
     * validated here" convention as every other lookup in this class.
     * Null/untagged is valid and common; this is a manager-applied label,
     * not something auto-computed.
     */
    public array $guestSegments = [
        'vip'      => ['label' => 'VIP', 'badge' => 'warning'],
        'business' => ['label' => 'Business', 'badge' => 'info'],
        'leisure'  => ['label' => 'Leisure', 'badge' => 'secondary'],
    ];

    /**
     * Structured guest stay preferences — bed type/dietary/seating/
     * allergies stay free text on guest_preferences since they genuinely
     * vary too much to enumerate; this is the one part of it that is a
     * real fixed set.
     */
    public array $smokingPreferences = [
        'non_smoking' => ['label' => 'Non-Smoking'],
        'smoking'     => ['label' => 'Smoking'],
    ];

    /**
     * Executive Dining club tiers — a separate, staff-enrolled membership
     * from the transactional loyalty programme above. Benefit text per
     * tier is manager-editable free text in Settings (dining.*_benefits),
     * not enumerated here, since what a hotel actually offers varies too
     * much to model as fixed rules.
     */
    public array $diningMembershipTiers = [
        'silver'   => ['label' => 'Silver', 'badge' => 'secondary'],
        'gold'     => ['label' => 'Gold', 'badge' => 'warning text-dark'],
        'platinum' => ['label' => 'Platinum', 'badge' => 'dark'],
    ];

    public array $diningMembershipStatuses = [
        'active'    => ['label' => 'Active', 'badge' => 'success'],
        'expired'   => ['label' => 'Expired', 'badge' => 'secondary'],
        'cancelled' => ['label' => 'Cancelled', 'badge' => 'danger'],
    ];

    /** Full workforce management (Phase 4) — every role that can be assigned a shift sees these. */
    public array $shiftBlocks = [
        'morning'   => ['label' => 'Morning', 'time' => '6:00am – 2:00pm', 'badge' => 'info'],
        'afternoon' => ['label' => 'Afternoon', 'time' => '2:00pm – 10:00pm', 'badge' => 'warning text-dark'],
        'night'     => ['label' => 'Night', 'time' => '10:00pm – 6:00am', 'badge' => 'dark'],
    ];

    public array $shiftStatuses = [
        'scheduled' => ['label' => 'Scheduled', 'badge' => 'secondary'],
        'completed' => ['label' => 'Completed', 'badge' => 'success'],
        'no_show'   => ['label' => 'No-Show', 'badge' => 'danger'],
        'cancelled' => ['label' => 'Cancelled', 'badge' => 'dark'],
    ];

    /** Shared by shift swap requests and time-off requests — same three-state approval workflow. */
    public array $requestStatuses = [
        'pending'  => ['label' => 'Pending', 'badge' => 'warning text-dark'],
        'approved' => ['label' => 'Approved', 'badge' => 'success'],
        'denied'   => ['label' => 'Denied', 'badge' => 'danger'],
    ];

    // --- Housekeeping / Maintenance / Inventory — Phase 4 modules, built
    // for real once user-supplied mockups asked for them (previously
    // disabled "Soon" nav items).

    public array $housekeepingTaskTypes = [
        'standard_cleaning' => ['label' => 'Standard Cleaning'],
        'deep_cleaning'      => ['label' => 'Deep Cleaning'],
        'turn_down'          => ['label' => 'Turn Down Service'],
        'vacate_cleaning'    => ['label' => 'Vacate Cleaning'],
    ];

    public array $taskPriorities = [
        'low'    => ['label' => 'Low', 'badge' => 'secondary'],
        'medium' => ['label' => 'Medium', 'badge' => 'warning'],
        'high'   => ['label' => 'High', 'badge' => 'danger'],
    ];

    public array $housekeepingTaskStatuses = [
        'not_started' => ['label' => 'Not Started', 'badge' => 'secondary'],
        'in_progress' => ['label' => 'In Progress', 'badge' => 'warning'],
        'completed'   => ['label' => 'Completed', 'badge' => 'success'],
    ];

    public array $workOrderStatuses = [
        'open'        => ['label' => 'Open', 'badge' => 'primary'],
        'in_progress' => ['label' => 'In Progress', 'badge' => 'warning'],
        'completed'   => ['label' => 'Completed', 'badge' => 'success'],
    ];

    /**
     * Complaint & service recovery tracking — open through the whole
     * organization (any department can log or be assigned one), not just
     * front desk/housekeeping like the modules above.
     */
    public array $complaintCategories = [
        'room'         => ['label' => 'Room'],
        'fnb'          => ['label' => 'F&B'],
        'housekeeping' => ['label' => 'Housekeeping'],
        'maintenance'  => ['label' => 'Maintenance'],
        'billing'      => ['label' => 'Billing'],
        'other'        => ['label' => 'Other'],
    ];

    public array $complaintStatuses = [
        'open'        => ['label' => 'Open', 'badge' => 'danger'],
        'assigned'    => ['label' => 'Assigned', 'badge' => 'warning'],
        'resolved'    => ['label' => 'Resolved', 'badge' => 'success'],
        'followed_up' => ['label' => 'Followed Up', 'badge' => 'secondary'],
    ];

    public array $inventoryCategories = [
        'linen'     => ['label' => 'Linen'],
        'amenities' => ['label' => 'Amenities'],
        'fnb'       => ['label' => 'F&B'],
        'cleaning'  => ['label' => 'Cleaning Supplies'],
        'other'     => ['label' => 'Other'],
    ];

    /**
     * The hotel's own operating costs — distinct from guest-facing
     * revenue, which already lives in $folioCategories. Feeds the
     * Profit & Loss report alongside FolioLineItemModel's revenue totals.
     */
    public array $expenseCategories = [
        'utilities'   => ['label' => 'Utilities'],
        'payroll'     => ['label' => 'Payroll / Salaries'],
        'supplies'    => ['label' => 'Supplies'],
        'maintenance' => ['label' => 'Repairs & Maintenance'],
        'marketing'   => ['label' => 'Marketing'],
        'other'       => ['label' => 'Other'],
    ];

    /**
     * Module 9: Phase 1 shipped manager/front_desk. Phase 2 adds fnb
     * (table reservations, POS, kitchen display, events) — housekeeping/
     * accounts still wait for their own phase.
     */
    public array $staffRoles = [
        'manager'      => ['label' => 'Manager', 'badge' => 'primary'],
        'front_desk'   => ['label' => 'Front Desk', 'badge' => 'info'],
        'fnb'          => ['label' => 'F&B', 'badge' => 'success'],
        'housekeeping' => ['label' => 'Housekeeping', 'badge' => 'warning text-dark'],
        'accounts'     => ['label' => 'Accounts', 'badge' => 'secondary'],
    ];

    /**
     * Nav sections a role can have visible — see RoleManagementController
     * and the CreateRolePermissionsTable migration's doc comment for what
     * this does and doesn't control. `roles` here is the set of roles
     * that can ever see this module at all (mirrors the $isFrontDesk/
     * $isFnb/$isManager route-group boundaries in layouts/main.php and
     * Routes.php) — a role not listed here never gets a toggle for it,
     * since no amount of nav-visibility toggling can show them a route
     * they're not server-side permitted to reach anyway.
     */
    public array $permissionModules = [
        'dashboard'       => ['label' => 'Dashboard', 'roles' => ['manager', 'front_desk']],
        'shifts'          => ['label' => 'Shift Schedule', 'roles' => ['manager', 'front_desk', 'fnb', 'housekeeping', 'accounts']],
        'reservations'    => ['label' => 'Reservations', 'roles' => ['manager', 'front_desk']],
        'front_desk_ops'  => ['label' => 'Front Desk (Check-In/Out, Folios, Payments)', 'roles' => ['manager', 'front_desk']],
        'guests'          => ['label' => 'Guests', 'roles' => ['manager', 'front_desk']],
        'complaints'      => ['label' => 'Service Recovery', 'roles' => ['manager', 'front_desk', 'fnb']],
        'rooms'           => ['label' => 'Rooms', 'roles' => ['manager', 'front_desk', 'housekeeping']],
        'housekeeping'    => ['label' => 'Housekeeping', 'roles' => ['manager', 'front_desk', 'housekeeping']],
        'maintenance'     => ['label' => 'Maintenance', 'roles' => ['manager', 'front_desk', 'housekeeping']],
        'restaurant'      => ['label' => 'Restaurant (F&B)', 'roles' => ['manager', 'fnb']],
        'events'          => ['label' => 'Events', 'roles' => ['manager', 'fnb']],
        'billing_finance' => ['label' => 'Billing & Finance', 'roles' => ['manager', 'accounts']],
        'reports'         => ['label' => 'Reports & Analytics', 'roles' => ['manager', 'accounts']],
        'corporate_accounts' => ['label' => 'Corporate Accounts', 'roles' => ['manager', 'front_desk', 'accounts']],
        'invoicing'       => ['label' => 'Invoicing (Folios & Payments)', 'roles' => ['manager', 'front_desk', 'accounts']],
        'ai_modules'      => ['label' => 'AI Modules', 'roles' => ['manager']],
        'staff'           => ['label' => 'Staff', 'roles' => ['manager']],
        'inventory'       => ['label' => 'Inventory', 'roles' => ['manager']],
        'communication'   => ['label' => 'Communication', 'roles' => ['manager']],
        'campaigns'       => ['label' => 'Email Campaigns', 'roles' => ['manager']],
        'activity_log'    => ['label' => 'Activity Log', 'roles' => ['manager']],
        'rate_plans'      => ['label' => 'Rate Plans', 'roles' => ['manager', 'accounts']],
        'expenses'        => ['label' => 'Expenses', 'roles' => ['manager', 'accounts']],
        'services'        => ['label' => 'Services & Extras', 'roles' => ['manager']],
        'settings'        => ['label' => 'Settings', 'roles' => ['manager']],
        // Manager-only, not accounts — salary data is more sensitive than
        // routine billing (see the payroll build plan).
        'payroll'         => ['label' => 'Payroll & Salaries', 'roles' => ['manager']],
        'ai_assistant'    => ['label' => 'Staff Booking Assistant', 'roles' => ['manager', 'front_desk']],
        'ai_alerts'        => ['label' => 'AI Alerts', 'roles' => ['manager']],
        'guest_message_drafts' => ['label' => 'Guest Message Drafts', 'roles' => ['manager']],
        'concierge'       => ['label' => 'WhatsApp Concierge', 'roles' => ['manager', 'front_desk']],
    ];

    // --- Super Admin / control-plane (platform billing hotels for their
    // PMS subscription) — everything below validates control-DB tables,
    // never a tenant DB. Kept in this same class since the "small fixed
    // set of options, stored as VARCHAR, validated here" convention is
    // exactly the same reasoning, just on the other database.

    public array $adminRoles = [
        'super_admin' => ['label' => 'Super Admin'],
    ];

    public array $planBillingIntervals = [
        'monthly' => ['label' => 'Monthly'],
        'yearly'  => ['label' => 'Yearly'],
    ];

    public array $subscriptionStatuses = [
        'trial'     => ['label' => 'Trial', 'badge' => 'info'],
        'active'    => ['label' => 'Active', 'badge' => 'success'],
        'past_due'  => ['label' => 'Past Due', 'badge' => 'warning'],
        'cancelled' => ['label' => 'Cancelled', 'badge' => 'danger'],
    ];

    public array $invoiceStatuses = [
        'draft'   => ['label' => 'Draft', 'badge' => 'secondary'],
        'sent'    => ['label' => 'Sent', 'badge' => 'primary'],
        'paid'    => ['label' => 'Paid', 'badge' => 'success'],
        'overdue' => ['label' => 'Overdue', 'badge' => 'danger'],
        'void'    => ['label' => 'Void', 'badge' => 'dark'],
    ];

    public array $transactionTypes = [
        'charge' => ['label' => 'Charge'],
        'refund' => ['label' => 'Refund'],
    ];

    public array $transactionStatuses = [
        'pending' => ['label' => 'Pending', 'badge' => 'secondary'],
        'success' => ['label' => 'Success', 'badge' => 'success'],
        'failed'  => ['label' => 'Failed', 'badge' => 'danger'],
    ];

    public array $transactionMethods = [
        'hubtel_momo'   => ['label' => 'Hubtel Mobile Money'],
        'hubtel_card'   => ['label' => 'Hubtel Card'],
        'manual'        => ['label' => 'Manual'],
        'bank_transfer' => ['label' => 'Bank Transfer'],
    ];

    public function bookingStatusKeys(): array
    {
        return array_keys($this->bookingStatuses);
    }

    public function roomStatusKeys(): array
    {
        return array_keys($this->roomStatuses);
    }

    public function folioCategoryKeys(): array
    {
        return array_keys($this->folioCategories);
    }

    public function paymentMethodKeys(): array
    {
        return array_keys($this->paymentMethods);
    }

    /**
     * The subset staff can pick from a "record payment" dropdown —
     * excludes hubtel_momo/hubtel_card, which only the webhook ever writes.
     */
    public function manualPaymentMethods(): array
    {
        return array_filter($this->paymentMethods, static fn ($key) => ! str_starts_with($key, 'hubtel_'), ARRAY_FILTER_USE_KEY);
    }
}
