<?php
/**
 * Arag_Expense — هزینه‌های دستی + گزارش مالی گراف ERP
 */
if ( ! defined( 'ABSPATH' ) ) exit;

class Arag_Expense {

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

    public static function categories(): array {
        return [
            'raw_materials' => [ 'label' => 'مواد اولیه', 'icon' => '🌿', 'color' => '#16a34a' ],
            'packaging'     => [ 'label' => 'بسته‌بندی',   'icon' => '📦', 'color' => '#ca8a04' ],
            'shipping'      => [ 'label' => 'حمل و ارسال', 'icon' => '🚚', 'color' => '#2563eb' ],
            'marketing'     => [ 'label' => 'تبلیغات',     'icon' => '📣', 'color' => '#db2777' ],
            'rent'          => [ 'label' => 'اجاره',       'icon' => '🏠', 'color' => '#7c3aed' ],
            'utilities'     => [ 'label' => 'آب/برق/گاز',  'icon' => '💡', 'color' => '#0891b2' ],
            'salary'        => [ 'label' => 'حقوق',        'icon' => '👥', 'color' => '#ea580c' ],
            'other'         => [ 'label' => 'سایر',        'icon' => '📋', 'color' => '#64748b' ],
        ];
    }

    public static function list_expenses( int $limit = 200, ?string $from = null, ?string $to = null ): array {
        global $wpdb;
        $t = self::table();
        if ( $wpdb->get_var( "SHOW TABLES LIKE '{$t}'" ) !== $t ) {
            return [];
        }
        $where = '1=1';
        $args  = [];
        if ( $from ) {
            $where .= ' AND expense_date >= %s';
            $args[] = $from;
        }
        if ( $to ) {
            $where .= ' AND expense_date <= %s';
            $args[] = $to;
        }
        $sql = "SELECT * FROM {$t} WHERE {$where} ORDER BY expense_date DESC, id DESC LIMIT {$limit}";
        if ( $args ) {
            $sql = $wpdb->prepare( $sql, ...$args );
        }
        return $wpdb->get_results( $sql, ARRAY_A ) ?: [];
    }

    public static function create( array $data, int $user_id = 0 ): array {
        global $wpdb;
        $t = self::table();
        $cats = self::categories();
        $cat = sanitize_key( $data['category'] ?? 'other' );
        if ( ! isset( $cats[ $cat ] ) ) {
            $cat = 'other';
        }
        $title = sanitize_text_field( $data['title'] ?? '' );
        $amount = (float) ( $data['amount'] ?? 0 );
        $date = sanitize_text_field( $data['expense_date'] ?? date( 'Y-m-d' ) );
        if ( $title === '' || $amount <= 0 ) {
            return [ 'success' => false, 'message' => 'عنوان و مبلغ الزامی است' ];
        }
        $wpdb->insert( $t, [
            'category'     => $cat,
            'title'        => $title,
            'amount'       => $amount,
            'expense_date' => $date,
            'notes'        => sanitize_textarea_field( $data['notes'] ?? '' ),
            'created_by'   => $user_id,
        ] );
        return [ 'success' => true, 'id' => (int) $wpdb->insert_id ];
    }

    public static function delete( int $id ): bool {
        global $wpdb;
        return (bool) $wpdb->delete( self::table(), [ 'id' => $id ] );
    }

    public static function revenue_summary( ?string $from = null, ?string $to = null ): array {
        global $wpdb;
        $ot = $wpdb->prefix . 'arag_orders';
        $where = "payment_status IN ('paid','cod')";
        $args = [];
        if ( $from ) {
            $where .= ' AND DATE(created_at) >= %s';
            $args[] = $from;
        }
        if ( $to ) {
            $where .= ' AND DATE(created_at) <= %s';
            $args[] = $to;
        }
        $sql = "SELECT COALESCE(SUM(total),0) AS total, COALESCE(SUM(subtotal),0) AS subtotal,
                COALESCE(SUM(discount_amount),0) AS discounts, COUNT(*) AS orders
                FROM {$ot} WHERE {$where}";
        if ( $args ) {
            $sql = $wpdb->prepare( $sql, ...$args );
        }
        $row = $wpdb->get_row( $sql, ARRAY_A );
        return [
            'total'     => (float) ( $row['total'] ?? 0 ),
            'subtotal'  => (float) ( $row['subtotal'] ?? 0 ),
            'discounts' => (float) ( $row['discounts'] ?? 0 ),
            'orders'    => (int) ( $row['orders'] ?? 0 ),
        ];
    }

