<?php
/**
 * Growth_Platform — منطق پورتال رشدگاه / شبکه سفیران (MVP)
 */
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Growth_Platform {

    public const COMMISSION_PCT = 10.0;
    public const ATTRIBUTION_DAYS = 45;

    public static function tbl( string $name ): string {
        global $wpdb;
        return $wpdb->prefix . 'growth_' . $name;
    }

    public static function service_catalog(): array {
        return [
            'website' => [
                'slug'        => 'website',
                'title'       => 'ساخت سایت',
                'tagline'     => 'از تک‌صفحه‌ای تا فروشگاهی سبک',
                'icon'        => '🌐',
                'form'        => 'package',
                'packages'    => [
                    [ 'code' => 'starter',     'title' => 'استارتر',       'price' => 18000000,  'desc' => 'لندینگ تک‌صفحه‌ای + فرم تماس' ],
                    [ 'code' => 'business',    'title' => 'کسب‌وکار',      'price' => 45000000,  'desc' => '۵–۸ صفحه + فرم + پنل ساده' ],
                    [ 'code' => 'shop-light',  'title' => 'فروشگاهی سبک', 'price' => 75000000,  'desc' => 'کاتالوگ + سبد خرید پایه' ],
                ],
            ],
            'sales_partner' => [
                'slug'     => 'sales_partner',
                'title'    => 'مشارکت در فروش',
                'tagline'  => 'محصول از ما — فروش از شما',
                'icon'     => '🤝',
                'form'     => 'partner',
                'packages' => [],
            ],
            'accounting_workshop' => [
                'slug'     => 'accounting_workshop',
                'title'    => 'آموزش حسابداری ۳ساعته',
                'tagline'  => 'کارگاه کوتاه و کاربردی',
                'icon'     => '📘',
                'form'     => 'session',
                'packages' => [
                    [ 'code' => 'invoice-basics', 'title' => 'فاکتور و دفتر',     'price' => 2500000, 'desc' => 'آشنایی با فاکتور و دفتر روزنامه' ],
                    [ 'code' => 'abc-lite',       'title' => 'ABC ساده',          'price' => 2800000, 'desc' => 'بهای تمام‌شده برای کسب‌وکار کوچک' ],
                    [ 'code' => 'read-balance',   'title' => 'خواندن تراز',       'price' => 2600000, 'desc' => 'تراز آزمایشی و گزارش‌های پایه' ],
                ],
            ],
            'branding' => [
                'slug'     => 'branding',
                'title'    => 'برندینگ محصول',
                'tagline'  => 'نام، هویت و لانچ',
                'icon'     => '✨',
                'form'     => 'package',
                'packages' => [
                    [ 'code' => 'name-promise',  'title' => 'نام و وعده برند',   'price' => 12000000, 'desc' => 'نام‌گذاری + پیام اصلی' ],
                    [ 'code' => 'visual-base',   'title' => 'هویت بصری پایه',   'price' => 28000000, 'desc' => 'لوگو، رنگ، تایپوگرافی' ],
                    [ 'code' => 'content-30',    'title' => 'بسته محتوایی ۳۰روزه', 'price' => 18000000, 'desc' => 'تقویم محتوا + قالب‌ها' ],
                    [ 'code' => 'product-launch','title' => 'لانچ محصول',       'price' => 35000000, 'desc' => 'لندینگ + کمپین کوتاه' ],
                ],
            ],
        ];
    }

    public static function ethics_text(): string {
        return 'منشور اخلاق سفیر ACC: درآمد فقط از فروش تأییدشده خدمات واقعی است، نه از عضوگیری. '
            . 'وعده ثروت تضمینی، فشار برای ثبت‌نام دیگران، و استفاده از امکانات/لوگوی دستگاه‌های اجرایی ممنوع است. '
            . 'در تبلیغات شخصی باید افشا شود که معرفی‌کننده کمیسیون دارد. ورود رایگان است و هیچ خرید اجباری برای فعال‌سازی وجود ندارد.';
    }

    public static function public_meta(): array {
        return [
            'brand'       => 'رشدگاه ACC',
            'tagline'     => 'خدمات واقعی · شبکه سفیران شفاف',
            'services'    => array_values( self::service_catalog() ),
            'ethics'      => self::ethics_text(),
            'commission'  => [ 'pct' => self::COMMISSION_PCT, 'levels' => 1 ],
            'sessions'    => self::list_open_sessions(),
        ];
    }

    public static function generate_ref_code( string $prefix = 'GR' ): string {
        return strtoupper( $prefix . substr( md5( uniqid( (string) mt_rand(), true ) ), 0, 6 ) );
    }

    public static function find_ambassador_by_code( string $code ): ?array {
        global $wpdb;
        $code = strtoupper( sanitize_text_field( $code ) );
        if ( $code === '' ) {
            return null;
        }
        $row = $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM " . self::tbl( 'ambassadors' ) . " WHERE referral_code = %s AND status = 'active' LIMIT 1",
            $code
        ), ARRAY_A );
        return $row ?: null;
    }

    public static function get_ambassador_by_user( int $user_id ): ?array {
        global $wpdb;
        if ( $user_id <= 0 ) {
            return null;
        }
        $row = $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM " . self::tbl( 'ambassadors' ) . " WHERE user_id = %d LIMIT 1",
            $user_id
        ), ARRAY_A );
        return $row ?: null;
    }

    public static function package_price( string $service_slug, string $package_code ): float {
        $cat = self::service_catalog()[ $service_slug ] ?? null;
        if ( ! $cat ) {
            return 0;
        }
        foreach ( $cat['packages'] as $p ) {
            if ( $p['code'] === $package_code ) {
                return (float) $p['price'];
            }
        }
        return 0;
    }

    public static function create_order( array $data ): array {
        global $wpdb;
        $service = sanitize_key( (string) ( $data['service_slug'] ?? '' ) );
        $catalog = self::service_catalog();
        if ( ! isset( $catalog[ $service ] ) ) {
            return [ 'success' => false, 'message' => 'خدمت نامعتبر است' ];
        }

        $name  = sanitize_text_field( (string) ( $data['customer_name'] ?? '' ) );
        $phone = sanitize_text_field( (string) ( $data['customer_phone'] ?? '' ) );
        if ( $name === '' || $phone === '' ) {
            return [ 'success' => false, 'message' => 'نام و موبایل الزامی است' ];
        }

        $package = sanitize_key( (string) ( $data['package_code'] ?? '' ) );
        $amount  = self::package_price( $service, $package );
        if ( $service === 'sales_partner' ) {
            $amount = 0;
        }

        $ref_code = strtoupper( sanitize_text_field( (string) ( $data['referral_code'] ?? '' ) ) );
        $amb      = $ref_code ? self::find_ambassador_by_code( $ref_code ) : null;
        $amb_id   = $amb ? (int) $amb['id'] : null;

        $order_code = self::generate_ref_code( 'GO' );
        $payload    = [
            'notes'          => sanitize_textarea_field( (string) ( $data['notes'] ?? '' ) ),
            'city'           => sanitize_text_field( (string) ( $data['city'] ?? '' ) ),
            'business_name'  => sanitize_text_field( (string) ( $data['business_name'] ?? '' ) ),
            'partner_interest' => sanitize_textarea_field( (string) ( $data['partner_interest'] ?? '' ) ),
            'session_id'     => (int) ( $data['session_id'] ?? 0 ),
        ];

        $ok = $wpdb->insert( self::tbl( 'orders' ), [
            'order_code'      => $order_code,
            'user_id'         => (int) ( $data['user_id'] ?? 0 ) ?: null,
            'service_slug'    => $service,
            'package_code'    => $package,
            'customer_name'   => $name,
            'customer_phone'  => $phone,
            'customer_email'  => sanitize_email( (string) ( $data['customer_email'] ?? '' ) ),
            'amount'          => $amount,
            'status'          => 'submitted',
            'invoice_status'  => 'stub',
            'ambassador_id'   => $amb_id,
            'referral_code'   => $ref_code ?: null,
            'payload_json'    => wp_json_encode( $payload, JSON_UNESCAPED_UNICODE ),
            'created_at'      => current_time( 'mysql' ),
        ] );

        if ( ! $ok ) {
            return [ 'success' => false, 'message' => 'ثبت سفارش ناموفق بود' ];
        }

        $order_id = (int) $wpdb->insert_id;

        if ( $amb_id ) {
            $wpdb->insert( self::tbl( 'leads' ), [
                'ambassador_id'   => $amb_id,
                'order_id'        => $order_id,
                'customer_name'   => $name,
                'customer_phone'  => $phone,
                'service_interest'=> $service,
                'status'          => 'introduced',
                'source'          => 'order_form',
                'created_at'      => current_time( 'mysql' ),
            ] );
            $wpdb->query( $wpdb->prepare(
                'UPDATE ' . self::tbl( 'ambassadors' ) . ' SET total_leads = total_leads + 1 WHERE id = %d',
                $amb_id
            ) );
        }

        if ( $service === 'accounting_workshop' && ! empty( $payload['session_id'] ) ) {
            self::book_session_slot( (int) $payload['session_id'], $order_id, $name, $phone );
        }

        return [
            'success'    => true,
            'order_id'   => $order_id,
            'order_code' => $order_code,
            'amount'     => $amount,
            'status'     => 'submitted',
        ];
    }

    public static function list_open_sessions(): array {
        global $wpdb;
        $t = self::tbl( 'sessions' );
        $rows = $wpdb->get_results(
            "SELECT * FROM {$t} WHERE status = 'open' AND starts_at >= NOW() ORDER BY starts_at ASC LIMIT 40",
            ARRAY_A
        );
        return $rows ?: [];
    }

    public static function book_session_slot( int $session_id, int $order_id, string $name, string $phone ): array {
        global $wpdb;
        $t = self::tbl( 'sessions' );
        $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$t} WHERE id = %d", $session_id ), ARRAY_A );
        if ( ! $row ) {
            return [ 'success' => false, 'message' => 'جلسه یافت نشد' ];
        }
        if ( (int) $row['seats_taken'] >= (int) $row['seats_total'] ) {
            return [ 'success' => false, 'message' => 'ظرفیت تکمیل است' ];
        }
        $wpdb->update( $t, [
            'seats_taken' => (int) $row['seats_taken'] + 1,
            'status'      => ( (int) $row['seats_taken'] + 1 >= (int) $row['seats_total'] ) ? 'full' : 'open',
            'updated_at'  => current_time( 'mysql' ),
        ], [ 'id' => $session_id ] );

        $payload = [ 'booked_name' => $name, 'booked_phone' => $phone, 'order_id' => $order_id ];
        $wpdb->query( $wpdb->prepare(
            "UPDATE {$t} SET notes = %s WHERE id = %d",
            wp_json_encode( $payload, JSON_UNESCAPED_UNICODE ),
            $session_id
        ) );
        return [ 'success' => true ];
    }

    public static function register_ambassador( array $data ): array {
        global $wpdb;
        $path = sanitize_key( (string) ( $data['path'] ?? 'neighbor' ) );
        if ( ! in_array( $path, [ 'neighbor', 'device_referral' ], true ) ) {
            $path = 'neighbor';
        }

        $name  = sanitize_text_field( (string) ( $data['display_name'] ?? '' ) );
        $phone = sanitize_text_field( (string) ( $data['phone'] ?? '' ) );
        if ( $name === '' || $phone === '' ) {
            return [ 'success' => false, 'message' => 'نام و موبایل الزامی است' ];
        }

        $ethics = ! empty( $data['ethics_accepted'] );
        if ( ! $ethics ) {
            return [ 'success' => false, 'message' => 'پذیرش منشور اخلاق الزامی است' ];
        }

        if ( $path === 'device_referral' && empty( $data['compliance_ack'] ) ) {
            return [ 'success' => false, 'message' => 'خوداظهاری انطباق با مقررات دستگاه الزامی است' ];
        }

        $user_id = (int) ( $data['user_id'] ?? 0 );
        $existing = null;
        if ( $user_id > 0 ) {
            $existing = self::get_ambassador_by_user( $user_id );
        }
        if ( ! $existing ) {
            $existing = $wpdb->get_row( $wpdb->prepare(
                'SELECT * FROM ' . self::tbl( 'ambassadors' ) . ' WHERE phone = %s LIMIT 1',
                $phone
            ), ARRAY_A );
        }
        if ( $existing ) {
            return [
                'success'    => true,
                'is_new'     => false,
                'ambassador' => self::_amb_public( $existing ),
            ];
        }

        $code = self::generate_ref_code( $path === 'device_referral' ? 'DV' : 'SF' );
        while ( self::find_ambassador_by_code( $code ) ) {
            $code = self::generate_ref_code( $path === 'device_referral' ? 'DV' : 'SF' );
        }

        $tier = $path === 'device_referral' ? 'device_referral' : 'neighbor';
        $ok = $wpdb->insert( self::tbl( 'ambassadors' ), [
            'user_id'          => $user_id ?: null,
            'display_name'     => $name,
            'phone'            => $phone,
            'email'            => sanitize_email( (string) ( $data['email'] ?? '' ) ),
            'city'             => sanitize_text_field( (string) ( $data['city'] ?? '' ) ),
            'path'             => $path,
            'tier'             => $tier,
            'referral_code'    => $code,
            'status'           => 'active',
            'ethics_accepted'  => 1,
            'ethics_accepted_at' => current_time( 'mysql' ),
            'compliance_ack'   => $path === 'device_referral' ? 1 : 0,
            'commission_pct'   => self::COMMISSION_PCT,
            'allow_subtree'    => 0,
            'created_at'       => current_time( 'mysql' ),
        ] );

        if ( ! $ok ) {
            return [ 'success' => false, 'message' => 'ثبت سفیر ناموفق بود' ];
        }

        $id  = (int) $wpdb->insert_id;
        $amb = $wpdb->get_row( $wpdb->prepare(
            'SELECT * FROM ' . self::tbl( 'ambassadors' ) . ' WHERE id = %d', $id
        ), ARRAY_A );

        return [
            'success'    => true,
            'is_new'     => true,
            'ambassador' => self::_amb_public( $amb ),
        ];
    }

    public static function add_lead( int $ambassador_id, array $data ): array {
        global $wpdb;
        $name  = sanitize_text_field( (string) ( $data['customer_name'] ?? '' ) );
        $phone = sanitize_text_field( (string) ( $data['customer_phone'] ?? '' ) );
        if ( $name === '' || $phone === '' ) {
            return [ 'success' => false, 'message' => 'نام و موبایل مشتری الزامی است' ];
        }
        $ok = $wpdb->insert( self::tbl( 'leads' ), [
            'ambassador_id'    => $ambassador_id,
            'customer_name'    => $name,
            'customer_phone'   => $phone,
            'service_interest' => sanitize_key( (string) ( $data['service_interest'] ?? 'website' ) ),
            'notes'            => sanitize_textarea_field( (string) ( $data['notes'] ?? '' ) ),
            'status'           => 'introduced',
            'source'           => 'manual',
            'created_at'       => current_time( 'mysql' ),
        ] );
        if ( ! $ok ) {
            return [ 'success' => false, 'message' => 'ثبت لید ناموفق' ];
        }
        $wpdb->query( $wpdb->prepare(
            'UPDATE ' . self::tbl( 'ambassadors' ) . ' SET total_leads = total_leads + 1 WHERE id = %d',
            $ambassador_id
        ) );
        return [ 'success' => true, 'lead_id' => (int) $wpdb->insert_id ];
    }

    public static function confirm_order( int $order_id, int $admin_user_id = 0 ): array {
        global $wpdb;
        $t = self::tbl( 'orders' );
        $order = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$t} WHERE id = %d", $order_id ), ARRAY_A );
        if ( ! $order ) {
            return [ 'success' => false, 'message' => 'سفارش یافت نشد' ];
        }
        if ( $order['status'] === 'confirmed' ) {
            return [ 'success' => true, 'message' => 'قبلاً تأیید شده', 'order' => $order ];
        }

        $wpdb->update( $t, [
            'status'         => 'confirmed',
            'invoice_status' => 'pending_invoice',
            'confirmed_at'   => current_time( 'mysql' ),
            'confirmed_by'   => $admin_user_id ?: null,
            'updated_at'     => current_time( 'mysql' ),
        ], [ 'id' => $order_id ] );

        $amb_id = (int) ( $order['ambassador_id'] ?? 0 );
        $amount = (float) $order['amount'];
        if ( $amb_id > 0 && $amount > 0 ) {
            $amb = $wpdb->get_row( $wpdb->prepare(
                'SELECT * FROM ' . self::tbl( 'ambassadors' ) . ' WHERE id = %d', $amb_id
            ), ARRAY_A );
            $pct = $amb ? (float) $amb['commission_pct'] : self::COMMISSION_PCT;
            $comm = round( $amount * $pct / 100, 0 );
            $dedupe = 'order_' . $order_id;
            $exists = (int) $wpdb->get_var( $wpdb->prepare(
                'SELECT id FROM ' . self::tbl( 'commissions' ) . ' WHERE dedupe_key = %s',
                $dedupe
            ) );
            if ( ! $exists ) {
                $wpdb->insert( self::tbl( 'commissions' ), [
                    'ambassador_id'     => $amb_id,
                    'order_id'          => $order_id,
                    'level'             => 1,
                    'order_amount'      => $amount,
                    'commission_pct'    => $pct,
                    'commission_amount' => $comm,
                    'status'            => 'approved',
                    'dedupe_key'        => $dedupe,
                    'created_at'        => current_time( 'mysql' ),
                    'approved_at'       => current_time( 'mysql' ),
                ] );
                $wpdb->query( $wpdb->prepare(
                    'UPDATE ' . self::tbl( 'ambassadors' ) . '
                     SET total_earned = total_earned + %f,
                         balance_pending = balance_pending + %f,
                         converted_leads = converted_leads + 1
                     WHERE id = %d',
                    $comm, $comm, $amb_id
                ) );
            }
            $wpdb->update( self::tbl( 'leads' ), [ 'status' => 'converted' ], [
                'order_id' => $order_id,
            ] );
        }

        $order = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$t} WHERE id = %d", $order_id ), ARRAY_A );
        return [ 'success' => true, 'order' => $order ];
    }

    public static function customer_orders( ?int $user_id, string $phone = '' ): array {
        global $wpdb;
        $t = self::tbl( 'orders' );
        if ( $user_id > 0 ) {
            return $wpdb->get_results( $wpdb->prepare(
                "SELECT * FROM {$t} WHERE user_id = %d ORDER BY id DESC LIMIT 50", $user_id
            ), ARRAY_A ) ?: [];
        }
        if ( $phone !== '' ) {
            return $wpdb->get_results( $wpdb->prepare(
                "SELECT * FROM {$t} WHERE customer_phone = %s ORDER BY id DESC LIMIT 50", $phone
            ), ARRAY_A ) ?: [];
        }
        return [];
    }

    public static function ambassador_dashboard( int $ambassador_id ): array {
        global $wpdb;
        $amb = $wpdb->get_row( $wpdb->prepare(
            'SELECT * FROM ' . self::tbl( 'ambassadors' ) . ' WHERE id = %d', $ambassador_id
        ), ARRAY_A );
        if ( ! $amb ) {
            return [];
        }
        $leads = $wpdb->get_results( $wpdb->prepare(
            'SELECT * FROM ' . self::tbl( 'leads' ) . ' WHERE ambassador_id = %d ORDER BY id DESC LIMIT 40',
            $ambassador_id
        ), ARRAY_A ) ?: [];
        $comms = $wpdb->get_results( $wpdb->prepare(
            'SELECT * FROM ' . self::tbl( 'commissions' ) . ' WHERE ambassador_id = %d ORDER BY id DESC LIMIT 40',
            $ambassador_id
        ), ARRAY_A ) ?: [];
        $orders = $wpdb->get_results( $wpdb->prepare(
            'SELECT * FROM ' . self::tbl( 'orders' ) . ' WHERE ambassador_id = %d ORDER BY id DESC LIMIT 40',
            $ambassador_id
        ), ARRAY_A ) ?: [];

        return [
            'ambassador'  => self::_amb_public( $amb ),
            'leads'       => $leads,
            'commissions' => $comms,
            'orders'      => $orders,
            'share_url'   => '/acc-engine/growth.php?ref=' . rawurlencode( $amb['referral_code'] ),
            'subtree'     => $amb['path'] === 'device_referral' ? null : [ 'enabled' => false, 'note' => 'درخت چندسطحی در MVP غیرفعال است' ],
        ];
    }

    public static function admin_dashboard(): array {
        global $wpdb;
        $orders = $wpdb->get_results(
            'SELECT * FROM ' . self::tbl( 'orders' ) . ' ORDER BY id DESC LIMIT 80',
            ARRAY_A
        ) ?: [];
        $ambs = $wpdb->get_results(
            'SELECT * FROM ' . self::tbl( 'ambassadors' ) . ' ORDER BY id DESC LIMIT 80',
            ARRAY_A
        ) ?: [];
        $comms = $wpdb->get_results(
            'SELECT * FROM ' . self::tbl( 'commissions' ) . ' ORDER BY id DESC LIMIT 80',
            ARRAY_A
        ) ?: [];
        $sessions = $wpdb->get_results(
            'SELECT * FROM ' . self::tbl( 'sessions' ) . ' ORDER BY starts_at ASC LIMIT 40',
            ARRAY_A
        ) ?: [];

        return [
            'orders'      => $orders,
            'ambassadors' => array_map( [ self::class, '_amb_public' ], $ambs ),
            'commissions' => $comms,
            'sessions'    => $sessions,
            'stats'       => [
                'orders_total'       => count( $orders ),
                'orders_confirmed'   => count( array_filter( $orders, static fn( $o ) => ( $o['status'] ?? '' ) === 'confirmed' ) ),
                'ambassadors_active' => count( array_filter( $ambs, static fn( $a ) => ( $a['status'] ?? '' ) === 'active' ) ),
                'commission_sum'     => array_sum( array_map( static fn( $c ) => (float) $c['commission_amount'], $comms ) ),
            ],
        ];
    }

    private static function _amb_public( ?array $amb ): ?array {
        if ( ! $amb ) {
            return null;
        }
        return [
            'id'              => (int) $amb['id'],
            'display_name'    => $amb['display_name'],
            'phone'           => $amb['phone'],
            'email'           => $amb['email'] ?? '',
            'city'            => $amb['city'] ?? '',
            'path'            => $amb['path'],
            'tier'            => $amb['tier'],
            'referral_code'   => $amb['referral_code'],
            'status'          => $amb['status'],
            'commission_pct'  => (float) $amb['commission_pct'],
            'total_leads'     => (int) $amb['total_leads'],
            'converted_leads' => (int) $amb['converted_leads'],
            'total_earned'    => (float) $amb['total_earned'],
            'balance_pending' => (float) $amb['balance_pending'],
            'allow_subtree'   => (int) $amb['allow_subtree'],
            'ethics_accepted' => (int) $amb['ethics_accepted'],
        ];
    }
}
