<?php
/**
 * election-logistics.php — انبار اقلام تبلیغاتی + محل نصب بنر/پوستر
 */
if ( ! defined( 'ABSPATH' ) ) exit;

trait Election_Logistics {

    public const WAREHOUSE_CATEGORIES = [
        'banner'   => 'بنر و پلاکارد',
        'poster'   => 'پوستر و تراکت',
        'flag'     => 'پرچم و اریبند',
        'sticker'  => 'برچسب و استیکر',
        'gift'     => 'هدایا و اقلام تبلیغاتی',
        'other'    => 'سایر',
    ];

    public const BANNER_SPOT_TYPES = [
        'facade'   => 'نمای ساختمان',
        'wall'     => 'دیوار شهری',
        'board'    => 'تابلو ثابت',
        'pole'     => 'پایه/چرشته',
        'vehicle'  => 'خودرو/وانت',
        'shop'     => 'ویترین مغازه',
        'other'    => 'سایر',
    ];

    public const BANNER_STATUSES = [
        'planned'   => 'برنامه‌ریزی',
        'approved'  => 'تأیید ستاد',
        'installed' => 'نصب شده',
        'verified'  => 'بازرسی OK',
        'removed'   => 'جمع‌آوری',
    ];

    public static function warehouse_table(): string {
        global $wpdb;
        return $wpdb->prefix . 'election_warehouse_items';
    }

    public static function warehouse_moves_table(): string {
        global $wpdb;
        return $wpdb->prefix . 'election_warehouse_moves';
    }

    public static function banner_spots_table(): string {
        global $wpdb;
        return $wpdb->prefix . 'election_banner_spots';
    }

    public static function fmt_warehouse_item( array $row ): array {
        $row['category_label'] = self::WAREHOUSE_CATEGORIES[ $row['category'] ?? '' ] ?? ( $row['category'] ?? '' );
        $row['available_qty']  = max( 0, (int) $row['stock_qty'] - (int) ( $row['reserved_qty'] ?? 0 ) );
        return $row;
    }

    public static function list_warehouse_items( ?string $category = null ): array {
        global $wpdb;
        $t = self::warehouse_table();
        if ( $wpdb->get_var( "SHOW TABLES LIKE '{$t}'" ) !== $t ) {
            return [];
        }
        $w   = [ '1=1' ];
        $args = [];
        if ( $category ) {
            $w[]    = 'category = %s';
            $args[] = sanitize_key( $category );
        }
        $sql  = "SELECT * FROM {$t} WHERE " . implode( ' AND ', $w ) . ' ORDER BY category, name';
        $rows = $args ? $wpdb->get_results( $wpdb->prepare( $sql, ...$args ), ARRAY_A ) : $wpdb->get_results( $sql, ARRAY_A );
        return array_map( [ __CLASS__, 'fmt_warehouse_item' ], $rows ?: [] );
    }