    public static function expense_summary( ?string $from = null, ?string $to = null ): array {
        $items = self::list_expenses( 5000, $from, $to );
        $by_cat = [];
        $total = 0.0;
        foreach ( $items as $e ) {
            $c = $e['category'] ?? 'other';
            $amt = (float) $e['amount'];
            $by_cat[ $c ] = ( $by_cat[ $c ] ?? 0 ) + $amt;
            $total += $amt;
        }
        return [ 'total' => $total, 'by_category' => $by_cat, 'count' => count( $items ) ];
    }

    public static function financial_graph( ?string $from = null, ?string $to = null ): array {
        $rev = self::revenue_summary( $from, $to );
        $exp = self::expense_summary( $from, $to );
        $profit = $rev['total'] - $exp['total'];
        $margin = $rev['total'] > 0 ? round( ( $profit / $rev['total'] ) * 100, 1 ) : 0;

        $cats = self::categories();
        $expense_nodes = [];
        foreach ( $exp['by_category'] as $key => $amt ) {
            if ( $amt <= 0 ) continue;
            $meta = $cats[ $key ] ?? $cats['other'];
            $expense_nodes[] = [
                'id'    => $key,
                'label' => $meta['label'],
                'icon'  => $meta['icon'],
                'color' => $meta['color'],
                'amount'=> $amt,
            ];
        }
        usort( $expense_nodes, static fn( $a, $b ) => $b['amount'] <=> $a['amount'] );

        $break_even = $exp['total'] > 0 && $rev['orders'] > 0
            ? ceil( $exp['total'] / ( $rev['total'] / max( $rev['orders'], 1 ) ) )
            : 0;

        return [
            'revenue'       => $rev,
            'expenses'      => $exp,
            'profit'        => $profit,
            'margin_pct'    => $margin,
            'expense_nodes' => $expense_nodes,
            'flow'          => [
                [ 'from' => 'revenue', 'to' => 'expenses', 'amount' => min( $rev['total'], $exp['total'] ) ],
                [ 'from' => 'revenue', 'to' => 'profit',   'amount' => max( 0, $profit ) ],
            ],
            'break_even_orders' => $break_even,
            'period'        => [ 'from' => $from, 'to' => $to ],
        ];
    }

    public static function monthly_series( int $months = 6 ): array {
        global $wpdb;
        $ot = $wpdb->prefix . 'arag_orders';
        $out = [];
        for ( $i = $months - 1; $i >= 0; $i-- ) {
            $start = date( 'Y-m-01', strtotime( "-{$i} months" ) );
            $end   = date( 'Y-m-t', strtotime( $start ) );
            $rev   = self::revenue_summary( $start, $end );
            $exp   = self::expense_summary( $start, $end );
            $out[] = [
                'month'  => date( 'Y-m', strtotime( $start ) ),
                'label'  => self::fa_month( $start ),
                'revenue'=> $rev['total'],
                'expense'=> $exp['total'],
                'profit' => $rev['total'] - $exp['total'],
            ];
        }
        return $out;
    }

    private static function fa_month( string $date ): string {
        $months = [ '01'=>'فروردین','02'=>'اردیبهشت','03'=>'خرداد','04'=>'تیر','05'=>'مرداد','06'=>'شهریور',
                    '07'=>'مهر','08'=>'آبان','09'=>'آذر','10'=>'دی','11'=>'بهمن','12'=>'اسفند' ];
        $m = date( 'm', strtotime( $date ) );
        $y = date( 'Y', strtotime( $date ) );
        return ( $months[ $m ] ?? $m ) . ' ' . $y;
    }
}
