<?php
/**
 * SR_Supplier_Controller — پورتال تأمین‌کننده (کاتالوگ، سفارشات، پروفایل)
 */
if ( ! defined( 'ABSPATH' ) ) exit;

require_once ACC_PATH . 'includes/helpers/svc-supplier.php';

class SR_Supplier_Controller {

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

        register_rest_route( $ns, '/service/supplier/me', [
            'methods'             => 'GET',
            'callback'            => [ __CLASS__, 'get_me' ],
            'permission_callback' => [ __CLASS__, 'supplier_perm' ],
        ] );

        register_rest_route( $ns, '/service/supplier/profile', [
            'methods'             => 'PUT',
            'callback'            => [ __CLASS__, 'update_profile' ],
            'permission_callback' => [ __CLASS__, 'supplier_perm' ],
        ] );

        register_rest_route( $ns, '/service/supplier/catalog', [
            'methods'             => 'GET',
            'callback'            => [ __CLASS__, 'list_catalog' ],
            'permission_callback' => [ __CLASS__, 'supplier_perm' ],
        ] );

        register_rest_route( $ns, '/service/supplier/catalog', [
            'methods'             => 'POST',
            'callback'            => [ __CLASS__, 'create_catalog_item' ],
            'permission_callback' => [ __CLASS__, 'supplier_perm' ],
        ] );

        register_rest_route( $ns, '/service/supplier/catalog/(?P<id>\d+)', [
            'methods'             => 'PUT',
            'callback'            => [ __CLASS__, 'update_catalog_item' ],
            'permission_callback' => [ __CLASS__, 'supplier_perm' ],
        ] );

        register_rest_route( $ns, '/service/supplier/catalog/(?P<id>\d+)', [
            'methods'             => 'DELETE',
            'callback'            => [ __CLASS__, 'delete_catalog_item' ],
            'permission_callback' => [ __CLASS__, 'supplier_perm' ],
        ] );

        register_rest_route( $ns, '/service/supplier/orders', [
            'methods'             => 'GET',
            'callback'            => [ __CLASS__, 'list_orders' ],
            'permission_callback' => [ __CLASS__, 'supplier_perm' ],
        ] );

        register_rest_route( $ns, '/service/supplier/orders/open', [
            'methods'             => 'GET',
            'callback'            => [ __CLASS__, 'list_open_orders' ],
            'permission_callback' => [ __CLASS__, 'supplier_perm' ],
        ] );

        register_rest_route( $ns, '/service/supplier/orders/(?P<id>\d+)', [
            'methods'             => 'PUT',
            'callback'            => [ __CLASS__, 'update_order' ],
            'permission_callback' => [ __CLASS__, 'supplier_perm' ],
        ] );

        register_rest_route( $ns, '/service/supplier/orders/(?P<id>\d+)/claim', [
            'methods'             => 'POST',
            'callback'            => [ __CLASS__, 'claim_order' ],
            'permission_callback' => [ __CLASS__, 'supplier_perm' ],
        ] );

