<?php
/**
 * Acc_Portal_Accounting_Controller — API حسابداری مجزا per-portal
 */
if ( ! defined( 'ABSPATH' ) ) exit;

require_once ACC_PATH . 'includes/helpers/acc-portal-accounting.php';

class Acc_Portal_Accounting_Controller {

    public static function register_routes(): void {
        $ns  = 'acc/v1';
        $jwt = 'acc_jwt_check_permission';

        register_rest_route( $ns, '/portal-acct/portals', [
            'methods' => 'GET', 'callback' => [ __CLASS__, 'list_portals' ], 'permission_callback' => $jwt,
        ] );

        register_rest_route( $ns, '/portal-acct/(?P<module>[a-z_]+)/meta', [
            'methods' => 'GET', 'callback' => [ __CLASS__, 'meta' ], 'permission_callback' => $jwt,
        ] );
        register_rest_route( $ns, '/portal-acct/(?P<module>[a-z_]+)/dashboard', [
            'methods' => 'GET', 'callback' => [ __CLASS__, 'dashboard' ], 'permission_callback' => $jwt,
        ] );
        register_rest_route( $ns, '/portal-acct/(?P<module>[a-z_]+)/documents', [
            'methods' => 'GET', 'callback' => [ __CLASS__, 'documents' ], 'permission_callback' => $jwt,
        ] );
        register_rest_route( $ns, '/portal-acct/(?P<module>[a-z_]+)/documents/(?P<id>\d+)', [
            'methods' => 'GET', 'callback' => [ __CLASS__, 'document_detail' ], 'permission_callback' => $jwt,
        ] );
        register_rest_route( $ns, '/portal-acct/(?P<module>[a-z_]+)/ledger', [
            'methods' => 'GET', 'callback' => [ __CLASS__, 'ledger' ], 'permission_callback' => $jwt,
        ] );
        register_rest_route( $ns, '/portal-acct/(?P<module>[a-z_]+)/trial-balance', [
            'methods' => 'GET', 'callback' => [ __CLASS__, 'trial_balance' ], 'permission_callback' => $jwt,
        ] );
        register_rest_route( $ns, '/portal-acct/(?P<module>[a-z_]+)/income-statement', [
            'methods' => 'GET', 'callback' => [ __CLASS__, 'income_statement' ], 'permission_callback' => $jwt,
        ] );
        register_rest_route( $ns, '/portal-acct/(?P<module>[a-z_]+)/chart', [
            'methods' => 'GET', 'callback' => [ __CLASS__, 'chart' ], 'permission_callback' => $jwt,
        ] );
        register_rest_route( $ns, '/portal-acct/(?P<module>[a-z_]+)/portal', [
            [ 'methods' => 'GET', 'callback' => [ __CLASS__, 'get_portal_settings' ], 'permission_callback' => $jwt ],
            [ 'methods' => 'PUT', 'callback' => [ __CLASS__, 'save_portal_settings' ], 'permission_callback' => $jwt ],
        ] );
        register_rest_route( $ns, '/portal-acct/(?P<module>[a-z_]+)/confirm/(?P<id>\d+)', [
            'methods' => 'POST', 'callback' => [ __CLASS__, 'confirm' ], 'permission_callback' => $jwt,
        ] );
        register_rest_route( $ns, '/portal-acct/election/post-tx/(?P<tx_id>\d+)', [
            'methods' => 'POST', 'callback' => [ __CLASS__, 'post_election_tx' ], 'permission_callback' => $jwt,
        ] );
        register_rest_route( $ns, '/portal-acct/install', [
            'methods' => 'POST', 'callback' => [ __CLASS__, 'install' ], 'permission_callback' => $jwt,
        ] );
    }

