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

class Manfiet_Financial_Account_Manager {
    // Post type must be 20 characters or fewer for WordPress
    public const POST_TYPE = 'manfiet_fin_account';
    private const REST_NAMESPACE = 'manfi-expense-tracker/v1';

    public function __construct() {
        add_action('init', [$this, 'register_post_type']);
        add_action('rest_api_init', [$this, 'register_routes']);
    }

    public static function install() {
        self::register_post_type_static();
        flush_rewrite_rules();
    }

    public function register_post_type() {
        self::register_post_type_static();
    }

    public static function register_post_type_static() {
        register_post_type(self::POST_TYPE, [
            'labels' => [
                'name' => __('Financial Accounts', 'manfi-expense-tracker'),
                'singular_name' => __('Financial Account', 'manfi-expense-tracker'),
            ],
            'public' => false,
            'show_ui' => false,
            'show_in_menu' => false,
            'show_in_rest' => false,
            'supports' => ['title'],
            'has_archive' => false,
            'rewrite' => false,
        ]);
    }

    private function can_manage_accounts() {
        return current_user_can('manage_expenses') || current_user_can('manage_options');
    }

    public function require_manage_permission() {
        if (!$this->can_manage_accounts()) {
            return new WP_Error(
                'manfiet_financial_account_forbidden',
                __('You do not have permission to manage financial accounts.', 'manfi-expense-tracker'),
                ['status' => 403]
            );
        }

        return true;
    }

    private function get_account_label(array $account) {
        $parts = array_filter([
            $account['provider_name'] ?? '',
            $account['account_type'] ?? '',
            $account['account_number'] ?? '',
        ]);

        return implode(' - ', $parts) ?: ($account['title'] ?? '');
    }

    private function get_account_payload($account_id) {
        $post = get_post($account_id);
        if (!$post || $post->post_type !== self::POST_TYPE) {
            return null;
        }

        return [
            'id' => $post->ID,
            'title' => get_the_title($post),
            'account_type' => (string) get_post_meta($account_id, '_manfiet_account_type', true),
            'provider_name' => (string) get_post_meta($account_id, '_manfiet_provider_name', true),
            'account_number' => (string) get_post_meta($account_id, '_manfiet_account_number', true),
            'holder_name' => (string) get_post_meta($account_id, '_manfiet_holder_name', true),
            'routing_number' => (string) get_post_meta($account_id, '_manfiet_routing_number', true),
            'branch_name' => (string) get_post_meta($account_id, '_manfiet_branch_name', true),
            'note' => (string) get_post_meta($account_id, '_manfiet_account_note', true),
            'is_default' => (bool) get_post_meta($account_id, '_manfiet_account_is_default', true),
        ];
    }

    private function save_account_meta($account_id, array $payload) {
        $fields = [
            '_manfiet_account_type' => sanitize_text_field((string) ($payload['account_type'] ?? 'bank')),
            '_manfiet_provider_name' => sanitize_text_field((string) ($payload['provider_name'] ?? '')),
            '_manfiet_account_number' => sanitize_text_field((string) ($payload['account_number'] ?? '')),
            '_manfiet_holder_name' => sanitize_text_field((string) ($payload['holder_name'] ?? '')),
            '_manfiet_routing_number' => sanitize_text_field((string) ($payload['routing_number'] ?? '')),
            '_manfiet_branch_name' => sanitize_text_field((string) ($payload['branch_name'] ?? '')),
            '_manfiet_account_note' => sanitize_textarea_field((string) ($payload['note'] ?? '')),
            '_manfiet_account_is_default' => !empty($payload['is_default']) ? '1' : '0',
        ];

        foreach ($fields as $meta_key => $value) {
            update_post_meta($account_id, $meta_key, $value);
        }
    }

    public function register_routes() {
        register_rest_route(self::REST_NAMESPACE, '/financial-accounts', [
            [
                'methods' => 'GET',
                'callback' => [$this, 'rest_list_financial_accounts'],
                'permission_callback' => [$this, 'require_manage_permission'],
            ],
            [
                'methods' => 'POST',
                'callback' => [$this, 'rest_create_financial_account'],
                'permission_callback' => [$this, 'require_manage_permission'],
            ],
        ]);

        register_rest_route(self::REST_NAMESPACE, '/financial-accounts/(?P<id>\d+)', [
            [
                'methods' => 'GET',
                'callback' => [$this, 'rest_get_financial_account'],
                'permission_callback' => [$this, 'require_manage_permission'],
            ],
            [
                'methods' => 'PUT,PATCH',
                'callback' => [$this, 'rest_update_financial_account'],
                'permission_callback' => [$this, 'require_manage_permission'],
            ],
            [
                'methods' => 'DELETE',
                'callback' => [$this, 'rest_delete_financial_account'],
                'permission_callback' => [$this, 'require_manage_permission'],
            ],
        ]);
    }

    public function rest_list_financial_accounts() {
        $posts = get_posts([
            'post_type' => self::POST_TYPE,
            'post_status' => ['publish', 'draft', 'private'],
            'numberposts' => -1,
            'orderby' => 'date',
            'order' => 'DESC',
        ]);

        $items = [];
        foreach ($posts as $post) {
            $payload = $this->get_account_payload($post->ID);
            if ($payload) {
                $payload['label'] = $this->get_account_label($payload);
                $items[] = $payload;
            }
        }

        return rest_ensure_response($items);
    }

