<?php
if ( ! defined( 'ABSPATH' ) ) exit;

if ( ! class_exists( 'ACC_SmartFlow_Controller' ) ) {

    class ACC_SmartFlow_Controller {

        public static function get_voucher_raw( WP_REST_Request $request ) {
            $voucher_id = (int) $request['id'];
            $data = self::fetch_voucher_data( $voucher_id );
            return new WP_REST_Response( $data, 200 );
        }

        public static function get_voucher_graph( WP_REST_Request $request ) {
            $voucher_id = (int) $request['id'];
            $graph      = self::calculate_graph( $voucher_id );
            return new WP_REST_Response( $graph, 200 );
        }

        /**
         * خواندن رویداد حسابداری واقعی از ai_acc_events + ai_acc_flows
         */
        private static function fetch_voucher_data( $voucher_id ) {
            global $wpdb;
            $pre = $wpdb->prefix;
            $id  = (int) $voucher_id;

            $ev = $wpdb->get_row( $wpdb->prepare(
                "SELECT id, event_type, amount, workflow_state, posted_at, metadata, event_payload
                 FROM {$pre}ai_acc_events WHERE id = %d", $id
            ), ARRAY_A );

            if ( ! $ev ) {
                return [ 'id' => $id, 'error' => 'رویداد یافت نشد', 'lines' => [] ];
            }

            $flows = $wpdb->get_results( $wpdb->prepare(
                "SELECT f.id AS line_id, f.from_account_id, f.to_account_id, f.amount, f.description,
                        f.dimension_id, f.tag_json, f.line_no,
                        fa.account_code AS from_code, fa.account_name AS from_name,
                        ta.account_code AS to_code, ta.account_name AS to_name
                 FROM {$pre}ai_acc_flows f
                 LEFT JOIN {$pre}ai_acc_accounts fa ON fa.account_id = f.from_account_id
                 LEFT JOIN {$pre}ai_acc_accounts ta ON ta.account_id = f.to_account_id
                 WHERE f.event_id = %d ORDER BY f.line_no ASC, f.id ASC",
                $id
            ), ARRAY_A ) ?: [];

            $lines = [];
            foreach ( $flows as $f ) {
                $tags = json_decode( $f['tag_json'] ?? '{}', true ) ?: [];
                $lines[] = [
                    'line_id'          => (int) $f['line_id'],
                    'line_no'          => (int) ( $f['line_no'] ?? 0 ),
                    'account_code'     => $f['from_code'],
                    'account_name'     => $f['from_name'],
                    'counter_code'     => $f['to_code'],
                    'counter_name'     => $f['to_name'],
                    'debit'            => (float) $f['amount'],
                    'credit'           => 0,
                    'counter_debit'    => 0,
                    'counter_credit'   => (float) $f['amount'],
                    'description'      => $f['description'],
                    'dimension_id'     => $f['dimension_id'],
                    'dimension_values' => $tags['dimension_values'] ?? null,
                ];
            }

            $payload = json_decode( $ev['metadata'] ?? $ev['event_payload'] ?? '{}', true ) ?: [];

            return [
                'id'             => (int) $ev['id'],
                'number'         => 'EVT-' . $ev['id'],
                'event_type'     => $ev['event_type'],
                'workflow_state' => $ev['workflow_state'],
                'date'           => $ev['posted_at'] ?? '',
                'currency'       => 'IRT',
                'amount'         => (float) $ev['amount'],
                'payload'        => $payload,
                'lines'          => $lines,
            ];
        }

        private static function calculate_graph( $voucher_id ) {
            $raw = self::fetch_voucher_data( $voucher_id );

            $accountMap = [];
            $edges      = [];

            foreach ( $raw['lines'] ?? [] as $line ) {
                $fromKey = (string) ( $line['account_code'] ?? $line['account_name'] );
                $toKey   = (string) ( $line['counter_code'] ?? $line['counter_name'] );
                $amt     = (float) ( $line['debit'] ?? 0 );

                if ( ! isset( $accountMap[ $fromKey ] ) ) {
                    $accountMap[ $fromKey ] = [
                        'id' => 'account:' . $fromKey, 'type' => 'ACCOUNT', 'code' => $fromKey,
                        'name' => $line['account_name'] ?? $fromKey, 'debit' => 0, 'credit' => 0,
                    ];
                }
                if ( ! isset( $accountMap[ $toKey ] ) ) {
                    $accountMap[ $toKey ] = [
                        'id' => 'account:' . $toKey, 'type' => 'ACCOUNT', 'code' => $toKey,
                        'name' => $line['counter_name'] ?? $toKey, 'debit' => 0, 'credit' => 0,
                    ];
                }
                $accountMap[ $fromKey ]['debit']  += $amt;
                $accountMap[ $toKey ]['credit']   += $amt;

                $edges[] = [
                    'from'   => 'account:' . $fromKey,
                    'to'     => 'account:' . $toKey,
                    'amount' => $amt,
                    'label'  => $line['description'] ?? '',
                ];
            }

            $total_dr = array_sum( array_column( $accountMap, 'debit' ) );
            $total_cr = array_sum( array_column( $accountMap, 'credit' ) );

            return [
                'nodes' => array_values( $accountMap ),
                'edges' => $edges,
                'meta'  => [
                    'voucher_id' => $raw['id'] ?? $voucher_id,
                    'event_type' => $raw['event_type'] ?? '',
                    'balanced'   => abs( $total_dr - $total_cr ) < 0.01,
                    'total_dr'   => $total_dr,
                    'total_cr'   => $total_cr,
                ],
            ];
        }
    }
}
