<?php
/**
 * svc-marketer.php — موتور بازاریابی و همکاری در فروش خدمات HVAC
 */
if ( ! defined( 'ABSPATH' ) ) exit;

class Svc_Marketer {

    public const ATTRIBUTION_DAYS = 30;

    public static function tier_config(): array {
        return [
            'starter' => [
                'label'       => 'شروع',
                'lead_bonus'  => 30000,
                'request_pct' => 0.01,
                'job_pct'     => 0.03,
                'min_conv'    => 0,
                'color'       => '#94a3b8',
            ],
            'pro' => [
                'label'       => 'حرفه‌ای',
                'lead_bonus'  => 50000,
                'request_pct' => 0.015,
                'job_pct'     => 0.05,
                'min_conv'    => 10,
                'color'       => '#3b82f6',
            ],
            'elite' => [
                'label'       => 'نخبه',
                'lead_bonus'  => 80000,
                'request_pct' => 0.02,
                'job_pct'     => 0.07,
                'min_conv'    => 30,
                'color'       => '#8b5cf6',
            ],
            'partner' => [
                'label'       => 'شریک',
                'lead_bonus'  => 120000,
                'request_pct' => 0.025,
                'job_pct'     => 0.10,
                'min_conv'    => 100,
                'color'       => '#f59e0b',
            ],
        ];
    }

    public static function service_types(): array {
        return [
            'repair'             => 'تعمیرات',
            'pm'                 => 'نگهداری پیشگیرانه',
            'parts_supply'       => 'تأمین قطعات',
            'equipment_purchase' => 'خرید تجهیزات',
            'phone_consult'      => 'مشاوره تلفنی',
            'installation'       => 'نصب و راه‌اندازی',
        ];
    }

    public static function normalize_phone( string $phone ): string {
        $p = preg_replace( '/\D+/', '', $phone );
        if ( str_starts_with( $p, '98' ) && strlen( $p ) === 12 ) {
            $p = '0' . substr( $p, 2 );
        }
        return $p;
    }

    public static function generate_code(): string {
        global $wpdb;
        do {
            $code = 'MKT-' . strtoupper( substr( md5( uniqid( (string) mt_rand(), true ) ), 0, 6 ) );
            $exists = (int) $wpdb->get_var( $wpdb->prepare(
                "SELECT COUNT(*) FROM {$wpdb->prefix}svc_marketer_accounts WHERE marketer_code=%s", $code
            ) );
        } while ( $exists );
        return $code;
    }