    public function rest_get_financial_account(WP_REST_Request $request) {
        $account_id = absint($request['id']);
        $payload = $this->get_account_payload($account_id);
        if (!$payload) {
            return new WP_Error('manfiet_financial_account_not_found', __('Financial account not found.', 'manfi-expense-tracker'), ['status' => 404]);
        }

        $payload['label'] = $this->get_account_label($payload);
        return rest_ensure_response($payload);
    }

    public function rest_create_financial_account(WP_REST_Request $request) {
        $data = $request->get_json_params();
        $provider_name = sanitize_text_field((string) ($data['provider_name'] ?? ''));
        $account_number = sanitize_text_field((string) ($data['account_number'] ?? ''));
        $account_type = sanitize_text_field((string) ($data['account_type'] ?? 'bank'));
        $holder_name = sanitize_text_field((string) ($data['holder_name'] ?? ''));

        // Mobile wallets require holder name + mobile number; banks require provider + account number.
        if (in_array($account_type, ['bkash', 'nagad', 'rocket'], true)) {
            if ($holder_name === '' || $account_number === '') {
                return new WP_Error('manfiet_financial_account_required', __('Holder name and mobile number are required for mobile wallets.', 'manfi-expense-tracker'), ['status' => 400]);
            }
        } else {
            if ($provider_name === '' || $account_number === '') {
                return new WP_Error('manfiet_financial_account_required', __('Provider name and account number are required.', 'manfi-expense-tracker'), ['status' => 400]);
            }
        }

        // Ensure post type is registered in REST context.
        if (!post_type_exists(self::POST_TYPE)) {
            self::register_post_type_static();
        }

        $title_parts = [];
        if ($provider_name) {
            $title_parts[] = $provider_name;
        }
        if (!$provider_name && $holder_name) {
            $title_parts[] = $holder_name;
        }
        $title_parts[] = $account_number ?: '';
        $post_title = trim(implode(' - ', array_filter($title_parts)));

        $post_id = wp_insert_post([
            'post_type' => self::POST_TYPE,
            'post_status' => 'publish',
            'post_title' => $post_title,
            'post_content' => '',
            'post_author' => get_current_user_id(),
        ], true);

        if (is_wp_error($post_id) || !$post_id) {
            if (is_wp_error($post_id)) {
                return $post_id;
            }

            return new WP_Error('manfiet_financial_account_insert_failed', __('Could not insert post into the database.', 'manfi-expense-tracker'), ['status' => 500]);
        }

        $this->save_account_meta($post_id, [
            'account_type' => $account_type,
            'provider_name' => $provider_name,
            'account_number' => $account_number,
            'holder_name' => $data['holder_name'] ?? '',
            'routing_number' => $data['routing_number'] ?? '',
            'branch_name' => $data['branch_name'] ?? '',
            'note' => $data['note'] ?? '',
            'is_default' => !empty($data['is_default']),
        ]);

        $payload = $this->get_account_payload($post_id);
        $payload['label'] = $this->get_account_label($payload);

        return rest_ensure_response($payload);
    }

    public function rest_update_financial_account(WP_REST_Request $request) {
        $account_id = absint($request['id']);
        if (!$this->get_account_payload($account_id)) {
            return new WP_Error('manfiet_financial_account_not_found', __('Financial account not found.', 'manfi-expense-tracker'), ['status' => 404]);
        }

        $data = $request->get_json_params();
        $provider_name = sanitize_text_field((string) ($data['provider_name'] ?? ''));
        $account_number = sanitize_text_field((string) ($data['account_number'] ?? ''));
        $account_type = sanitize_text_field((string) ($data['account_type'] ?? 'bank'));

        $holder_name = sanitize_text_field((string) ($data['holder_name'] ?? ''));

        if (in_array($account_type, ['bkash', 'nagad', 'rocket'], true)) {
            if ($holder_name === '' || $account_number === '') {
                return new WP_Error('manfiet_financial_account_required', __('Holder name and mobile number are required for mobile wallets.', 'manfi-expense-tracker'), ['status' => 400]);
            }
        } else {
            if ($provider_name === '' || $account_number === '') {
                return new WP_Error('manfiet_financial_account_required', __('Provider name and account number are required.', 'manfi-expense-tracker'), ['status' => 400]);
            }
        }

        $title_parts = [];
        if ($provider_name) {
            $title_parts[] = $provider_name;
        }
        if (!$provider_name && $holder_name) {
            $title_parts[] = $holder_name;
        }
        $title_parts[] = $account_number ?: '';
        $post_title = trim(implode(' - ', array_filter($title_parts)));

        wp_update_post([
            'ID' => $account_id,
            'post_title' => $post_title,
        ]);

        $this->save_account_meta($account_id, [
            'account_type' => $account_type,
            'provider_name' => $provider_name,
            'account_number' => $account_number,
            'holder_name' => $data['holder_name'] ?? '',
            'routing_number' => $data['routing_number'] ?? '',
            'branch_name' => $data['branch_name'] ?? '',
            'note' => $data['note'] ?? '',
            'is_default' => !empty($data['is_default']),
        ]);

        $payload = $this->get_account_payload($account_id);
        $payload['label'] = $this->get_account_label($payload);

        return rest_ensure_response($payload);
    }

    public function rest_delete_financial_account(WP_REST_Request $request) {
        $account_id = absint($request['id']);
        $result = wp_trash_post($account_id);
        if (!$result) {
            return new WP_Error('manfiet_financial_account_delete_failed', __('Failed to delete financial account.', 'manfi-expense-tracker'), ['status' => 400]);
        }

        return rest_ensure_response(['deleted' => true]);
    }
}
