<?php
/**
 * Election_Havadaran — سامانه هوادران انتخابات (GIS + ستاد)
 * بر اساس طرح پیشنهادی: پهنه‌بندی، سرشاخه، هوادار، بسته تبلیغاتی، SMS
 */
if ( ! defined( 'ABSPATH' ) ) exit;

require_once __DIR__ . '/election-personal-hq.php';
require_once __DIR__ . '/election-ballot-core.php';
require_once __DIR__ . '/election-org-departments.php';
require_once __DIR__ . '/election-logistics.php';
require_once __DIR__ . '/election-v6-features.php';
require_once __DIR__ . '/election-v7-finance-segments.php';
require_once __DIR__ . '/election-candidate-hub.php';
require_once __DIR__ . '/election-integrity-sectors.php';

class Election_Havadaran {
    use Election_Personal_HQ;
    use Election_Ballot_Core;
    use Election_Org_Departments;
    use Election_Logistics;
    use Election_V6_Features;
    use Election_V7_Finance_Segments;
    use Election_Candidate_Hub;
    use Election_Integrity_Sectors;

    public const BRANCH_CATEGORIES = [
        'personnel'        => 'پرسنل اداری',
        'waste'            => 'کارکنان پسماند',
        'green_space'      => 'فضای سبز',
        'dense_buildings'  => 'ساختمان‌های پرتراکم',
        'commercial'       => 'بازار و اصناف',
        'youth'            => 'جوانان و دانشگاه',
    ];

    public const PACKAGE_SIZES = [
        '21'  => [ 'label' => 'بسته ۲۱ نفره',  'capacity' => 21 ],
        '31'  => [ 'label' => 'بسته ۳۱ نفره',  'capacity' => 31 ],
        '01'  => [ 'label' => 'بسته تک‌نفره', 'capacity' => 1 ],
        '111' => [ 'label' => 'بسته ۱۱۱ نفره', 'capacity' => 111 ],
    ];

    public const TASK_STATUS = [
        'pending'    => 'در انتظار',
        'in_progress'=> 'در حال انجام',
        'done'       => 'انجام‌شده',
        'verified'   => 'تأیید سرشاخه',
    ];

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

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

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

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

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

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

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

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

    public static function can_manage( int $uid ): bool {
        return acl_user_is_super_admin( $uid )
            || acl_user_can( $uid, 'election.manage' );
    }

    public static function can_branch( int $uid ): bool {
        if ( self::can_manage( $uid ) ) return true;
        return acl_user_can( $uid, 'election.branch' ) && self::get_branch_by_user( $uid );
    }

    public static function can_supporter( int $uid ): bool {
        if ( self::can_branch( $uid ) ) return true;
        return acl_user_can( $uid, 'election.supporter' ) && self::get_supporter_by_user( $uid );
    }