    public static function issue_warehouse_item( int $uid, array $data ): array {
        global $wpdb;
        $t  = self::warehouse_table();
        $mt = self::warehouse_moves_table();
        if ( ! self::can_manage( $uid ) && ! acl_user_can( $uid, 'election.dept.goods' )
            && ! acl_user_can( $uid, 'election.dept.distribution' ) ) {
            return [ 'success' => false, 'message' => 'دسترسی انبار ندارید' ];
        }
        $item_id = (int) ( $data['item_id'] ?? 0 );
        $qty     = max( 1, (int) ( $data['qty'] ?? 1 ) );
        $item    = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$t} WHERE id = %d", $item_id ), ARRAY_A );
        if ( ! $item ) {
            return [ 'success' => false, 'message' => 'قلم یافت نشد' ];
        }
        $avail = (int) $item['stock_qty'] - (int) $item['reserved_qty'];
        if ( $qty > $avail ) {
            return [ 'success' => false, 'message' => 'موجودی کافی نیست' ];
        }
        $wpdb->update( $t, [ 'reserved_qty' => (int) $item['reserved_qty'] + $qty ], [ 'id' => $item_id ] );
        $wpdb->insert( $mt, [
            'item_id'    => $item_id,
            'user_id'    => (int) ( $data['to_user_id'] ?? 0 ) ?: $uid,
            'station_id' => (int) ( $data['station_id'] ?? 0 ) ?: null,
            'qty'        => $qty,
            'move_type'  => 'issue',
            'notes'      => sanitize_text_field( $data['notes'] ?? '' ),
            'created_by' => $uid,
            'created_at' => current_time( 'mysql' ),
        ] );
        return [ 'success' => true, 'id' => (int) $wpdb->insert_id ];
    }

    public static function fmt_banner_spot( array $row ): array {
        $row['spot_type_label'] = self::BANNER_SPOT_TYPES[ $row['spot_type'] ?? '' ] ?? ( $row['spot_type'] ?? '' );
        $row['status_label']    = self::BANNER_STATUSES[ $row['status'] ?? '' ] ?? ( $row['status'] ?? '' );
        return $row;
    }

    public static function list_banner_spots( ?int $station_id = null, ?int $user_id = null ): array {
        global $wpdb;
        $t = self::banner_spots_table();
        if ( $wpdb->get_var( "SHOW TABLES LIKE '{$t}'" ) !== $t ) {
            return [];
        }
        $w    = [ '1=1' ];
        $args = [];
        if ( $station_id ) {
            $w[]    = 'station_id = %d';
            $args[] = $station_id;
        }
        if ( $user_id ) {
            $w[]    = 'user_id = %d';
            $args[] = $user_id;
        }
        $sql  = "SELECT * FROM {$t} WHERE " . implode( ' AND ', $w ) . ' ORDER BY station_id, id DESC';
        $rows = $args ? $wpdb->get_results( $wpdb->prepare( $sql, ...$args ), ARRAY_A ) : $wpdb->get_results( $sql, ARRAY_A );
        return array_map( [ __CLASS__, 'fmt_banner_spot' ], $rows ?: [] );
    }

    public static function add_banner_spot( int $uid, array $data ): array {
        global $wpdb;
        $t = self::banner_spots_table();
        if ( $wpdb->get_var( "SHOW TABLES LIKE '{$t}'" ) !== $t ) {
            return [ 'success' => false, 'message' => 'جدول بنر موجود نیست' ];
        }
        $station_id = (int) ( $data['station_id'] ?? 0 );
        if ( ! $station_id ) {
            return [ 'success' => false, 'message' => 'صندوق الزامی است' ];
        }
        if ( ! self::can_manage( $uid ) && ! self::user_has_station( $uid, $station_id )
            && ! acl_user_can( $uid, 'election.dept.media' ) ) {
            return [ 'success' => false, 'message' => 'دسترسی به این صندوق ندارید' ];
        }
        $status = sanitize_key( $data['status'] ?? 'planned' );
        if ( ! isset( self::BANNER_STATUSES[ $status ] ) ) {
            $status = 'planned';
        }
        $wpdb->insert( $t, [
            'station_id'    => $station_id,
            'user_id'       => $uid,
            'spot_type'     => sanitize_key( $data['spot_type'] ?? 'wall' ),
            'location_desc' => sanitize_text_field( $data['location_desc'] ?? '' ),
            'address'       => sanitize_text_field( $data['address'] ?? '' ),
            'size'          => sanitize_text_field( $data['size'] ?? '' ),
            'status'        => $status,
            'phase'         => self::current_phase(),
            'notes'         => sanitize_textarea_field( $data['notes'] ?? '' ),
            'created_at'    => current_time( 'mysql' ),
        ] );
        return [ 'success' => true, 'id' => (int) $wpdb->insert_id ];
    }

    public static function update_banner_spot( int $uid, int $id, array $data ): array {
        global $wpdb;
        $t   = self::banner_spots_table();
        $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$t} WHERE id = %d", $id ), ARRAY_A );
        if ( ! $row ) {
            return [ 'success' => false, 'message' => 'یافت نشد' ];
        }
        $can = self::can_manage( $uid )
            || acl_user_can( $uid, 'election.dept.media' )
            || (int) $row['user_id'] === $uid;
        if ( ! $can ) {
            return [ 'success' => false, 'message' => 'دسترسی ندارید' ];
        }
        $upd = [];
        if ( isset( $data['status'] ) && isset( self::BANNER_STATUSES[ $data['status'] ] ) ) {
            $upd['status'] = sanitize_key( $data['status'] );
            if ( $upd['status'] === 'installed' ) {
                $upd['installed_at'] = current_time( 'mysql' );
            }
        }
        foreach ( [ 'location_desc', 'address', 'size', 'notes' ] as $f ) {
            if ( isset( $data[ $f ] ) ) {
                $upd[ $f ] = sanitize_text_field( $data[ $f ] );
            }
        }
        if ( $upd ) {
            $wpdb->update( $t, $upd, [ 'id' => $id ] );
        }
        return [ 'success' => true ];
    }

    public static function user_has_station( int $uid, int $station_id ): bool {
        return in_array( $station_id, self::user_station_ids( $uid ), true );
    }

    public static function warehouse_summary(): array {
        $items = self::list_warehouse_items();
        $total = array_sum( array_column( $items, 'stock_qty' ) );
        $avail = array_sum( array_column( $items, 'available_qty' ) );
        return [
            'items'       => count( $items ),
            'total_stock' => $total,
            'available'   => $avail,
            'categories'  => self::WAREHOUSE_CATEGORIES,
        ];
    }

    /** @return array<int,array{step:int,title:string,desc:string,tab:string}> */
    public static function field_workflow_steps(): array {
        return [
            [ 'step' => 1, 'title' => 'تخصیص صندوق',     'desc' => 'محل صندوق — چند صندوق همزمان',           'tab' => 'stations' ],
            [ 'step' => 2, 'title' => 'شناسایی',         'desc' => 'نانوایی، مدرسه، مسجد اطراف صندوق',       'tab' => 'poi' ],
            [ 'step' => 3, 'title' => 'تبلیغات',         'desc' => 'دریافت کالا، شعار، محل نصب بنر',         'tab' => 'campaign' ],
            [ 'step' => 4, 'title' => 'روز رأی',         'desc' => 'حضور و تشویق رأی‌دهندگان مردد',          'tab' => 'tasks' ],
            [ 'step' => 5, 'title' => 'گزارش',           'desc' => 'اطلاعات تصمیم‌گیری به ستاد',              'tab' => 'report' ],
            [ 'step' => 6, 'title' => 'تشکیلات',         'desc' => 'ستاد موقت — منطقه · شهرستان · کمیته',   'tab' => 'org-info' ],
        ];
    }

    public static function portal_mode( int $uid ): string {
        if ( self::can_manage( $uid ) ) {
            return 'admin';
        }
        if ( self::get_supporter_by_user( $uid ) && self::user_station_ids( $uid ) ) {
            return 'supporter';
        }
        foreach ( self::department_catalog() as $dept ) {
            if ( acl_user_can( $uid, $dept['permission'] ) ) {
                return 'dept';
            }
        }
        if ( self::get_branch_by_user( $uid ) ) {
            return 'dept';
        }
        if ( self::user_station_ids( $uid ) ) {
            return 'supporter';
        }
        return 'none';
    }
}