    private static function deny( string $module ): ?WP_REST_Response {
        if ( ! Acc_Portal_Accounting::get_portal( $module ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'پورتال ناشناخته' ], 404 );
        }
        $uid = (int) get_current_user_id();
        if ( ! self::can_view( $module, $uid ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'دسترسی حسابداری این پورتال را ندارید' ], 403 );
        }
        return null;
    }

    private static function can_view( string $module, int $uid ): bool {
        if ( $uid <= 0 ) {
            return false;
        }
        if ( function_exists( 'acl_user_is_super_admin' ) && acl_user_is_super_admin( $uid ) ) {
            return true;
        }
        switch ( $module ) {
            case 'arag_shop':
                if ( class_exists( 'Arag_Erp' ) ) {
                    return Arag_Erp::erp_can_view();
                }
                return acl_user_can( $uid, 'arag.erp.view' ) || acl_user_can( $uid, 'arag.accounting' );
            case 'service_portal':
                return acl_user_can( $uid, 'service.accounting' ) || acl_user_can( $uid, 'service.view' );
            case 'election':
                if ( class_exists( 'Election_Havadaran' ) ) {
                    return Election_Havadaran::can_financial( $uid ) || Election_Havadaran::can_manage( $uid );
                }
                return acl_user_can( $uid, 'election.accounting' ) || acl_user_can( $uid, 'election.dept.financial' );
            default:
                return acl_user_can( $uid, $module . '.accounting' );
        }
    }

    private static function can_post( string $module, int $uid ): bool {
        if ( function_exists( 'acl_user_is_super_admin' ) && acl_user_is_super_admin( $uid ) ) {
            return true;
        }
        switch ( $module ) {
            case 'arag_shop':
                return class_exists( 'Arag_Erp' ) && Arag_Erp::erp_can_post();
            case 'service_portal':
                return acl_user_can( $uid, 'service.accounting.post' );
            case 'election':
                return acl_user_can( $uid, 'election.accounting.post' )
                    || ( class_exists( 'Election_Havadaran' ) && Election_Havadaran::can_financial( $uid ) );
            default:
                return acl_user_can( $uid, $module . '.accounting.post' );
        }
    }

    public static function list_portals(): WP_REST_Response {
        return new WP_REST_Response( [ 'success' => true, 'data' => Acc_Portal_Accounting::list_portals() ] );
    }

    public static function meta( WP_REST_Request $req ): WP_REST_Response {
        $module = sanitize_key( $req->get_param( 'module' ) );
        if ( $d = self::deny( $module ) ) {
            return $d;
        }
        return new WP_REST_Response( [
            'success'  => true,
            'meta'     => Acc_Portal_Accounting::meta( $module ),
            'portal'   => Acc_Portal_Accounting::portal_settings( $module ),
            'can_post' => self::can_post( $module, (int) get_current_user_id() ),
        ] );
    }

    public static function dashboard( WP_REST_Request $req ): WP_REST_Response {
        $module = sanitize_key( $req->get_param( 'module' ) );
        if ( $d = self::deny( $module ) ) {
            return $d;
        }
        return new WP_REST_Response( [ 'success' => true, 'data' => Acc_Portal_Accounting::dashboard( $module ) ] );
    }

    public static function documents( WP_REST_Request $req ): WP_REST_Response {
        $module = sanitize_key( $req->get_param( 'module' ) );
        if ( $d = self::deny( $module ) ) {
            return $d;
        }
        $state = sanitize_text_field( $req->get_param( 'state' ) ?? '' );
        $limit = min( 200, max( 1, (int) ( $req->get_param( 'limit' ) ?? 80 ) ) );
        return new WP_REST_Response( [
            'success' => true,
            'data'    => Acc_Portal_Accounting::list_documents( $module, $limit, $state ),
            'meta'    => Acc_Portal_Accounting::meta( $module ),
        ] );
    }

    public static function document_detail( WP_REST_Request $req ): WP_REST_Response {
        $module = sanitize_key( $req->get_param( 'module' ) );
        if ( $d = self::deny( $module ) ) {
            return $d;
        }
        $row = Acc_Portal_Accounting::event_detail( $module, (int) $req->get_param( 'id' ) );
        if ( ! $row ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'سند یافت نشد' ], 404 );
        }
        return new WP_REST_Response( [ 'success' => true, 'data' => $row ] );
    }

    public static function ledger( WP_REST_Request $req ): WP_REST_Response {
        $module = sanitize_key( $req->get_param( 'module' ) );
        if ( $d = self::deny( $module ) ) {
            return $d;
        }
        $from  = $req->get_param( 'date_from' ) ?: null;
        $to    = $req->get_param( 'date_to' ) ?: null;
        $limit = min( 500, max( 1, (int) ( $req->get_param( 'limit' ) ?? 200 ) ) );
        return new WP_REST_Response( [
            'success' => true,
            'data'    => Acc_Portal_Accounting::ledger( $module, $from ? sanitize_text_field( $from ) : null, $to ? sanitize_text_field( $to ) : null, $limit ),
            'meta'    => Acc_Portal_Accounting::meta( $module ),
        ] );
    }

    public static function trial_balance( WP_REST_Request $req ): WP_REST_Response {
        $module = sanitize_key( $req->get_param( 'module' ) );
        if ( $d = self::deny( $module ) ) {
            return $d;
        }
        $from = $req->get_param( 'date_from' ) ?: null;
        $to   = $req->get_param( 'date_to' ) ?: null;
        return new WP_REST_Response( [
            'success' => true,
            'data'    => Acc_Portal_Accounting::trial_balance( $module, $from ? sanitize_text_field( $from ) : null, $to ? sanitize_text_field( $to ) : null ),
        ] );
    }

    public static function income_statement( WP_REST_Request $req ): WP_REST_Response {
        $module = sanitize_key( $req->get_param( 'module' ) );
        if ( $d = self::deny( $module ) ) {
            return $d;
        }
        $from = $req->get_param( 'date_from' ) ?: null;
        $to   = $req->get_param( 'date_to' ) ?: null;
        return new WP_REST_Response( [
            'success' => true,
            'data'    => Acc_Portal_Accounting::income_statement( $module, $from ? sanitize_text_field( $from ) : null, $to ? sanitize_text_field( $to ) : null ),
        ] );
    }

    public static function chart( WP_REST_Request $req ): WP_REST_Response {
        $module = sanitize_key( $req->get_param( 'module' ) );
        if ( $d = self::deny( $module ) ) {
            return $d;
        }
        Acc_Portal_Accounting::ensure_chart( $module );
        return new WP_REST_Response( [
            'success' => true,
            'data'    => Acc_Portal_Accounting::chart_tree( $module ),
            'meta'    => Acc_Portal_Accounting::meta( $module ),
        ] );
    }

    public static function get_portal_settings( WP_REST_Request $req ): WP_REST_Response {
        $module = sanitize_key( $req->get_param( 'module' ) );
        if ( $d = self::deny( $module ) ) {
            return $d;
        }
        return new WP_REST_Response( [ 'success' => true, 'data' => Acc_Portal_Accounting::portal_settings( $module ) ] );
    }

    public static function save_portal_settings( WP_REST_Request $req ): WP_REST_Response {
        $module = sanitize_key( $req->get_param( 'module' ) );
        if ( $d = self::deny( $module ) ) {
            return $d;
        }
        if ( ! self::can_post( $module, (int) get_current_user_id() ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'فقط حسابدار می‌تواند تنظیمات را ذخیره کند' ], 403 );
        }
        $body = $req->get_json_params() ?: [];
        Acc_Portal_Accounting::save_portal_settings( $module, $body );
        return new WP_REST_Response( [ 'success' => true, 'data' => Acc_Portal_Accounting::portal_settings( $module ) ] );
    }

    public static function confirm( WP_REST_Request $req ): WP_REST_Response {
        $module = sanitize_key( $req->get_param( 'module' ) );
        if ( $d = self::deny( $module ) ) {
            return $d;
        }
        if ( ! self::can_post( $module, (int) get_current_user_id() ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'دسترسی صدور ندارید' ], 403 );
        }
        $res = Acc_Portal_Accounting::confirm_event( $module, (int) $req->get_param( 'id' ) );
        $code = (int) ( $res['http'] ?? 200 );
        unset( $res['http'] );
        return new WP_REST_Response( $res, ! empty( $res['success'] ) ? 200 : $code );
    }

    public static function post_election_tx( WP_REST_Request $req ): WP_REST_Response {
        $module = 'election';
        if ( $d = self::deny( $module ) ) {
            return $d;
        }
        if ( ! self::can_post( $module, (int) get_current_user_id() ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'دسترسی صدور ندارید' ], 403 );
        }
        $res = Acc_Portal_Accounting::post_election_transaction( (int) $req->get_param( 'tx_id' ) );
        return new WP_REST_Response( $res, ! empty( $res['success'] ) ? 200 : 400 );
    }

    public static function install( WP_REST_Request $req ): WP_REST_Response {
        if ( ! function_exists( 'acl_user_is_super_admin' ) || ! acl_user_is_super_admin( (int) get_current_user_id() ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'فقط مدیر کل' ], 403 );
        }
        return new WP_REST_Response( [
            'success' => true,
            'charts'  => Acc_Portal_Accounting::ensure_all_charts(),
            'portals' => Acc_Portal_Accounting::list_portals(),
        ] );
    }
}

add_action( 'rest_api_init', [ 'Acc_Portal_Accounting_Controller', 'register_routes' ] );
