<?php
/**
 * Configurable salon commissions, tip allocation, local retail inventory,
 * low-stock monitoring, and Any Staff assignment strategies.
 */
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- This operational module reads and writes live plugin-owned scheduling, compensation, and inventory tables; identifiers use only the WordPress prefix and fixed suffixes.
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class YATOON_Salon_Operations {
    const SCHEMA_VERSION = '4.3.6';

    public static function init() {
        if ( ! self::available() ) {
            return;
        }
        self::install_schema();
        add_action( 'admin_menu', array( __CLASS__, 'add_menu' ), 26 );
        add_action( 'admin_post_yatoon_save_compensation', array( __CLASS__, 'save_compensation' ) );
        add_action( 'admin_post_yatoon_save_inventory_item', array( __CLASS__, 'save_inventory_item' ) );
        add_action( 'admin_post_yatoon_adjust_inventory', array( __CLASS__, 'adjust_inventory' ) );
        add_action( 'admin_post_yatoon_delete_inventory_item', array( __CLASS__, 'delete_inventory_item' ) );
        add_action( 'yatoon_booking_status_changed', array( __CLASS__, 'booking_status_changed' ), 110, 3 );
        add_action( 'yatoon_daily_health_snapshot', array( __CLASS__, 'record_low_stock_health' ), 20 );
    }

    private static function available() {
        return ( ! function_exists( 'yatoon_is_pro' ) || yatoon_is_pro() ) && is_dir( YATOON_PLUGIN_DIR . 'includes/pro' );
    }

    public static function install_schema() {
        if ( self::SCHEMA_VERSION === get_option( 'yatoon_salon_operations_schema_version', '' ) ) {
            return;
        }
        global $wpdb;
        require_once ABSPATH . 'wp-admin/includes/upgrade.php';
        $charset = $wpdb->get_charset_collate();
        dbDelta( "CREATE TABLE {$wpdb->prefix}yatoon_commission_rules (
            id bigint(20) NOT NULL AUTO_INCREMENT,
            staff_id bigint(20) NOT NULL DEFAULT 0,
            service_id bigint(20) NOT NULL DEFAULT 0,
            rate_type varchar(20) NOT NULL DEFAULT 'percentage',
            rate_value decimal(10,2) NOT NULL DEFAULT 0,
            tip_share_percent decimal(6,2) NOT NULL DEFAULT 0,
            rebook_days int(11) NOT NULL DEFAULT 0,
            updated_at datetime DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            UNIQUE KEY rule_scope (staff_id, service_id)
        ) {$charset};" );
        dbDelta( "CREATE TABLE {$wpdb->prefix}yatoon_commission_entries (
            id bigint(20) NOT NULL AUTO_INCREMENT,
            source_key varchar(100) NOT NULL,
            staff_id bigint(20) NOT NULL,
            service_commission decimal(12,2) NOT NULL DEFAULT 0,
            tip_amount decimal(12,2) NOT NULL DEFAULT 0,
            total_amount decimal(12,2) NOT NULL DEFAULT 0,
            details longtext DEFAULT NULL,
            calculated_at datetime DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            UNIQUE KEY source_staff (source_key, staff_id),
            KEY staff_id (staff_id),
            KEY calculated_at (calculated_at)
        ) {$charset};" );
        dbDelta( "CREATE TABLE {$wpdb->prefix}yatoon_inventory_items (
            id bigint(20) NOT NULL AUTO_INCREMENT,
            location_id bigint(20) NOT NULL DEFAULT 0,
            name varchar(255) NOT NULL,
            sku varchar(100) DEFAULT '',
            square_catalog_id varchar(255) DEFAULT '',
            quantity decimal(12,2) NOT NULL DEFAULT 0,
            low_stock_threshold decimal(12,2) NOT NULL DEFAULT 0,
            retail_price decimal(12,2) NOT NULL DEFAULT 0,
            unit_cost decimal(12,2) NOT NULL DEFAULT 0,
            is_active tinyint(1) NOT NULL DEFAULT 1,
            updated_at datetime DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            KEY sku (sku),
            KEY location_id (location_id),
            KEY stock_status (is_active, quantity)
        ) {$charset};" );
        dbDelta( "CREATE TABLE {$wpdb->prefix}yatoon_inventory_movements (
            id bigint(20) NOT NULL AUTO_INCREMENT,
            item_id bigint(20) NOT NULL,
            quantity_change decimal(12,2) NOT NULL DEFAULT 0,
            reason varchar(60) NOT NULL DEFAULT 'adjustment',
            reference varchar(255) DEFAULT '',
            actor_id bigint(20) DEFAULT NULL,
            created_at datetime DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            KEY item_id (item_id),
            KEY created_at (created_at)
        ) {$charset};" );
        add_option( 'yatoon_assignment_strategy', 'service_order' );
        add_option( 'yatoon_default_commission_type', 'percentage' );
        add_option( 'yatoon_default_commission_value', '0' );
        add_option( 'yatoon_tip_split_mode', 'assigned' );
        if ( YATOON_Schema_Verifier::tables_exist( array( 'yatoon_commission_rules', 'yatoon_commission_entries', 'yatoon_inventory_items', 'yatoon_inventory_movements' ) ) ) {
            update_option( 'yatoon_salon_operations_schema_version', self::SCHEMA_VERSION, false );
        }
    }

    public static function add_menu() {
        add_submenu_page(
            'yatoon-booking-system',
            __( 'Compensation & Inventory', 'yatoon-booking-system' ),
            __( 'Compensation & Stock', 'yatoon-booking-system' ),
            'manage_options',
            'yatoon-salon-operations',
            array( __CLASS__, 'render_admin' )
        );
    }

    /**
     * 4.6.1: nonce verification moved back inside this guard.
     *
     * Pro had split it into `require_admin()` plus a separate
     * `check_admin_referer()` at each of the four call sites. Two guards that
     * must both be remembered is one guard too many -- a new handler that
     * copies only the first line is a CSRF hole, and the split also made this
     * file impossible to diff against the Free build. One call, both checks.
     */
    private static function require_admin( $nonce_action ) {
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_die( esc_html__( 'Permission denied.', 'yatoon-booking-system' ) );
        }
        check_admin_referer( $nonce_action );
    }

    public static function save_compensation() {
        self::require_admin( 'yatoon_save_compensation' );
        $strategies = array( 'service_order', 'round_robin', 'least_loaded', 'preferred_staff', 'random' );
        $strategy = sanitize_key( wp_unslash( $_POST['assignment_strategy'] ?? 'service_order' ) );
        update_option( 'yatoon_assignment_strategy', in_array( $strategy, $strategies, true ) ? $strategy : 'service_order' );
        $types = array( 'percentage', 'fixed' );
        $default_type = sanitize_key( wp_unslash( $_POST['default_commission_type'] ?? 'percentage' ) );
        update_option( 'yatoon_default_commission_type', in_array( $default_type, $types, true ) ? $default_type : 'percentage' );
        update_option( 'yatoon_default_commission_value', max( 0, floatval( wp_unslash( $_POST['default_commission_value'] ?? 0 ) ) ) );
        $tip_modes = array( 'assigned', 'equal', 'service_revenue', 'custom' );
        $tip_mode = sanitize_key( wp_unslash( $_POST['tip_split_mode'] ?? 'assigned' ) );
        update_option( 'yatoon_tip_split_mode', in_array( $tip_mode, $tip_modes, true ) ? $tip_mode : 'assigned' );

        global $wpdb;
        $table = $wpdb->prefix . 'yatoon_commission_rules';
        $rules = (array) map_deep( wp_unslash( $_POST['rules'] ?? array() ), 'sanitize_text_field' );
        foreach ( $rules as $scope => $rule ) {
            $parts = explode( ':', sanitize_text_field( $scope ) );
            $staff_id = 'staff' === ( $parts[0] ?? '' ) ? absint( $parts[1] ?? 0 ) : 0;
            $service_id = 'service' === ( $parts[0] ?? '' ) ? absint( $parts[1] ?? 0 ) : 0;
            if ( ! $staff_id && ! $service_id ) {
                continue;
            }
            $rate_type = sanitize_key( wp_unslash( $rule['rate_type'] ?? 'percentage' ) );
            $data = array(
                'staff_id'          => $staff_id,
                'service_id'        => $service_id,
                'rate_type'         => in_array( $rate_type, $types, true ) ? $rate_type : 'percentage',
                'rate_value'        => max( 0, (float) ( $rule['rate_value'] ?? 0 ) ),
                'tip_share_percent' => min( 100, max( 0, (float) ( $rule['tip_share_percent'] ?? 0 ) ) ),
                'rebook_days'       => $service_id ? min( 730, max( 0, absint( $rule['rebook_days'] ?? 0 ) ) ) : 0,
                'updated_at'        => current_time( 'mysql' ),
            );
            $wpdb->replace( $table, $data, array( '%d', '%d', '%s', '%f', '%f', '%d', '%s' ) );
        }
        if ( class_exists( 'YATOON_Insights' ) ) {
            YATOON_Insights::audit( 'compensation_rules_saved', __( 'Compensation and assignment rules updated.', 'yatoon-booking-system' ) );
        }
        wp_safe_redirect( admin_url( 'admin.php?page=yatoon-salon-operations&saved=1' ) );
        exit;
    }

    public static function save_inventory_item() {
        self::require_admin( 'yatoon_save_inventory_item' );
        global $wpdb;
        $id = absint( wp_unslash( $_POST['item_id'] ?? 0 ) );
        $data = array(
            'location_id'        => absint( wp_unslash( $_POST['location_id'] ?? 0 ) ),
            'name'               => sanitize_text_field( wp_unslash( $_POST['name'] ?? '' ) ),
            'sku'                => sanitize_text_field( wp_unslash( $_POST['sku'] ?? '' ) ),
            'square_catalog_id'  => sanitize_text_field( wp_unslash( $_POST['square_catalog_id'] ?? '' ) ),
            'quantity'           => floatval( wp_unslash( $_POST['quantity'] ?? 0 ) ),
            'low_stock_threshold'=> max( 0, floatval( wp_unslash( $_POST['low_stock_threshold'] ?? 0 ) ) ),
            'retail_price'       => max( 0, floatval( wp_unslash( $_POST['retail_price'] ?? 0 ) ) ),
            'unit_cost'          => max( 0, floatval( wp_unslash( $_POST['unit_cost'] ?? 0 ) ) ),
            'is_active'          => isset( $_POST['is_active'] ) ? 1 : 0,
            'updated_at'         => current_time( 'mysql' ),
        );
        if ( '' === $data['name'] ) {
            wp_die( esc_html__( 'Item name is required.', 'yatoon-booking-system' ) );
        }
        if ( $id ) {
            $wpdb->update( $wpdb->prefix . 'yatoon_inventory_items', $data, array( 'id' => $id ) );
        } else {
            $wpdb->insert( $wpdb->prefix . 'yatoon_inventory_items', $data );
            $id = (int) $wpdb->insert_id;
        }
        if ( class_exists( 'YATOON_Insights' ) ) {
            YATOON_Insights::audit( 'inventory_item_saved', $data['name'], 'inventory_item', $id );
        }
        wp_safe_redirect( admin_url( 'admin.php?page=yatoon-salon-operations&tab=inventory&saved=1' ) );
        exit;
    }

    public static function adjust_inventory() {
        self::require_admin( 'yatoon_adjust_inventory' );
        global $wpdb;
        $item_id = absint( wp_unslash( $_POST['item_id'] ?? 0 ) );
        $change = floatval( wp_unslash( $_POST['quantity_change'] ?? 0 ) );
        if ( ! $item_id || 0.0 === $change ) {
            wp_safe_redirect( admin_url( 'admin.php?page=yatoon-salon-operations&tab=inventory' ) );
            exit;
        }
        $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}yatoon_inventory_items SET quantity=quantity+%f, updated_at=%s WHERE id=%d", $change, current_time( 'mysql' ), $item_id ) );
        $wpdb->insert( $wpdb->prefix . 'yatoon_inventory_movements', array(
            'item_id'         => $item_id,
            'quantity_change' => $change,
            'reason'          => sanitize_key( wp_unslash( $_POST['reason'] ?? 'adjustment' ) ),
            'reference'       => sanitize_text_field( wp_unslash( $_POST['reference'] ?? '' ) ),
            'actor_id'        => get_current_user_id(),
            'created_at'      => current_time( 'mysql' ),
        ) );
        if ( class_exists( 'YATOON_Insights' ) ) {
            YATOON_Insights::audit( 'inventory_adjusted', sprintf( 'Inventory adjusted by %s', $change ), 'inventory_item', $item_id );
        }
        wp_safe_redirect( admin_url( 'admin.php?page=yatoon-salon-operations&tab=inventory&adjusted=1' ) );
        exit;
    }

    public static function delete_inventory_item() {
        self::require_admin( 'yatoon_delete_inventory_item' );
        global $wpdb;
        $item_id = absint( wp_unslash( $_GET['item_id'] ?? 0 ) );
        $wpdb->delete( $wpdb->prefix . 'yatoon_inventory_items', array( 'id' => $item_id ), array( '%d' ) );
        if ( class_exists( 'YATOON_Insights' ) ) {
            YATOON_Insights::audit( 'inventory_item_deleted', __( 'Inventory item deleted.', 'yatoon-booking-system' ), 'inventory_item', $item_id );
        }
        wp_safe_redirect( admin_url( 'admin.php?page=yatoon-salon-operations&tab=inventory' ) );
        exit;
    }

    public static function booking_status_changed( $booking_id, $new_status, $old_status = '' ) {
        if ( 'completed' === strtolower( (string) $new_status ) ) {
            self::calculate_commission( $booking_id );
        }
    }

    public static function calculate_commission( $booking_id ) {
        global $wpdb;
        $booking = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}yatoon_bookings WHERE id=%d", $booking_id ) );
        if ( ! $booking ) {
            return;
        }
        $rows = $booking->group_booking_id
            ? $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}yatoon_bookings WHERE group_booking_id=%s", $booking->group_booking_id ) )
            : array( $booking );
        $source_key = $booking->group_booking_id ? 'group:' . sanitize_key( $booking->group_booking_id ) : 'booking:' . absint( $booking->id );
        $staff_totals = array();
        $tip_total = 0.0;
        foreach ( $rows as $row ) {
            $staff_id = absint( $row->staff_id );
            if ( ! $staff_id ) {
                continue;
            }
            $base = max( 0, (float) $row->total_price - (float) $row->tip_amount );
            $tip_total = max( $tip_total, (float) $row->tip_amount );
            $rule = self::commission_rule( $staff_id, absint( $row->service_id ) );
            $commission = 'fixed' === $rule['rate_type'] ? (float) $rule['rate_value'] : $base * (float) $rule['rate_value'] / 100;
            if ( ! isset( $staff_totals[ $staff_id ] ) ) {
                $staff_totals[ $staff_id ] = array( 'base' => 0.0, 'commission' => 0.0, 'tip_weight' => (float) $rule['tip_share_percent'], 'services' => array() );
            }
            $staff_totals[ $staff_id ]['base'] += $base;
            $staff_totals[ $staff_id ]['commission'] += $commission;
            $staff_totals[ $staff_id ]['services'][] = absint( $row->service_id );
        }
        $tip_mode = get_option( 'yatoon_tip_split_mode', 'assigned' );
        $weight_total = 0.0;
        foreach ( $staff_totals as $staff_id => &$totals ) {
            if ( 'service_revenue' === $tip_mode ) {
                $totals['tip_weight'] = $totals['base'];
            } elseif ( 'equal' === $tip_mode || ( 'assigned' === $tip_mode && count( $staff_totals ) > 1 ) ) {
                $totals['tip_weight'] = 1;
            } elseif ( 'assigned' === $tip_mode ) {
                $totals['tip_weight'] = 1;
            }
            $weight_total += max( 0, $totals['tip_weight'] );
        }
        unset( $totals );
        if ( $weight_total <= 0 && $staff_totals ) {
            $weight_total = count( $staff_totals );
            foreach ( $staff_totals as &$totals ) {
                $totals['tip_weight'] = 1;
            }
            unset( $totals );
        }
        foreach ( $staff_totals as $staff_id => $totals ) {
            $tip = $weight_total > 0 ? $tip_total * $totals['tip_weight'] / $weight_total : 0;
            $commission = round( $totals['commission'], 2 );
            $tip = round( $tip, 2 );
            $wpdb->replace( $wpdb->prefix . 'yatoon_commission_entries', array(
                'source_key'         => $source_key,
                'staff_id'           => $staff_id,
                'service_commission' => $commission,
                'tip_amount'         => $tip,
                'total_amount'       => $commission + $tip,
                'details'            => wp_json_encode( array( 'base' => $totals['base'], 'services' => $totals['services'], 'tip_mode' => $tip_mode ) ),
                'calculated_at'      => current_time( 'mysql' ),
            ) );
        }
    }

    private static function commission_rule( $staff_id, $service_id ) {
        global $wpdb;
        $table = $wpdb->prefix . 'yatoon_commission_rules';
        $rule = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE staff_id=%d AND service_id=%d LIMIT 1", $staff_id, $service_id ), ARRAY_A );
        if ( ! $rule ) {
            $rule = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE staff_id=%d AND service_id=0 LIMIT 1", $staff_id ), ARRAY_A );
        }
        if ( ! $rule ) {
            $rule = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$table} WHERE staff_id=0 AND service_id=%d LIMIT 1", $service_id ), ARRAY_A );
        }
        return $rule ?: array(
            'rate_type' => get_option( 'yatoon_default_commission_type', 'percentage' ),
            'rate_value' => (float) get_option( 'yatoon_default_commission_value', 0 ),
            'tip_share_percent' => 0,
        );
    }

    public static function rank_staff( array $staff, $service_id = 0, $start_at = '' ) {
        if ( count( $staff ) < 2 || ! self::available() ) {
            return $staff;
        }
        $strategy = get_option( 'yatoon_assignment_strategy', 'service_order' );
        if ( 'random' === $strategy ) {
            shuffle( $staff );
            return $staff;
        }
        if ( 'round_robin' === $strategy ) {
            $last = absint( get_option( 'yatoon_round_robin_last_staff', 0 ) );
            usort( $staff, static function ( $a, $b ) use ( $last ) {
                $ak = (int) $a->id > $last ? (int) $a->id : (int) $a->id + PHP_INT_MAX / 2;
                $bk = (int) $b->id > $last ? (int) $b->id : (int) $b->id + PHP_INT_MAX / 2;
                return $ak <=> $bk;
            } );
            if ( $staff ) {
                update_option( 'yatoon_round_robin_last_staff', (int) $staff[0]->id, false );
            }
            return $staff;
        }
        if ( 'preferred_staff' === $strategy && ! empty( $_POST['customer_email'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- public booking input is authorized by the calling endpoint and treated as an untrusted lookup key only.
            global $wpdb;
            $email = sanitize_email( wp_unslash( $_POST['customer_email'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- see authorization boundary above.
            $preferred = $wpdb->get_var( $wpdb->prepare( "SELECT preferred_staff FROM {$wpdb->prefix}yatoon_clients WHERE email=%s LIMIT 1", $email ) );
            if ( $preferred ) {
                usort( $staff, static function ( $a, $b ) use ( $preferred ) {
                    $am = (string) $a->id === (string) $preferred || 0 === strcasecmp( (string) $a->name, (string) $preferred );
                    $bm = (string) $b->id === (string) $preferred || 0 === strcasecmp( (string) $b->name, (string) $preferred );
                    return (int) $bm <=> (int) $am;
                } );
            }
            return $staff;
        }
        if ( 'least_loaded' === $strategy ) {
            global $wpdb;
            $date = $start_at ? substr( sanitize_text_field( $start_at ), 0, 10 ) : current_time( 'Y-m-d' );
            $ids = array_map( static function ( $person ) {
 return absint( $person->id );
}, $staff );
            $loads = array_fill_keys( $ids, 0 );
            if ( $ids ) {
                $id_sql = implode( ',', array_map( 'absint', $ids ) );
                // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- ID list contains only absint values; table name uses the WordPress prefix.
                $rows = $wpdb->get_results( $wpdb->prepare( "SELECT staff_id, SUM(TIMESTAMPDIFF(MINUTE,start_time,end_time)) AS minutes FROM {$wpdb->prefix}yatoon_bookings WHERE staff_id IN ({$id_sql}) AND DATE(start_time)=%s AND status NOT IN ('cancelled','cancelled_by_customer','CANCELLED_BY_CUSTOMER','CANCELLED_BY_SELLER','DECLINED','no_show') GROUP BY staff_id", $date ) );
                foreach ( $rows as $row ) {
                    $loads[ (int) $row->staff_id ] = (int) $row->minutes;
                }
                usort( $staff, static function ( $a, $b ) use ( $loads ) {
                    return ( $loads[ (int) $a->id ] ?? 0 ) <=> ( $loads[ (int) $b->id ] ?? 0 );
                } );
            }
        }
        return $staff;
    }

    public static function record_low_stock_health() {
        global $wpdb;
        $count = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->prefix}yatoon_inventory_items WHERE is_active=1 AND quantity<=low_stock_threshold" );
        if ( $count && class_exists( 'YATOON_Insights' ) ) {
            /* translators: %d: number of inventory items at or below their low-stock threshold. */
            YATOON_Insights::audit( 'low_stock', sprintf( _n( '%d inventory item is low in stock.', '%d inventory items are low in stock.', $count, 'yatoon-booking-system' ), $count ) );
        }
    }

    public static function render_admin() {
        if ( ! current_user_can( 'manage_options' ) ) {
            return;
        }
        global $wpdb;
        $tab = sanitize_key( wp_unslash( $_GET['tab'] ?? 'compensation' ) );
        $staff = $wpdb->get_results( "SELECT id,name FROM {$wpdb->prefix}yatoon_staff WHERE is_active=1 ORDER BY name" );
        $services = $wpdb->get_results( "SELECT id,name FROM {$wpdb->prefix}yatoon_services WHERE is_active=1 ORDER BY name" );
        $rules = array();
        foreach ( $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}yatoon_commission_rules" ) as $rule ) {
            $rules[ $rule->staff_id ? 'staff:' . $rule->staff_id : 'service:' . $rule->service_id ] = $rule;
        }
        $items = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}yatoon_inventory_items ORDER BY is_active DESC,name" );
        $locations = $wpdb->get_results( "SELECT id,name FROM {$wpdb->prefix}yatoon_locations WHERE is_active=1 ORDER BY name" );
        $edit_item = null;
        if ( ! empty( $_GET['edit_item'] ) ) {
            $edit_item = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}yatoon_inventory_items WHERE id=%d", absint( $_GET['edit_item'] ) ) );
        }
        $entries = $wpdb->get_results( "SELECT ce.*,s.name AS staff_name FROM {$wpdb->prefix}yatoon_commission_entries ce LEFT JOIN {$wpdb->prefix}yatoon_staff s ON s.id=ce.staff_id ORDER BY ce.id DESC LIMIT 100" );
        ?>
        <div class="wrap"><h1><?php esc_html_e( 'Compensation & Stock', 'yatoon-booking-system' ); ?></h1><nav class="nav-tab-wrapper"><a class="nav-tab <?php echo 'compensation' === $tab ? 'nav-tab-active' : ''; ?>" href="?page=yatoon-salon-operations&tab=compensation"><?php esc_html_e( 'Compensation', 'yatoon-booking-system' ); ?></a><a class="nav-tab <?php echo 'inventory' === $tab ? 'nav-tab-active' : ''; ?>" href="?page=yatoon-salon-operations&tab=inventory"><?php esc_html_e( 'Inventory', 'yatoon-booking-system' ); ?></a></nav>
        <?php if ( 'inventory' === $tab ) : ?>
        <h2><?php esc_html_e( 'Add retail item', 'yatoon-booking-system' ); ?></h2><form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" style="background:#fff;padding:16px;display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:12px"><?php wp_nonce_field( 'yatoon_save_inventory_item' ); ?><input type="hidden" name="action" value="yatoon_save_inventory_item"><label><?php esc_html_e( 'Name', 'yatoon-booking-system' ); ?><input class="regular-text" required name="name"></label><label>SKU<input name="sku"></label><label><?php esc_html_e( 'Square catalog ID (optional)', 'yatoon-booking-system' ); ?><input name="square_catalog_id"></label><label><?php esc_html_e( 'Quantity', 'yatoon-booking-system' ); ?><input type="number" step="0.01" name="quantity" value="0"></label><label><?php esc_html_e( 'Low-stock level', 'yatoon-booking-system' ); ?><input type="number" step="0.01" name="low_stock_threshold" value="0"></label><label><?php esc_html_e( 'Retail price', 'yatoon-booking-system' ); ?><input type="number" step="0.01" name="retail_price" value="0"></label><label><?php esc_html_e( 'Unit cost', 'yatoon-booking-system' ); ?><input type="number" step="0.01" name="unit_cost" value="0"></label><label><input type="checkbox" name="is_active" value="1" checked> <?php esc_html_e( 'Active', 'yatoon-booking-system' ); ?></label><button class="button button-primary"><?php esc_html_e( 'Save item', 'yatoon-booking-system' ); ?></button></form>
        <h2><?php esc_html_e( 'Inventory', 'yatoon-booking-system' ); ?></h2><table class="widefat striped"><thead><tr><th><?php esc_html_e( 'Item', 'yatoon-booking-system' ); ?></th><th>SKU</th><th><?php esc_html_e( 'Stock', 'yatoon-booking-system' ); ?></th><th><?php esc_html_e( 'Adjust', 'yatoon-booking-system' ); ?></th></tr></thead><tbody><?php foreach ( $items as $item ) : ?><tr><td><strong><?php echo esc_html( $item->name ); ?></strong><?php if ( $item->quantity <= $item->low_stock_threshold ) : ?> <span style="color:#b32d2e"><?php esc_html_e( 'Low stock', 'yatoon-booking-system' ); ?></span><?php endif; ?></td><td><?php echo esc_html( $item->sku ); ?></td><td><?php echo esc_html( $item->quantity ); ?></td><td><form style="display:flex;gap:6px" method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>"><?php wp_nonce_field( 'yatoon_adjust_inventory' ); ?><input type="hidden" name="action" value="yatoon_adjust_inventory"><input type="hidden" name="item_id" value="<?php echo esc_attr( $item->id ); ?>"><input type="number" step="0.01" name="quantity_change" placeholder="+/-" required><select name="reason"><option value="purchase"><?php esc_html_e( 'Purchase', 'yatoon-booking-system' ); ?></option><option value="sale"><?php esc_html_e( 'Retail sale', 'yatoon-booking-system' ); ?></option><option value="usage"><?php esc_html_e( 'Service usage', 'yatoon-booking-system' ); ?></option><option value="damage"><?php esc_html_e( 'Damage', 'yatoon-booking-system' ); ?></option><option value="adjustment"><?php esc_html_e( 'Correction', 'yatoon-booking-system' ); ?></option></select><button class="button"><?php esc_html_e( 'Apply', 'yatoon-booking-system' ); ?></button></form></td></tr><?php endforeach; ?></tbody></table>
        <?php else : ?>
        <form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>"><?php wp_nonce_field( 'yatoon_save_compensation' ); ?><input type="hidden" name="action" value="yatoon_save_compensation"><h2><?php esc_html_e( 'Default rules', 'yatoon-booking-system' ); ?></h2><table class="form-table"><tr><th><?php esc_html_e( 'Any Staff assignment', 'yatoon-booking-system' ); ?></th><td><select name="assignment_strategy"><?php foreach ( array( 'service_order'=>'Service/admin order','round_robin'=>'Round robin','least_loaded'=>'Least loaded that day','preferred_staff'=>'Returning client preference','random'=>'Random' ) as $value=>$label ) : ?><option value="<?php echo esc_attr( $value ); ?>" <?php selected( get_option( 'yatoon_assignment_strategy', 'service_order' ), $value ); ?>><?php echo esc_html( $label ); ?></option><?php endforeach; ?></select></td></tr><tr><th><?php esc_html_e( 'Default commission', 'yatoon-booking-system' ); ?></th><td><select name="default_commission_type"><option value="percentage" <?php selected( get_option( 'yatoon_default_commission_type' ), 'percentage' ); ?>>%</option><option value="fixed" <?php selected( get_option( 'yatoon_default_commission_type' ), 'fixed' ); ?>><?php esc_html_e( 'Fixed', 'yatoon-booking-system' ); ?></option></select> <input type="number" min="0" step="0.01" name="default_commission_value" value="<?php echo esc_attr( get_option( 'yatoon_default_commission_value', 0 ) ); ?>"></td></tr><tr><th><?php esc_html_e( 'Tip allocation', 'yatoon-booking-system' ); ?></th><td><select name="tip_split_mode"><?php foreach ( array( 'assigned'=>'Assigned staff (or equal for multi-staff)','equal'=>'Equal split','service_revenue'=>'Proportional to service revenue','custom'=>'Custom staff weights' ) as $value=>$label ) : ?><option value="<?php echo esc_attr( $value ); ?>" <?php selected( get_option( 'yatoon_tip_split_mode', 'assigned' ), $value ); ?>><?php echo esc_html( $label ); ?></option><?php endforeach; ?></select></td></tr></table>
        <h2><?php esc_html_e( 'Staff overrides', 'yatoon-booking-system' ); ?></h2><table class="widefat striped"><thead><tr><th><?php esc_html_e( 'Staff', 'yatoon-booking-system' ); ?></th><th><?php esc_html_e( 'Commission type', 'yatoon-booking-system' ); ?></th><th><?php esc_html_e( 'Value', 'yatoon-booking-system' ); ?></th><th><?php esc_html_e( 'Custom tip weight %', 'yatoon-booking-system' ); ?></th></tr></thead><tbody><?php foreach ( $staff as $person ) : $rule=$rules[ 'staff:' . $person->id ]??null; ?><tr><td><?php echo esc_html( $person->name ); ?></td><td><select name="rules[staff:<?php echo esc_attr( $person->id ); ?>][rate_type]"><option value="percentage" <?php selected( $rule->rate_type??'', 'percentage' ); ?>>%</option><option value="fixed" <?php selected( $rule->rate_type??'', 'fixed' ); ?>><?php esc_html_e( 'Fixed', 'yatoon-booking-system' ); ?></option></select></td><td><input type="number" min="0" step="0.01" name="rules[staff:<?php echo esc_attr( $person->id ); ?>][rate_value]" value="<?php echo esc_attr( $rule->rate_value??0 ); ?>"></td><td><input type="number" min="0" max="100" step="0.01" name="rules[staff:<?php echo esc_attr( $person->id ); ?>][tip_share_percent]" value="<?php echo esc_attr( $rule->tip_share_percent??0 ); ?>"></td></tr><?php endforeach; ?></tbody></table>
        <h2><?php esc_html_e( 'Service overrides', 'yatoon-booking-system' ); ?></h2><table class="widefat striped"><thead><tr><th><?php esc_html_e( 'Service', 'yatoon-booking-system' ); ?></th><th><?php esc_html_e( 'Commission type', 'yatoon-booking-system' ); ?></th><th><?php esc_html_e( 'Value', 'yatoon-booking-system' ); ?></th><th><?php esc_html_e( 'Recommended rebook days', 'yatoon-booking-system' ); ?></th></tr></thead><tbody><?php foreach ( $services as $service ) : $rule=$rules[ 'service:' . $service->id ]??null; ?><tr><td><?php echo esc_html( $service->name ); ?></td><td><select name="rules[service:<?php echo esc_attr( $service->id ); ?>][rate_type]"><option value="percentage" <?php selected( $rule->rate_type??'', 'percentage' ); ?>>%</option><option value="fixed" <?php selected( $rule->rate_type??'', 'fixed' ); ?>><?php esc_html_e( 'Fixed', 'yatoon-booking-system' ); ?></option></select></td><td><input type="number" min="0" step="0.01" name="rules[service:<?php echo esc_attr( $service->id ); ?>][rate_value]" value="<?php echo esc_attr( $rule->rate_value??0 ); ?>"></td><td><input type="number" min="0" max="730" name="rules[service:<?php echo esc_attr( $service->id ); ?>][rebook_days]" value="<?php echo esc_attr( $rule->rebook_days??0 ); ?>" placeholder="e.g. 21"></td></tr><?php endforeach; ?></tbody></table><p><button class="button button-primary"><?php esc_html_e( 'Save rules', 'yatoon-booking-system' ); ?></button></p></form>
        <h2><?php esc_html_e( 'Recent calculated earnings', 'yatoon-booking-system' ); ?></h2><table class="widefat striped"><thead><tr><th><?php esc_html_e( 'Date', 'yatoon-booking-system' ); ?></th><th><?php esc_html_e( 'Staff', 'yatoon-booking-system' ); ?></th><th><?php esc_html_e( 'Service commission', 'yatoon-booking-system' ); ?></th><th><?php esc_html_e( 'Tips', 'yatoon-booking-system' ); ?></th><th><?php esc_html_e( 'Total', 'yatoon-booking-system' ); ?></th></tr></thead><tbody><?php foreach ( $entries as $entry ) : ?><tr><td><?php echo esc_html( $entry->calculated_at ); ?></td><td><?php echo esc_html( $entry->staff_name ); ?></td><td><?php echo esc_html( number_format_i18n( $entry->service_commission, 2 ) ); ?></td><td><?php echo esc_html( number_format_i18n( $entry->tip_amount, 2 ) ); ?></td><td><strong><?php echo esc_html( number_format_i18n( $entry->total_amount, 2 ) ); ?></strong></td></tr><?php endforeach; ?></tbody></table>
        <?php endif; ?></div>
        <?php
    }
}