    public static function get_by_code( string $code ): ?array {
        global $wpdb;
        $code = strtoupper( trim( $code ) );
        if ( ! $code ) return null;
        $row = $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}svc_marketer_accounts WHERE marketer_code=%s AND status='active' LIMIT 1",
            $code
        ), ARRAY_A );
        return $row ?: null;
    }

    public static function get_by_id( int $id ): ?array {
        global $wpdb;
        if ( $id <= 0 ) return null;
        $row = $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}svc_marketer_accounts WHERE id=%d", $id
        ), ARRAY_A );
        return $row ?: null;
    }

    public static function register( array $data ): array {
        global $wpdb;
        $phone = self::normalize_phone( (string) ( $data['phone'] ?? '' ) );
        if ( strlen( $phone ) < 10 ) {
            return [ 'success' => false, 'message' => 'شماره موبایل معتبر نیست' ];
        }

        $existing = $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}svc_marketer_accounts WHERE phone=%s", $phone
        ), ARRAY_A );

        if ( $existing ) {
            if ( ! empty( $data['display_name'] ) ) {
                $wpdb->update( "{$wpdb->prefix}svc_marketer_accounts", [
                    'display_name' => sanitize_text_field( $data['display_name'] ),
                    'email'        => sanitize_email( $data['email'] ?? '' ) ?: null,
                    'city'         => sanitize_text_field( $data['city'] ?? '' ) ?: null,
                ], [ 'id' => (int) $existing['id'] ] );
                $existing = self::get_by_id( (int) $existing['id'] );
            }
            return [ 'success' => true, 'account' => $existing, 'is_new' => false ];
        }

        $wpdb->insert( "{$wpdb->prefix}svc_marketer_accounts", [
            'phone'         => $phone,
            'display_name'  => sanitize_text_field( $data['display_name'] ?? 'بازاریاب' ),
            'email'         => sanitize_email( $data['email'] ?? '' ) ?: null,
            'city'          => sanitize_text_field( $data['city'] ?? '' ) ?: null,
            'marketer_code' => self::generate_code(),
            'tier'          => 'starter',
            'status'        => 'active',
        ] );

        return [
            'success' => true,
            'account' => self::get_by_id( (int) $wpdb->insert_id ),
            'is_new'  => true,
        ];
    }

    public static function recalc_tier( int $marketer_id ): void {
        global $wpdb;
        $account = self::get_by_id( $marketer_id );
        if ( ! $account ) return;

        $conv = (int) $account['converted_leads'];
        $new_tier = 'starter';
        foreach ( array_reverse( self::tier_config(), true ) as $key => $cfg ) {
            if ( $conv >= (int) $cfg['min_conv'] ) {
                $new_tier = $key;
                break;
            }
        }
        if ( $new_tier !== $account['tier'] ) {
            $wpdb->update( "{$wpdb->prefix}svc_marketer_accounts", [ 'tier' => $new_tier ], [ 'id' => $marketer_id ] );
        }
    }

    public static function tier_rates( string $tier ): array {
        return self::tier_config()[ $tier ] ?? self::tier_config()['starter'];
    }

    public static function introduce_lead( int $marketer_id, array $data ): array {
        global $wpdb;
        $account = self::get_by_id( $marketer_id );
        if ( ! $account || $account['status'] !== 'active' ) {
            return [ 'success' => false, 'message' => 'حساب بازاریاب فعال نیست' ];
        }

        $phone = self::normalize_phone( (string) ( $data['customer_phone'] ?? '' ) );
        if ( strlen( $phone ) < 10 ) {
            return [ 'success' => false, 'message' => 'موبایل مشتری معتبر نیست' ];
        }

        $pre = $wpdb->prefix;
        $active = $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM {$pre}svc_marketer_leads
             WHERE customer_phone=%s AND status NOT IN ('lost','converted')
             AND (expires_at IS NULL OR expires_at > NOW())
             ORDER BY id DESC LIMIT 1",
            $phone
        ), ARRAY_A );

        if ( $active && (int) $active['marketer_id'] !== $marketer_id ) {
            return [ 'success' => false, 'message' => 'این مشتری قبلاً توسط بازاریاب دیگری معرفی شده' ];
        }
        if ( $active && (int) $active['marketer_id'] === $marketer_id ) {
            return [ 'success' => true, 'lead' => $active, 'message' => 'این مشتری قبلاً در لیست شماست' ];
        }

        $interest = sanitize_key( $data['service_interest'] ?? 'repair' );
        if ( ! isset( self::service_types()[ $interest ] ) ) {
            $interest = 'repair';
        }

        $expires = gmdate( 'Y-m-d H:i:s', time() + self::ATTRIBUTION_DAYS * DAY_IN_SECONDS );
        $wpdb->insert( "{$pre}svc_marketer_leads", [
            'marketer_id'      => $marketer_id,
            'customer_name'    => sanitize_text_field( $data['customer_name'] ?? '' ),
            'customer_phone'   => $phone,
            'customer_city'    => sanitize_text_field( $data['customer_city'] ?? '' ) ?: null,
            'service_interest' => $interest,
            'notes'            => sanitize_textarea_field( $data['notes'] ?? '' ) ?: null,
            'status'           => 'introduced',
            'expires_at'       => $expires,
        ] );
        $lead_id = (int) $wpdb->insert_id;

        $wpdb->query( $wpdb->prepare(
            "UPDATE {$pre}svc_marketer_accounts SET total_leads = total_leads + 1 WHERE id=%d",
            $marketer_id
        ) );

        $rates = self::tier_rates( $account['tier'] );
        self::_add_commission( $marketer_id, $lead_id, 'lead_introduced', (float) $rates['lead_bonus'], 0, [
            'ref_type'   => 'lead',
            'ref_id'     => $lead_id,
            'dedupe_key' => 'lead_' . $lead_id,
            'note'       => 'پاداش معرفی مشتری',
            'status'     => 'pending',
        ] );

        return [ 'success' => true, 'lead' => self::get_lead( $lead_id ) ];
    }

    public static function get_lead( int $lead_id ): ?array {
        global $wpdb;
        return $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}svc_marketer_leads WHERE id=%d", $lead_id
        ), ARRAY_A ) ?: null;
    }

    public static function find_lead_for_phone( string $phone, ?int $marketer_id = null ): ?array {
        global $wpdb;
        $phone = self::normalize_phone( $phone );
        if ( ! $phone ) return null;

        if ( $marketer_id ) {
            return $wpdb->get_row( $wpdb->prepare(
                "SELECT * FROM {$wpdb->prefix}svc_marketer_leads
                 WHERE customer_phone=%s AND marketer_id=%d
                 AND status NOT IN ('lost')
                 AND (expires_at IS NULL OR expires_at > NOW())
                 ORDER BY id DESC LIMIT 1",
                $phone, $marketer_id
            ), ARRAY_A ) ?: null;
        }

        return $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}svc_marketer_leads
             WHERE customer_phone=%s AND status NOT IN ('lost','converted')
             AND (expires_at IS NULL OR expires_at > NOW())
             ORDER BY id DESC LIMIT 1",
            $phone
        ), ARRAY_A ) ?: null;
    }

    public static function attribute_by_code( string $code, string $phone, string $name = '' ): ?array {
        $marketer = self::get_by_code( $code );
        if ( ! $marketer ) return null;

        $result = self::introduce_lead( (int) $marketer['id'], [
            'customer_phone'   => $phone,
            'customer_name'    => $name,
            'service_interest' => 'repair',
            'notes'            => 'ثبت خودکار از لینک بازاریاب',
        ] );

        return $result['lead'] ?? null;
    }

    public static function on_request_created( array $request_data, int $request_id ): void {
        global $wpdb;
        $phone = self::normalize_phone( $request_data['phone'] ?? '' );
        if ( ! $phone || $request_id <= 0 ) return;

        $marketer_id = (int) ( $request_data['marketer_id'] ?? 0 );
        $lead = null;

        if ( $marketer_id ) {
            $lead = self::find_lead_for_phone( $phone, $marketer_id );
        }
        if ( ! $lead ) {
            $lead = self::find_lead_for_phone( $phone );
        }
        if ( ! $lead ) return;

        $marketer_id = (int) $lead['marketer_id'];
        $account = self::get_by_id( $marketer_id );
        if ( ! $account ) return;

        $wpdb->update( "{$wpdb->prefix}svc_marketer_leads", [
            'status'     => 'request_created',
            'request_id' => $request_id,
        ], [ 'id' => (int) $lead['id'] ] );

        $wpdb->update( "{$wpdb->prefix}svc_requests", [
            'marketer_id' => $marketer_id,
        ], [ 'id' => $request_id ] );

        $estimate = (float) ( $request_data['cost_estimate'] ?? 0 );
        $rates = self::tier_rates( $account['tier'] );
        if ( $estimate > 0 && $rates['request_pct'] > 0 ) {
            $amount = round( $estimate * $rates['request_pct'] );
            self::_add_commission( $marketer_id, (int) $lead['id'], 'request_created', $amount, $rates['request_pct'] * 100, [
                'order_value' => $estimate,
                'ref_type'    => 'request',
                'ref_id'      => $request_id,
                'dedupe_key'  => 'req_' . $request_id,
                'note'        => 'کمیسیون ثبت درخواست',
                'status'      => 'pending',
            ] );
        }

        self::_approve_lead_bonus( $marketer_id, (int) $lead['id'] );
    }

    public static function on_report_finalized( array $report ): void {
        global $wpdb;
        $req_id = (int) ( $report['request_id'] ?? 0 );
        if ( ! $req_id ) return;

        $marketer_id = (int) $wpdb->get_var( $wpdb->prepare(
            "SELECT marketer_id FROM {$wpdb->prefix}svc_requests WHERE id=%d", $req_id
        ) );
        if ( ! $marketer_id ) {
            $phone = self::normalize_phone( $report['phone'] ?? '' );
            $lead = $phone ? self::find_lead_for_phone( $phone ) : null;
            if ( $lead ) {
                $marketer_id = (int) $lead['marketer_id'];
                $wpdb->update( "{$wpdb->prefix}svc_requests", [ 'marketer_id' => $marketer_id ], [ 'id' => $req_id ] );
            }
        }
        if ( ! $marketer_id ) return;

        $account = self::get_by_id( $marketer_id );
        if ( ! $account ) return;

        $total = (float) ( $report['total'] ?? 0 );
        if ( $total <= 0 ) return;

        $lead = $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}svc_marketer_leads WHERE marketer_id=%d AND request_id=%d LIMIT 1",
            $marketer_id, $req_id
        ), ARRAY_A );

        if ( ! $lead ) {
            $phone = self::normalize_phone( $report['phone'] ?? '' );
            $lead = $phone ? self::find_lead_for_phone( $phone, $marketer_id ) : null;
        }

        $lead_id = $lead ? (int) $lead['id'] : null;
        $rates = self::tier_rates( $account['tier'] );
        $amount = round( $total * $rates['job_pct'] );

        self::_add_commission( $marketer_id, $lead_id, 'job_completed', $amount, $rates['job_pct'] * 100, [
            'order_value' => $total,
            'ref_type'    => 'report',
            'ref_id'      => (int) ( $report['id'] ?? 0 ),
            'dedupe_key'  => 'job_' . ( $report['id'] ?? 0 ),
            'note'        => 'کمیسیون تکمیل کار و صدور فاکتور',
            'status'      => 'approved',
        ] );

        if ( $lead_id ) {
            $was_converted = ( $lead['status'] ?? '' ) === 'converted';
            $wpdb->update( "{$wpdb->prefix}svc_marketer_leads", [
                'status'       => 'converted',
                'order_value'  => $total,
                'converted_at' => current_time( 'mysql' ),
                'request_id'   => $req_id,
            ], [ 'id' => $lead_id ] );

            if ( ! $was_converted ) {
                $wpdb->query( $wpdb->prepare(
                    "UPDATE {$wpdb->prefix}svc_marketer_accounts SET converted_leads = converted_leads + 1 WHERE id=%d",
                    $marketer_id
                ) );
                self::recalc_tier( $marketer_id );
            }
        }
    }

    private static function _approve_lead_bonus( int $marketer_id, int $lead_id ): void {
        global $wpdb;
        $wpdb->update( "{$wpdb->prefix}svc_marketer_commissions", [
            'status'      => 'approved',
            'approved_at' => current_time( 'mysql' ),
        ], [
            'marketer_id' => $marketer_id,
            'lead_id'     => $lead_id,
            'event_type'  => 'lead_introduced',
            'status'      => 'pending',
        ] );
        self::_sync_balances( $marketer_id );
    }

    private static function _add_commission( int $marketer_id, ?int $lead_id, string $event, float $amount, float $pct, array $opts ): ?array {
        global $wpdb;
        if ( $amount <= 0 ) return null;

        $dedupe = $opts['dedupe_key'] ?? '';
        if ( $dedupe ) {
            $exists = (int) $wpdb->get_var( $wpdb->prepare(
                "SELECT COUNT(*) FROM {$wpdb->prefix}svc_marketer_commissions WHERE marketer_id=%d AND dedupe_key=%s",
                $marketer_id, $dedupe
            ) );
            if ( $exists ) return null;
        }

        $status = $opts['status'] ?? 'pending';
        $wpdb->insert( "{$wpdb->prefix}svc_marketer_commissions", [
            'marketer_id'        => $marketer_id,
            'lead_id'            => $lead_id,
            'event_type'         => $event,
            'order_value'        => (float) ( $opts['order_value'] ?? 0 ),
            'commission_pct'     => $pct,
            'commission_amount'  => $amount,
            'status'             => $status,
            'ref_type'           => $opts['ref_type'] ?? null,
            'ref_id'             => $opts['ref_id'] ?? null,
            'dedupe_key'         => $dedupe ?: null,
            'note'               => $opts['note'] ?? '',
            'approved_at'        => $status === 'approved' ? current_time( 'mysql' ) : null,
        ] );

        self::_sync_balances( $marketer_id );
        return [ 'id' => (int) $wpdb->insert_id, 'amount' => $amount ];
    }

    private static function _sync_balances( int $marketer_id ): void {
        global $wpdb;
        $pre = $wpdb->prefix;

        $pending = (float) $wpdb->get_var( $wpdb->prepare(
            "SELECT COALESCE(SUM(commission_amount),0) FROM {$pre}svc_marketer_commissions
             WHERE marketer_id=%d AND status IN ('pending','approved')", $marketer_id
        ) );
        $paid_comm = (float) $wpdb->get_var( $wpdb->prepare(
            "SELECT COALESCE(SUM(commission_amount),0) FROM {$pre}svc_marketer_commissions
             WHERE marketer_id=%d AND status='paid'", $marketer_id
        ) );
        $paid_out = (float) $wpdb->get_var( $wpdb->prepare(
            "SELECT COALESCE(SUM(amount),0) FROM {$pre}svc_marketer_payouts
             WHERE marketer_id=%d AND status='paid'", $marketer_id
        ) );
        $total_earned = (float) $wpdb->get_var( $wpdb->prepare(
            "SELECT COALESCE(SUM(commission_amount),0) FROM {$pre}svc_marketer_commissions
             WHERE marketer_id=%d AND status IN ('approved','paid')", $marketer_id
        ) );

        $balance_pending = max( 0, $pending + $paid_comm - $paid_out );

        $wpdb->update( "{$pre}svc_marketer_accounts", [
            'balance_pending' => $balance_pending,
            'balance_paid'    => $paid_out,
            'total_earned'    => $total_earned,
        ], [ 'id' => $marketer_id ] );
    }

    public static function sync_balances( int $marketer_id ): void {
        self::_sync_balances( $marketer_id );
    }

    public static function request_payout( int $marketer_id, array $bank = [] ): array {
        global $wpdb;
        $account = self::get_by_id( $marketer_id );
        if ( ! $account ) {
            return [ 'success' => false, 'message' => 'حساب یافت نشد' ];
        }

        $min_payout = 200000;
        $balance = (float) $account['balance_pending'];
        if ( $balance < $min_payout ) {
            return [ 'success' => false, 'message' => 'حداقل مبلغ تسویه ' . number_format( $min_payout ) . ' تومان است' ];
        }

        $open = (int) $wpdb->get_var( $wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->prefix}svc_marketer_payouts WHERE marketer_id=%d AND status IN ('requested','processing')",
            $marketer_id
        ) );
        if ( $open ) {
            return [ 'success' => false, 'message' => 'درخواست تسویه قبلی در حال بررسی است' ];
        }

        $bank_info = [
            'holder'  => sanitize_text_field( $bank['holder'] ?? $account['display_name'] ),
            'iban'    => sanitize_text_field( $bank['iban'] ?? '' ),
            'bank'    => sanitize_text_field( $bank['bank'] ?? '' ),
            'card'    => sanitize_text_field( $bank['card'] ?? '' ),
        ];

        if ( ! empty( $bank_info['iban'] ) || ! empty( $bank_info['card'] ) ) {
            $wpdb->update( "{$wpdb->prefix}svc_marketer_accounts", [
                'bank_info' => wp_json_encode( $bank_info, JSON_UNESCAPED_UNICODE ),
            ], [ 'id' => $marketer_id ] );
        }

        $wpdb->insert( "{$wpdb->prefix}svc_marketer_payouts", [
            'marketer_id'   => $marketer_id,
            'amount'        => $balance,
            'status'        => 'requested',
            'bank_snapshot' => wp_json_encode( $bank_info, JSON_UNESCAPED_UNICODE ),
        ] );

        return [ 'success' => true, 'payout_id' => (int) $wpdb->insert_id, 'amount' => $balance ];
    }

    public static function dashboard( int $marketer_id ): array {
        global $wpdb;
        $pre = $wpdb->prefix;
        $account = self::get_by_id( $marketer_id );
        if ( ! $account ) return [];

        $tier_cfg = self::tier_rates( $account['tier'] );
        $all_tiers = self::tier_config();
        $next_tier = null;
        foreach ( $all_tiers as $key => $cfg ) {
            if ( (int) $cfg['min_conv'] > (int) $account['converted_leads'] ) {
                $next_tier = [
                    'key'   => $key,
                    'label' => $cfg['label'],
                    'need'  => (int) $cfg['min_conv'] - (int) $account['converted_leads'],
                ];
                break;
            }
        }

        $leads = $wpdb->get_results( $wpdb->prepare(
            "SELECT * FROM {$pre}svc_marketer_leads WHERE marketer_id=%d ORDER BY introduced_at DESC LIMIT 50",
            $marketer_id
        ), ARRAY_A ) ?: [];

        $commissions = $wpdb->get_results( $wpdb->prepare(
            "SELECT * FROM {$pre}svc_marketer_commissions WHERE marketer_id=%d ORDER BY created_at DESC LIMIT 50",
            $marketer_id
        ), ARRAY_A ) ?: [];

        $payouts = $wpdb->get_results( $wpdb->prepare(
            "SELECT * FROM {$pre}svc_marketer_payouts WHERE marketer_id=%d ORDER BY created_at DESC LIMIT 20",
            $marketer_id
        ), ARRAY_A ) ?: [];

        $funnel = [
            'introduced'      => 0,
            'request_created' => 0,
            'converted'       => 0,
            'lost'            => 0,
        ];
        foreach ( $leads as $l ) {
            $st = $l['status'] ?? 'introduced';
            if ( isset( $funnel[ $st ] ) ) $funnel[ $st ]++;
        }

        $site = function_exists( 'site_url' ) ? site_url( 'service.php' ) : '/acc-engine/service.php';
        $share_url = $site . ( str_contains( $site, '?' ) ? '&' : '?' ) . 'mkt=' . urlencode( $account['marketer_code'] );

        $rank = 1 + (int) $wpdb->get_var( $wpdb->prepare(
            "SELECT COUNT(*) FROM {$pre}svc_marketer_accounts WHERE converted_leads > %d AND status='active'",
            (int) $account['converted_leads']
        ) );

        return [
            'account'       => $account,
            'tier_label'    => $tier_cfg['label'],
            'tier_color'    => $tier_cfg['color'],
            'tier_rates'    => $tier_cfg,
            'next_tier'     => $next_tier,
            'all_tiers'     => $all_tiers,
            'share_url'     => $share_url,
            'share_code'    => $account['marketer_code'],
            'leads'         => $leads,
            'commissions'   => $commissions,
            'payouts'       => $payouts,
            'funnel'        => $funnel,
            'rank_position' => $rank,
            'service_types' => self::service_types(),
            'min_payout'    => 200000,
            'attribution_days' => self::ATTRIBUTION_DAYS,
        ];
    }

    public static function leaderboard( int $limit = 20 ): array {
        global $wpdb;
        return $wpdb->get_results( $wpdb->prepare(
            "SELECT id, display_name, tier, converted_leads, total_earned, balance_pending, marketer_code
             FROM {$wpdb->prefix}svc_marketer_accounts
             WHERE status='active'
             ORDER BY converted_leads DESC, total_earned DESC
             LIMIT %d", $limit
        ), ARRAY_A ) ?: [];
    }
}
