<?php

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class CPM_WBS_Controller {

    private static $table = 'cp_wbs';

    public static function get_wbs_items( WP_REST_Request $request ) {
        global $wpdb;
        $project_id = $request->get_param( 'project_id' );
        
        $sql = "SELECT * FROM {$wpdb->prefix}" . self::$table;
        if ( $project_id ) {
            $items = $wpdb->get_results( $wpdb->prepare( "{$sql} WHERE project_id = %d ORDER BY sort_index ASC, id ASC", (int)$project_id ), ARRAY_A );
        } else {
            $items = $wpdb->get_results( "{$sql} ORDER BY project_id ASC, sort_index ASC, id ASC", ARRAY_A );
        }

        return rest_ensure_response( array_map( ['self', 'map_wbs'], $items ) );
    }

    public static function get_wbs_item( WP_REST_Request $request ) {
        global $wpdb;
        $item = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}" . self::$table . " WHERE id = %d", (int)$request['id'] ), ARRAY_A );
        if ( ! $item ) return new WP_Error( 'not_found', 'WBS not found', ['status' => 404] );
        return rest_ensure_response( self::map_wbs( $item ) );
    }

    public static function create_wbs( WP_REST_Request $request ) {
        global $wpdb;
        $params = $request->get_json_params();
        if ( empty($params['project_id']) || empty($params['code']) || empty($params['name']) ) {
            return new WP_Error( 'invalid_data', 'Missing fields', ['status' => 400] );
        }

        $data = [
            'project_id' => (int)$params['project_id'],
            'code'       => sanitize_text_field($params['code']),
            'name'       => sanitize_text_field($params['name']),
            'sort_index' => isset($params['sort_index']) ? (int)$params['sort_index'] : 0,
            'parent_id'  => isset($params['parent_id']) && $params['parent_id'] !== '' ? (int)$params['parent_id'] : null
        ];

        $wpdb->insert( $wpdb->prefix . self::$table, $data );
        $item = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}" . self::$table . " WHERE id = %d", $wpdb->insert_id ), ARRAY_A );
        return new WP_REST_Response( self::map_wbs($item), 201 );
    }

    public static function update_wbs( WP_REST_Request $request ) {
        global $wpdb;
        $id = (int)$request['id'];
        $existing = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}" . self::$table . " WHERE id = %d", $id ), ARRAY_A );
        if ( ! $existing ) return new WP_Error( 'not_found', 'WBS not found', ['status' => 404] );

        $params = $request->get_json_params();
        $data = [];
        $fields = ['project_id', 'code', 'name', 'sort_index'];
        
        foreach($fields as $f) if(isset($params[$f])) $data[$f] = $params[$f];
        if(isset($params['parent_id'])) $data['parent_id'] = $params['parent_id'] === '' ? null : (int)$params['parent_id'];

        if(empty($data)) return new WP_Error( 'no_data', 'No fields to update', ['status' => 400] );
        
        $wpdb->update( $wpdb->prefix . self::$table, $data, ['id' => $id] );
        $item = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}" . self::$table . " WHERE id = %d", $id ), ARRAY_A );
        return rest_ensure_response( self::map_wbs($item) );
    }

    public static function delete_wbs( WP_REST_Request $request ) {
        global $wpdb;
        $id = (int)$request['id'];
        if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}" . self::$table . " WHERE id = %d", $id ) ) ) 
            return new WP_Error( 'not_found', 'Not found', ['status' => 404] );
        
        $wpdb->delete( $wpdb->prefix . self::$table, ['id' => $id] );
        return rest_ensure_response( ['deleted' => true, 'id' => $id] );
    }

    public static function map_wbs( $r ) {
        return [
            'id' => (int)$r['id'],
            'project_id' => (int)$r['project_id'],
            'code' => $r['code'],
            'name' => $r['name'],
            'parent_id' => $r['parent_id'] ? (int)$r['parent_id'] : null,
            'sort_index' => (int)$r['sort_index']
        ];
    }
}