        register_rest_route( $ns, '/service/supplier/catalog/all', [
            'methods'             => 'GET',
            'callback'            => [ __CLASS__, 'admin_list_all_catalog' ],
            'permission_callback' => [ __CLASS__, 'admin_perm' ],
        ] );
    }

    public static function supplier_perm(): bool {
        $uid = get_current_user_id();
        return $uid > 0 && Svc_Supplier::is_supplier( $uid );
    }

    public static function admin_perm(): bool {
        $uid = get_current_user_id();
        if ( $uid <= 0 ) return false;
        if ( function_exists( 'acl_user_is_super_admin' ) && acl_user_is_super_admin( $uid ) ) {
            return true;
        }
        return function_exists( 'acl_user_can' ) && acl_user_can( $uid, 'service.manage' );
    }

    private static function uid(): int {
        return (int) get_current_user_id();
    }

    public static function get_me( WP_REST_Request $req ): WP_REST_Response {
        $uid = self::uid();
        $profile = Svc_Supplier::ensure_profile( $uid );
        $stats   = Svc_Supplier::catalog_stats( $uid );
        $orders  = self::_order_counts( $uid );

        return new WP_REST_Response( [
            'success' => true,
            'data'    => [
                'user_id'      => $uid,
                'profile'      => self::_format_profile( $profile ),
                'catalog_stats'=> $stats,
                'order_stats'  => $orders,
                'item_types'   => Svc_Supplier::item_types(),
            ],
        ], 200 );
    }

    public static function update_profile( WP_REST_Request $req ): WP_REST_Response {
        $uid = self::uid();
        Svc_Supplier::ensure_profile( $uid );
        $body = $req->get_json_params() ?: [];

        $allowed = [ 'company_name', 'contact_name', 'phone', 'email', 'address', 'city', 'description', 'is_active' ];
        $update  = [];
        foreach ( $allowed as $k ) {
            if ( array_key_exists( $k, $body ) ) {
                $update[ $k ] = is_string( $body[ $k ] ) ? sanitize_text_field( $body[ $k ] ) : $body[ $k ];
            }
        }
        if ( isset( $update['is_active'] ) ) {
            $update['is_active'] = (int) (bool) $update['is_active'];
        }
        if ( empty( $update ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'داده‌ای ارسال نشد' ], 400 );
        }

        global $wpdb;
        $wpdb->update( Svc_Supplier::profile_table(), $update, [ 'user_id' => $uid ] );
        $profile = Svc_Supplier::get_profile( $uid );

        return new WP_REST_Response( [
            'success' => true,
            'data'    => self::_format_profile( $profile ),
        ], 200 );
    }

    public static function list_catalog( WP_REST_Request $req ): WP_REST_Response {
        $uid  = self::uid();
        $type = sanitize_text_field( $req->get_param( 'type' ) ?? '' );
        $q    = sanitize_text_field( $req->get_param( 'q' ) ?? '' );

        global $wpdb;
        $t   = Svc_Supplier::catalog_table();
        $sql = "SELECT * FROM {$t} WHERE supplier_user_id = %d";
        $args = [ $uid ];

        if ( $type && isset( Svc_Supplier::item_types()[ $type ] ) ) {
            $sql .= ' AND item_type = %s';
            $args[] = $type;
        }
        if ( $q !== '' ) {
            $like = '%' . $wpdb->esc_like( $q ) . '%';
            $sql .= ' AND (name LIKE %s OR sku LIKE %s OR description LIKE %s)';
            $args[] = $like;
            $args[] = $like;
            $args[] = $like;
        }
        $sql .= ' ORDER BY updated_at DESC, id DESC';

        $rows = $wpdb->get_results( $wpdb->prepare( $sql, ...$args ), ARRAY_A ) ?: [];

        return new WP_REST_Response( [
            'success' => true,
            'data'    => array_map( [ __CLASS__, '_format_catalog' ], $rows ),
        ], 200 );
    }

    public static function create_catalog_item( WP_REST_Request $req ): WP_REST_Response {
        $uid  = self::uid();
        $body = $req->get_json_params() ?: [];
        $item = self::_validate_catalog_payload( $body );
        if ( is_wp_error( $item ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => $item->get_error_message() ], 400 );
        }

        global $wpdb;
        $item['supplier_user_id'] = $uid;
        $wpdb->insert( Svc_Supplier::catalog_table(), $item );
        $id = (int) $wpdb->insert_id;
        $row = $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM " . Svc_Supplier::catalog_table() . " WHERE id = %d", $id
        ), ARRAY_A );

        return new WP_REST_Response( [
            'success' => true,
            'data'    => self::_format_catalog( $row ),
        ], 201 );
    }

    public static function update_catalog_item( WP_REST_Request $req ): WP_REST_Response {
        $uid = self::uid();
        $id  = (int) $req['id'];
        $row = self::_get_own_catalog( $id, $uid );
        if ( ! $row ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'آیتم یافت نشد' ], 404 );
        }

        $body = $req->get_json_params() ?: [];
        $item = self::_validate_catalog_payload( $body, true );
        if ( is_wp_error( $item ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => $item->get_error_message() ], 400 );
        }
        if ( empty( $item ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'داده‌ای ارسال نشد' ], 400 );
        }

        global $wpdb;
        $wpdb->update( Svc_Supplier::catalog_table(), $item, [ 'id' => $id, 'supplier_user_id' => $uid ] );
        $row = self::_get_own_catalog( $id, $uid );

        return new WP_REST_Response( [
            'success' => true,
            'data'    => self::_format_catalog( $row ),
        ], 200 );
    }

    public static function delete_catalog_item( WP_REST_Request $req ): WP_REST_Response {
        $uid = self::uid();
        $id  = (int) $req['id'];
        if ( ! self::_get_own_catalog( $id, $uid ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'آیتم یافت نشد' ], 404 );
        }
        global $wpdb;
        $wpdb->delete( Svc_Supplier::catalog_table(), [ 'id' => $id, 'supplier_user_id' => $uid ] );

        return new WP_REST_Response( [ 'success' => true ], 200 );
    }

    public static function list_orders( WP_REST_Request $req ): WP_REST_Response {
        $uid    = self::uid();
        $status = sanitize_text_field( $req->get_param( 'status' ) ?? '' );

        global $wpdb;
        $t = $wpdb->prefix . 'svc_parts_orders';
        if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $t ) ) !== $t ) {
            return new WP_REST_Response( [ 'success' => true, 'data' => [] ], 200 );
        }

        $sql  = "SELECT o.*, r.id AS request_id, r.service_type, r.status AS request_status
                 FROM {$t} o
                 LEFT JOIN {$wpdb->prefix}svc_requests r ON r.id = o.request_id
                 WHERE o.supplier_id = %d";
        $args = [ $uid ];
        if ( $status ) {
            $sql .= ' AND o.status = %s';
            $args[] = $status;
        }
        $sql .= ' ORDER BY o.id DESC LIMIT 100';
        $rows = $wpdb->get_results( $wpdb->prepare( $sql, ...$args ), ARRAY_A ) ?: [];

        return new WP_REST_Response( [
            'success' => true,
            'data'    => array_map( [ __CLASS__, '_format_order' ], $rows ),
        ], 200 );
    }

    public static function list_open_orders( WP_REST_Request $req ): WP_REST_Response {
        $uid = self::uid();

        global $wpdb;
        $ot = $wpdb->prefix . 'svc_parts_orders';
        $ct = Svc_Supplier::catalog_table();
        if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $ot ) ) !== $ot ) {
            return new WP_REST_Response( [ 'success' => true, 'data' => [] ], 200 );
        }

        $skus = $wpdb->get_col( $wpdb->prepare(
            "SELECT DISTINCT sku FROM {$ct} WHERE supplier_user_id = %d AND is_active = 1 AND sku != ''",
            $uid
        ) ) ?: [];
        $names = $wpdb->get_col( $wpdb->prepare(
            "SELECT name FROM {$ct} WHERE supplier_user_id = %d AND is_active = 1",
            $uid
        ) ) ?: [];

        $sql  = "SELECT o.*, r.id AS request_id, r.service_type
                 FROM {$ot} o
                 LEFT JOIN {$wpdb->prefix}svc_requests r ON r.id = o.request_id
                 WHERE o.status IN ('supplier_pending','pending')
                   AND (o.supplier_id IS NULL OR o.supplier_id = 0 OR o.supplier_id = %d)";
        $args = [ $uid ];

        $match_clauses = [];
        foreach ( array_filter( array_unique( array_merge( $skus, $names ) ) ) as $term ) {
            $like = '%' . $wpdb->esc_like( $term ) . '%';
            $match_clauses[] = $wpdb->prepare( 'o.part_number LIKE %s', $like );
        }
        if ( $match_clauses ) {
            $sql .= ' AND (' . implode( ' OR ', $match_clauses ) . ')';
        } else {
            $sql .= ' AND 1=0';
        }
        $sql .= ' ORDER BY o.id DESC LIMIT 50';

        $rows = $wpdb->get_results( $wpdb->prepare( $sql, ...$args ), ARRAY_A ) ?: [];

        return new WP_REST_Response( [
            'success' => true,
            'data'    => array_map( [ __CLASS__, '_format_order' ], $rows ),
        ], 200 );
    }

    public static function claim_order( WP_REST_Request $req ): WP_REST_Response {
        $uid = self::uid();
        $id  = (int) $req['id'];
        $body = $req->get_json_params() ?: [];

        global $wpdb;
        $t = $wpdb->prefix . 'svc_parts_orders';
        $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$t} WHERE id = %d", $id ), ARRAY_A );
        if ( ! $row ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'سفارش یافت نشد' ], 404 );
        }
        if ( ! in_array( $row['status'], [ 'supplier_pending', 'pending' ], true ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'این سفارش قابل پذیرش نیست' ], 400 );
        }

        $match = Svc_Supplier::match_catalog( (string) ( $row['part_number'] ?? '' ), (int) ( $row['part_qty'] ?? 1 ) );
        if ( ! $match || (int) $match['supplier_user_id'] !== $uid ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'این قطعه در کاتالوگ شما نیست' ], 403 );
        }

        $price = isset( $body['quote_price'] ) ? (float) $body['quote_price']
            : ( isset( $body['quoted_price'] ) ? (float) $body['quoted_price'] : (float) ( $match['price'] ?? 0 ) );
        $note = sanitize_textarea_field( $body['note'] ?? '' );
        $wpdb->update( $t, [
            'supplier_id' => $uid,
            'status'      => 'quoted',
            'quote_price' => $price,
            'eta_days'    => (int) ( $match['lead_days'] ?? $row['eta_days'] ?? 5 ),
            'notes'       => $note ? '[تأمین‌کننده] ' . $note : ( $row['notes'] ?? '' ),
        ], [ 'id' => $id ] );

        $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$t} WHERE id = %d", $id ), ARRAY_A );

        return new WP_REST_Response( [
            'success' => true,
            'data'    => self::_format_order( $row ),
        ], 200 );
    }

    public static function update_order( WP_REST_Request $req ): WP_REST_Response {
        $uid = self::uid();
        $id  = (int) $req['id'];
        $body = $req->get_json_params() ?: [];

        global $wpdb;
        $t = $wpdb->prefix . 'svc_parts_orders';
        $row = $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM {$t} WHERE id = %d AND supplier_id = %d", $id, $uid
        ), ARRAY_A );
        if ( ! $row ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'سفارش یافت نشد' ], 404 );
        }

        $update = [];
        if ( isset( $body['quote_price'] ) ) {
            $update['quote_price'] = (float) $body['quote_price'];
        } elseif ( isset( $body['quoted_price'] ) ) {
            $update['quote_price'] = (float) $body['quoted_price'];
        }
        if ( isset( $body['status'] ) ) {
            $st = sanitize_text_field( $body['status'] );
            if ( in_array( $st, [ 'quoted', 'shipped', 'delivered', 'cancelled', 'ready' ], true ) ) {
                $update['status'] = $st;
            }
        }
        if ( isset( $body['note'] ) ) {
            $update['notes'] = trim( ( $row['notes'] ?? '' ) . "\n[تأمین‌کننده] " . sanitize_textarea_field( $body['note'] ) );
        }

        if ( empty( $update ) ) {
            return new WP_REST_Response( [ 'success' => false, 'message' => 'داده‌ای ارسال نشد' ], 400 );
        }
        $wpdb->update( $t, $update, [ 'id' => $id ] );
        $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$t} WHERE id = %d", $id ), ARRAY_A );

        return new WP_REST_Response( [
            'success' => true,
            'data'    => self::_format_order( $row ),
        ], 200 );
    }

    public static function admin_list_all_catalog( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $t = Svc_Supplier::catalog_table();
        $pt = Svc_Supplier::profile_table();
        $rows = $wpdb->get_results(
            "SELECT c.*, p.company_name
             FROM {$t} c
             LEFT JOIN {$pt} p ON p.user_id = c.supplier_user_id
             ORDER BY c.id DESC LIMIT 200",
            ARRAY_A
        ) ?: [];

        $out = [];
        foreach ( $rows as $r ) {
            $f = self::_format_catalog( $r );
            $f['company_name'] = $r['company_name'] ?? '';
            $out[] = $f;
        }

        return new WP_REST_Response( [ 'success' => true, 'data' => $out ], 200 );
    }

    private static function _get_own_catalog( int $id, int $uid ): ?array {
        global $wpdb;
        return $wpdb->get_row( $wpdb->prepare(
            "SELECT * FROM " . Svc_Supplier::catalog_table() . " WHERE id = %d AND supplier_user_id = %d",
            $id, $uid
        ), ARRAY_A ) ?: null;
    }

    private static function _validate_catalog_payload( array $body, bool $partial = false ) {
        $fields = [];
        $map = [
            'item_type'   => 'sanitize_text_field',
            'name'        => 'sanitize_text_field',
            'sku'         => 'sanitize_text_field',
            'description' => 'sanitize_textarea_field',
            'unit'        => 'sanitize_text_field',
            'brand'       => 'sanitize_text_field',
            'model'       => 'sanitize_text_field',
        ];
        foreach ( $map as $k => $fn ) {
            if ( array_key_exists( $k, $body ) ) {
                $fields[ $k ] = $fn( (string) $body[ $k ] );
            }
        }
        if ( array_key_exists( 'price', $body ) ) $fields['price'] = max( 0, (float) $body['price'] );
        if ( array_key_exists( 'stock_qty', $body ) ) $fields['stock_qty'] = max( 0, (int) $body['stock_qty'] );
        if ( array_key_exists( 'in_stock', $body ) ) $fields['in_stock'] = (int) (bool) $body['in_stock'];
        if ( array_key_exists( 'is_active', $body ) ) $fields['is_active'] = (int) (bool) $body['is_active'];
        if ( array_key_exists( 'lead_days', $body ) ) $fields['lead_days'] = max( 0, (int) $body['lead_days'] );

        if ( ! $partial ) {
            if ( empty( $fields['name'] ) ) {
                return new WP_Error( 'invalid', 'نام کالا/خدمت الزامی است' );
            }
            $type = $fields['item_type'] ?? 'part';
            if ( ! isset( Svc_Supplier::item_types()[ $type ] ) ) {
                $fields['item_type'] = 'part';
            }
        } elseif ( isset( $fields['item_type'] ) && ! isset( Svc_Supplier::item_types()[ $fields['item_type'] ] ) ) {
            return new WP_Error( 'invalid', 'نوع آیتم نامعتبر است' );
        }

        return $fields;
    }

    private static function _format_profile( ?array $row ): array {
        if ( ! $row ) return [];
        return [
            'user_id'       => (int) $row['user_id'],
            'company_name'  => $row['company_name'] ?? '',
            'contact_name'  => $row['contact_name'] ?? '',
            'phone'         => $row['phone'] ?? '',
            'email'         => $row['email'] ?? '',
            'address'       => $row['address'] ?? '',
            'city'          => $row['city'] ?? '',
            'description'   => $row['description'] ?? '',
            'is_active'     => (bool) ( $row['is_active'] ?? 1 ),
        ];
    }

    private static function _format_catalog( ?array $row ): array {
        if ( ! $row ) return [];
        $types = Svc_Supplier::item_types();
        $type  = $row['item_type'] ?? 'part';
        return [
            'id'          => (int) $row['id'],
            'item_type'   => $type,
            'item_type_label' => $types[ $type ] ?? $type,
            'name'        => $row['name'] ?? '',
            'sku'         => $row['sku'] ?? '',
            'description' => $row['description'] ?? '',
            'unit'        => $row['unit'] ?? 'عدد',
            'brand'       => $row['brand'] ?? '',
            'model'       => $row['model'] ?? '',
            'price'       => (float) ( $row['price'] ?? 0 ),
            'stock_qty'   => (int) ( $row['stock_qty'] ?? 0 ),
            'in_stock'    => (bool) ( $row['in_stock'] ?? 0 ),
            'lead_days'   => (int) ( $row['lead_days'] ?? 0 ),
            'is_active'   => (bool) ( $row['is_active'] ?? 1 ),
            'updated_at'  => $row['updated_at'] ?? '',
        ];
    }

    private static function _format_order( ?array $row ): array {
        if ( ! $row ) return [];
        return [
            'id'             => (int) $row['id'],
            'request_id'     => (int) ( $row['request_id'] ?? 0 ),
            'service_type'   => $row['service_type'] ?? '',
            'customer_name'  => $row['customer_name'] ?? '',
            'part_number'    => $row['part_number'] ?? '',
            'part_qty'       => (int) ( $row['part_qty'] ?? 1 ),
            'status'         => $row['status'] ?? '',
            'quote_price'    => (float) ( $row['quote_price'] ?? 0 ),
            'eta_days'       => (int) ( $row['eta_days'] ?? 0 ),
            'notes'          => $row['notes'] ?? '',
            'created_at'     => $row['created_at'] ?? '',
        ];
    }

    private static function _order_counts( int $uid ): array {
        global $wpdb;
        $t = $wpdb->prefix . 'svc_parts_orders';
        if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $t ) ) !== $t ) {
            return [ 'total' => 0, 'open' => 0, 'quoted' => 0, 'delivered' => 0 ];
        }
        $rows = $wpdb->get_results( $wpdb->prepare(
            "SELECT status, COUNT(*) AS cnt FROM {$t} WHERE supplier_id = %d GROUP BY status",
            $uid
        ), ARRAY_A ) ?: [];
        $out = [ 'total' => 0, 'open' => 0, 'quoted' => 0, 'delivered' => 0 ];
        foreach ( $rows as $r ) {
            $out['total'] += (int) $r['cnt'];
            $st = $r['status'];
            if ( in_array( $st, [ 'supplier_pending', 'pending' ], true ) ) $out['open'] += (int) $r['cnt'];
            if ( $st === 'quoted' ) $out['quoted'] += (int) $r['cnt'];
            if ( $st === 'delivered' ) $out['delivered'] += (int) $r['cnt'];
        }
        return $out;
    }
}