    public static function get_branch_by_user( int $uid ): ?array {
        global $wpdb;
        $t = self::branches_table();
        $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$t} WHERE user_id = %d AND is_active = 1", $uid ), ARRAY_A );
        return $row ? self::fmt_branch( $row ) : null;
    }

    public static function get_supporter_by_user( int $uid ): ?array {
        global $wpdb;
        $t = self::supporters_table();
        $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$t} WHERE user_id = %d AND is_active = 1", $uid ), ARRAY_A );
        return $row ? self::fmt_supporter( $row ) : null;
    }

    public static function fmt_branch( array $row ): array {
        $row['category_label'] = self::BRANCH_CATEGORIES[ $row['category'] ?? '' ] ?? ( $row['category'] ?? '' );
        $row['zone'] = json_decode( $row['zone_json'] ?? '{}', true ) ?: [];
        return $row;
    }

    public static function fmt_supporter( array $row ): array {
        global $wpdb;
        $row['segment_ids'] = json_decode( $row['segment_ids_json'] ?? '[]', true ) ?: [];
        $branch = $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM " . self::branches_table() . " WHERE id = %d", (int) $row['branch_id']
        ), ARRAY_A );
        $row['branch'] = $branch ? self::fmt_branch( $branch ) : null;
        return $row;
    }

    public static function stats(): array {
        global $wpdb;
        $hqs_t = self::hqs_table();
        $hqs_n = $wpdb->get_var( "SHOW TABLES LIKE '{$hqs_t}'" ) === $hqs_t
            ? (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$hqs_t} WHERE is_active=1" )
            : 0;
        $seg = self::segment_stats();
        return [
            'segments'   => $seg['total'],
            'segment_progress' => $seg,
            'stations'   => (int) $wpdb->get_var( "SELECT COUNT(*) FROM " . self::stations_table() ),
            'districts'  => $wpdb->get_var( "SHOW TABLES LIKE '" . self::districts_table() . "'" ) === self::districts_table()
                ? (int) $wpdb->get_var( "SELECT COUNT(*) FROM " . self::districts_table() )
                : 0,
            'branches'   => (int) $wpdb->get_var( "SELECT COUNT(*) FROM " . self::branches_table() . " WHERE is_active=1" ),
            'supporters' => (int) $wpdb->get_var( "SELECT COUNT(*) FROM " . self::supporters_table() . " WHERE is_active=1" ),
            'hqs'        => $hqs_n,
            'packages'   => (int) $wpdb->get_var( "SELECT COUNT(*) FROM " . self::packages_table() ),
            'sms_sent'   => (int) $wpdb->get_var( "SELECT COUNT(*) FROM " . self::sms_table() . " WHERE status='sent'" ),
            'city'       => 'شیراز',
            'target_segments' => 1011,
            'gis_linked' => self::gis_tables_exist(),
        ];
    }

    public static function list_segments( array $opts = [] ): array {
        global $wpdb;
        $t = self::segments_table();
        $w = [ '1=1' ];
        $args = [];
        if ( ! empty( $opts['neighborhood'] ) ) {
            $w[] = 'neighborhood = %s';
            $args[] = sanitize_text_field( $opts['neighborhood'] );
        }
        if ( ! empty( $opts['station_id'] ) ) {
            $w[] = 'station_id = %d';
            $args[] = (int) $opts['station_id'];
        }
        if ( ! empty( $opts['ids'] ) && is_array( $opts['ids'] ) ) {
            $ids = array_map( 'intval', $opts['ids'] );
            $w[] = 'id IN (' . implode( ',', $ids ) . ')';
        }
        $sql = "SELECT * FROM {$t} WHERE " . implode( ' AND ', $w ) . ' ORDER BY neighborhood, part_no LIMIT 500';
        $rows = $args ? $wpdb->get_results( $wpdb->prepare( $sql, ...$args ), ARRAY_A ) : $wpdb->get_results( $sql, ARRAY_A );
        return array_map( [ __CLASS__, 'fmt_segment' ], $rows ?: [] );
    }

    public static function fmt_segment( array $row ): array {
        $row['age_profile'] = json_decode( $row['age_profile_json'] ?? '{}', true ) ?: [];
        $row['label'] = ( $row['neighborhood'] ?? '' ) . ' — بخش ' . ( $row['part_no'] ?? '' );
        return $row;
    }

    public static function list_stations(): array {
        global $wpdb;
        return $wpdb->get_results( "SELECT * FROM " . self::stations_table() . " ORDER BY id", ARRAY_A ) ?: [];
    }

    public static function list_branches(): array {
        global $wpdb;
        $rows = $wpdb->get_results(
            "SELECT * FROM " . self::branches_table() . " WHERE is_active=1 ORDER BY category, id",
            ARRAY_A
        ) ?: [];
        return array_map( [ __CLASS__, 'fmt_branch' ], $rows );
    }

    public static function list_supporters( ?int $branch_id = null ): array {
        global $wpdb;
        $t = self::supporters_table();
        if ( $branch_id ) {
            $rows = $wpdb->get_results( $wpdb->prepare(
                "SELECT * FROM {$t} WHERE branch_id = %d AND is_active=1 ORDER BY performance_score DESC", $branch_id
            ), ARRAY_A ) ?: [];
        } else {
            $rows = $wpdb->get_results( "SELECT * FROM {$t} WHERE is_active=1 ORDER BY branch_id, id", ARRAY_A ) ?: [];
        }
        return array_map( [ __CLASS__, 'fmt_supporter' ], $rows );
    }

    public static function content_for_user( int $uid ): array {
        global $wpdb;
        $t   = self::content_table();
        $hq  = self::get_hq_by_user( $uid );
        $branch = self::get_branch_by_user( $uid );
        $sup    = self::get_supporter_by_user( $uid );
        $seg_ids = $sup['segment_ids'] ?? [];

        $rows = $wpdb->get_results(
            "SELECT * FROM {$t} ORDER BY id DESC LIMIT 100", ARRAY_A
        ) ?: [];

        $out = [];
        foreach ( $rows as $r ) {
            $aud = $r['audience'] ?? 'all';
            $seg = (int) ( $r['segment_id'] ?? 0 );
            if ( $aud === 'branch' && $hq && ( $hq['role_type'] ?? '' ) === 'coordinator' ) {
                $out[] = self::fmt_content( $r );
            } elseif ( $aud === 'branch' && $branch && (int) $r['branch_id'] === (int) $branch['id'] ) {
                $out[] = self::fmt_content( $r );
            } elseif ( $aud === 'supporter' && $hq && ( $hq['role_type'] ?? '' ) === 'personal' ) {
                $out[] = self::fmt_content( $r );
            } elseif ( $aud === 'supporter' && $sup && ( ! $seg || in_array( $seg, $seg_ids, true ) ) ) {
                $out[] = self::fmt_content( $r );
            } elseif ( $aud === 'all' || self::can_manage( $uid ) ) {
                $out[] = self::fmt_content( $r );
            }
        }
        return $out;
    }

    public static function fmt_content( array $row ): array {
        $row['audience_label'] = match ( $row['audience'] ?? '' ) {
            'branch'    => 'سرشاخه',
            'supporter' => 'هوادار',
            default     => 'عمومی',
        };
        return $row;
    }

    public static function list_packages( ?int $branch_id = null ): array {
        global $wpdb;
        $t = self::packages_table();
        if ( $branch_id ) {
            $rows = $wpdb->get_results( $wpdb->prepare(
                "SELECT * FROM {$t} WHERE branch_id = %d OR branch_id IS NULL ORDER BY id DESC", $branch_id
            ), ARRAY_A ) ?: [];
        } else {
            $rows = $wpdb->get_results( "SELECT * FROM {$t} ORDER BY id DESC LIMIT 200", ARRAY_A ) ?: [];
        }
        return array_map( [ __CLASS__, 'fmt_package' ], $rows );
    }

    public static function fmt_package( array $row ): array {
        $size = $row['size_type'] ?? '21';
        $row['size_label'] = self::PACKAGE_SIZES[ $size ]['label'] ?? $size;
        $row['capacity'] = self::PACKAGE_SIZES[ $size ]['capacity'] ?? 0;
        return $row;
    }

    public static function submit_report( int $uid, array $data ): array {
        global $wpdb;
        if ( ! self::can_access( $uid ) ) {
            return [ 'success' => false, 'message' => 'دسترسی ندارید' ];
        }
        $wpdb->insert( self::reports_table(), [
            'user_id'    => $uid,
            'branch_id'  => null,
            'report_type'=> sanitize_key( $data['report_type'] ?? 'station_intel' ),
            'title'      => sanitize_text_field( $data['title'] ?? '' ),
            'body'       => sanitize_textarea_field( $data['body'] ?? '' ),
            'segment_id' => null,
            'station_id' => (int) ( $data['station_id'] ?? 0 ) ?: null,
            'phase'      => sanitize_key( $data['phase'] ?? self::current_phase() ),
            'status'     => 'submitted',
            'created_at' => current_time( 'mysql' ),
        ] );
        $hq = self::get_hq_by_user( $uid );
        if ( $hq ) {
            $wpdb->query( $wpdb->prepare(
                "UPDATE " . self::hqs_table() . " SET performance_score = performance_score + 1, tasks_done = tasks_done + 1 WHERE id = %d",
                (int) $hq['id']
            ) );
        }
        return [ 'success' => true, 'id' => (int) $wpdb->insert_id ];
    }

    public static function queue_sms( array $data ): array {
        global $wpdb;
        $phone = sanitize_text_field( $data['phone'] ?? '' );
        $msg   = sanitize_textarea_field( $data['message'] ?? '' );
        if ( ! $phone || ! $msg ) {
            return [ 'success' => false, 'message' => 'موبایل و متن الزامی است' ];
        }
        $wpdb->insert( self::sms_table(), [
            'phone'      => $phone,
            'message'    => $msg,
            'user_id'    => (int) ( $data['user_id'] ?? 0 ) ?: null,
            'status'     => 'queued',
            'created_at' => current_time( 'mysql' ),
        ] );
        $log_id = (int) $wpdb->insert_id;
        if ( ! empty( $data['send'] ) ) {
            require_once ACC_PATH . 'includes/helpers/acc-sms.php';
            $send = Acc_SMS::send( $phone, $msg );
            $wpdb->update( self::sms_table(), [
                'status' => ! empty( $send['success'] ) ? 'sent' : 'failed',
            ], [ 'id' => $log_id ] );
            return array_merge( [ 'success' => true, 'id' => $log_id ], $send );
        }
        return [ 'success' => true, 'id' => $log_id ];
    }

    public static function dashboard_for( int $uid ): array {
        return self::department_dashboard( $uid );
    }

    public static function can_access( int $uid ): bool {
        if ( self::can_manage( $uid ) ) {
            return true;
        }
        foreach ( self::department_catalog() as $dept ) {
            if ( acl_user_can( $uid, $dept['permission'] ) ) {
                return true;
            }
        }
        if ( self::has_hq( $uid ) ) {
            return true;
        }
        if ( self::get_branch_by_user( $uid ) ) {
            return true;
        }
        if ( self::get_supporter_by_user( $uid ) ) {
            return true;
        }
        return ! empty( self::user_station_ids( $uid ) );
    }

    public static function recent_sms( int $limit = 10 ): array {
        global $wpdb;
        return $wpdb->get_results( $wpdb->prepare(
            "SELECT * FROM " . self::sms_table() . " ORDER BY id DESC LIMIT %d", $limit
        ), ARRAY_A ) ?: [];
    }
}
