<?php
/**
 * UnitSales_Controller.php — فروش واحدهای ساختمانی
 * واحدها | مشتریان | فروش
 */

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

class UnitSales_Controller {

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

        // ── واحدها ──────────────────────────────────────────────
        register_rest_route($ns, '/units', [
            ['methods'=>'GET',  'callback'=>[self::class,'get_units'],   'permission_callback'=>$p],
            ['methods'=>'POST', 'callback'=>[self::class,'create_unit'], 'permission_callback'=>$p],
        ]);
        register_rest_route($ns, '/units/(?P<id>\d+)', [
            ['methods'=>'GET',    'callback'=>[self::class,'get_unit'],    'permission_callback'=>$p],
            ['methods'=>'PUT',    'callback'=>[self::class,'update_unit'], 'permission_callback'=>$p],
            ['methods'=>'DELETE', 'callback'=>[self::class,'delete_unit'], 'permission_callback'=>$p],
        ]);
        register_rest_route($ns, '/units/project/(?P<project_id>\d+)', [
            'methods'=>'GET', 'callback'=>[self::class,'get_units_by_project'], 'permission_callback'=>$p,
        ]);

        // ── مشتریان ─────────────────────────────────────────────
        register_rest_route($ns, '/sale-customers', [
            ['methods'=>'GET',  'callback'=>[self::class,'get_customers'],   'permission_callback'=>$p],
            ['methods'=>'POST', 'callback'=>[self::class,'create_customer'], 'permission_callback'=>$p],
        ]);
        register_rest_route($ns, '/sale-customers/(?P<id>\d+)', [
            ['methods'=>'GET',    'callback'=>[self::class,'get_customer'],    'permission_callback'=>$p],
            ['methods'=>'PUT',    'callback'=>[self::class,'update_customer'], 'permission_callback'=>$p],
            ['methods'=>'DELETE', 'callback'=>[self::class,'delete_customer'], 'permission_callback'=>$p],
        ]);

        // ── فروش ────────────────────────────────────────────────
        register_rest_route($ns, '/sales', [
            ['methods'=>'GET',  'callback'=>[self::class,'get_sales'],   'permission_callback'=>$p],
            ['methods'=>'POST', 'callback'=>[self::class,'create_sale'], 'permission_callback'=>$p],
        ]);
        register_rest_route($ns, '/sales/(?P<id>\d+)', [
            ['methods'=>'GET',    'callback'=>[self::class,'get_sale'],    'permission_callback'=>$p],
            ['methods'=>'PUT',    'callback'=>[self::class,'update_sale'], 'permission_callback'=>$p],
            ['methods'=>'DELETE', 'callback'=>[self::class,'cancel_sale'], 'permission_callback'=>$p],
        ]);
        register_rest_route($ns, '/sales/(?P<id>\d+)/transfer', [
            'methods'=>'POST', 'callback'=>[self::class,'transfer_unit'], 'permission_callback'=>$p,
        ]);

        // ── داشبورد فروش ────────────────────────────────────────
        register_rest_route($ns, '/sales/dashboard', [
            'methods'=>'GET', 'callback'=>[self::class,'get_dashboard'], 'permission_callback'=>$p,
        ]);
    }

    /* ══════════════════════════════════════════════════════════
       واحدها
    ══════════════════════════════════════════════════════════ */
    public static function get_units( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $pre    = $wpdb->prefix;
        $wheres = ['1=1'];
        $args   = [];

        if ($v = $req->get_param('project_id')) { $wheres[]='u.project_id=%d'; $args[]=(int)$v; }
        $uid = acl_current_user_id();
        if ( ! acl_append_scope_where( $uid, 'project', 'u.project_id', $wheres, $args ) ) {
            return new WP_REST_Response( [ 'data' => [], 'total' => 0 ] );
        }
        if ($v = $req->get_param('parcel_id'))  { $wheres[]='u.parcel_id=%d';  $args[]=(int)$v; }
        if ($v = $req->get_param('status'))     { $wheres[]='u.status=%s';     $args[]=sanitize_text_field($v); }
        if ($v = $req->get_param('type'))       { $wheres[]='u.type=%s';       $args[]=sanitize_text_field($v); }

        $where = 'WHERE '.implode(' AND ',$wheres);
        $sql   = "SELECT u.*,
                    p.name AS project_name,
                    s.id AS sale_id, s.customer_id, s.sale_price AS sold_price,
                    s.status AS sale_status, s.reservation_date,
                    c.name AS customer_name, c.phone AS customer_phone
                  FROM {$pre}sale_units u
                  LEFT JOIN {$pre}pc_projects p ON p.id = u.project_id
                  LEFT JOIN {$pre}sales s ON s.unit_id = u.id AND s.status != 'cancelled'
                  LEFT JOIN {$pre}sale_customers c ON c.id = s.customer_id
                  {$where}
                  ORDER BY u.floor DESC, u.unit_number";

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

        return new WP_REST_Response(['data'=>$rows??[], 'total'=>count($rows??[])]);
    }

    public static function get_units_by_project( WP_REST_Request $req ): WP_REST_Response {
        $req->set_param('project_id', $req->get_param('project_id'));
        return self::get_units($req);
    }

    public static function get_unit( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $pre = $wpdb->prefix;
        $id  = (int)$req->get_param('id');

        $unit = $wpdb->get_row($wpdb->prepare(
            "SELECT u.*, p.name AS project_name
             FROM {$pre}sale_units u
             LEFT JOIN {$pre}pc_projects p ON p.id = u.project_id
             WHERE u.id=%d", $id
        ), ARRAY_A);

        if (!$unit) return new WP_REST_Response(['message'=>'واحد یافت نشد'], 404);

        $deny = acl_deny_scope( acl_current_user_id(), 'project', $unit['project_id'] ? (int) $unit['project_id'] : null );
        if ( $deny ) return $deny;

        $unit['sale'] = $wpdb->get_row($wpdb->prepare(
            "SELECT s.*, c.name AS customer_name, c.phone AS customer_phone,
                    c.national_id AS customer_national_id, c.email AS customer_email
             FROM {$pre}sales s
             LEFT JOIN {$pre}sale_customers c ON c.id = s.customer_id
             WHERE s.unit_id=%d AND s.status != 'cancelled'
             ORDER BY s.id DESC LIMIT 1", $id
        ), ARRAY_A);

        return new WP_REST_Response(['data'=>$unit]);
    }

    public static function create_unit( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $pid  = $req->get_param('project_id') ? (int) $req->get_param('project_id') : null;
        $deny = acl_deny_scope( acl_current_user_id(), 'project', $pid );
        if ( $deny ) return $deny;
        $base  = (float)($req->get_param('base_price') ?: 0);
        $area  = (float)($req->get_param('area_sqm') ?: 0);
        $psqm  = (float)($req->get_param('price_per_sqm') ?: 0);
        // محاسبه خودکار
        if ($base == 0 && $area > 0 && $psqm > 0) $base = $area * $psqm;
        if ($psqm == 0 && $area > 0 && $base > 0) $psqm = $base / $area;

        $data = [
            'project_id'       => $req->get_param('project_id') ? (int)$req->get_param('project_id') : null,
            'parcel_id'        => $req->get_param('parcel_id')  ? (int)$req->get_param('parcel_id')  : null,
            'block'            => sanitize_text_field($req->get_param('block')       ?: ''),
            'floor'            => (int)($req->get_param('floor') ?: 0),
            'unit_number'      => sanitize_text_field($req->get_param('unit_number') ?: ''),
            'type'             => sanitize_text_field($req->get_param('type')        ?: 'residential'),
            'area_sqm'         => $area ?: null,
            'area_useful_sqm'  => $req->get_param('area_useful_sqm') ? (float)$req->get_param('area_useful_sqm') : null,
            'base_price'       => $base ?: null,
            'price_per_sqm'    => $psqm ?: null,
            'status'           => 'available',
            'view_direction'   => $req->get_param('view_direction') ?: null,
            'has_parking'      => $req->get_param('has_parking')  ? 1 : 0,
            'has_storage'      => $req->get_param('has_storage')  ? 1 : 0,
            'has_balcony'      => $req->get_param('has_balcony')  ? 1 : 0,
            'notes'            => sanitize_textarea_field($req->get_param('notes') ?: ''),
        ];
        if (!$data['unit_number']) return new WP_REST_Response(['message'=>'شماره واحد الزامی است'], 400);
        foreach (['block','view_direction','notes'] as $k) { if (!$data[$k]) unset($data[$k]); }

        $wpdb->insert($wpdb->prefix.'sale_units', $data);
        return new WP_REST_Response(['id'=>$wpdb->insert_id,'success'=>true], 201);
    }

    public static function update_unit( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $id   = (int)$req->get_param('id');
        $deny = acl_deny_entity_project( acl_current_user_id(), 'sale_units', $id );
        if ( $deny ) return $deny;
        $keys = ['project_id','parcel_id','block','floor','unit_number','type',
                 'area_sqm','area_useful_sqm','base_price','price_per_sqm',
                 'status','view_direction','has_parking','has_storage','has_balcony','notes'];
        $data = [];
        foreach ($keys as $k) {
            $v = $req->get_param($k);
            if ($v === null) continue;
            $ints    = ['project_id','parcel_id','floor','has_parking','has_storage','has_balcony'];
            $floats  = ['area_sqm','area_useful_sqm','base_price','price_per_sqm'];
            $data[$k] = in_array($k,$ints) ? (int)$v : (in_array($k,$floats) ? (float)$v : sanitize_textarea_field((string)$v));
        }
        if ( isset( $data['project_id'] ) ) {
            $deny = acl_deny_scope( acl_current_user_id(), 'project', $data['project_id'] ?: null );
            if ( $deny ) return $deny;
        }
        $wpdb->update($wpdb->prefix.'sale_units', $data, ['id'=>$id]);
        return new WP_REST_Response(['success'=>true]);
    }

    public static function delete_unit( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $id = (int)$req->get_param('id');
        $deny = acl_deny_entity_project( acl_current_user_id(), 'sale_units', $id );
        if ( $deny ) return $deny;
        // حذف فقط اگر فروخته نشده
        $status = $wpdb->get_var($wpdb->prepare(
            "SELECT status FROM {$wpdb->prefix}sale_units WHERE id=%d", $id
        ));
        if (in_array($status, ['sold','transferred'])) {
            return new WP_REST_Response(['message'=>'واحد فروخته‌شده قابل حذف نیست'], 409);
        }
        $wpdb->delete($wpdb->prefix.'sale_units', ['id'=>$id]);
        return new WP_REST_Response(['success'=>true]);
    }

    /* ══════════════════════════════════════════════════════════
       مشتریان
    ══════════════════════════════════════════════════════════ */
    public static function get_customers( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $pre    = $wpdb->prefix;
        $search = sanitize_text_field($req->get_param('search') ?: '');
        $where  = $search ? $wpdb->prepare(
            'WHERE c.name LIKE %s OR c.national_id LIKE %s OR c.phone LIKE %s',
            "%$search%", "%$search%", "%$search%"
        ) : '';

        $rows = $wpdb->get_results(
            "SELECT c.*,
                    COUNT(s.id) AS sale_count,
                    COALESCE(SUM(s.sale_price),0) AS total_purchased
             FROM {$pre}sale_customers c
             LEFT JOIN {$pre}sales s ON s.customer_id=c.id AND s.status != 'cancelled'
             {$where}
             GROUP BY c.id
             ORDER BY c.created_at DESC",
            ARRAY_A
        );
        return new WP_REST_Response(['data'=>$rows??[]]);
    }

    public static function get_customer( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $pre = $wpdb->prefix;
        $id  = (int)$req->get_param('id');
        $c   = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$pre}sale_customers WHERE id=%d",$id), ARRAY_A);
        if (!$c) return new WP_REST_Response(['message'=>'مشتری یافت نشد'], 404);
        $c['sales'] = $wpdb->get_results($wpdb->prepare(
            "SELECT s.*, u.unit_number, u.floor, u.type, p.name AS project_name
             FROM {$pre}sales s
             JOIN {$pre}sale_units u ON u.id=s.unit_id
             LEFT JOIN {$pre}pc_projects p ON p.id=u.project_id
             WHERE s.customer_id=%d ORDER BY s.created_at DESC", $id
        ), ARRAY_A);
        return new WP_REST_Response(['data'=>$c]);
    }

    public static function create_customer( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $data = [
            'name'        => sanitize_text_field($req->get_param('name') ?: ''),
            'national_id' => sanitize_text_field($req->get_param('national_id') ?: ''),
            'phone'       => sanitize_text_field($req->get_param('phone')  ?: ''),
            'phone2'      => sanitize_text_field($req->get_param('phone2') ?: ''),
            'email'       => sanitize_email($req->get_param('email') ?: ''),
            'address'     => sanitize_textarea_field($req->get_param('address') ?: ''),
            'city'        => sanitize_text_field($req->get_param('city') ?: ''),
            'type'        => sanitize_text_field($req->get_param('type') ?: 'individual'),
            'company_name'=> sanitize_text_field($req->get_param('company_name') ?: ''),
            'company_reg' => sanitize_text_field($req->get_param('company_reg')  ?: ''),
            'notes'       => sanitize_textarea_field($req->get_param('notes') ?: ''),
        ];
        if (!$data['name']) return new WP_REST_Response(['message'=>'نام الزامی است'], 400);
        foreach ($data as $k=>$v) { if ($v==='') unset($data[$k]); }
        $data['name'] = $req->get_param('name'); // keep name even if empty
        $wpdb->insert($wpdb->prefix.'sale_customers', $data);
        return new WP_REST_Response(['id'=>$wpdb->insert_id,'success'=>true], 201);
    }

    public static function update_customer( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $id   = (int)$req->get_param('id');
        $keys = ['name','national_id','phone','phone2','email','address','city',
                 'type','company_name','company_reg','notes'];
        $data = [];
        foreach ($keys as $k) {
            $v = $req->get_param($k);
            if ($v !== null) $data[$k] = sanitize_textarea_field((string)$v);
        }
        $wpdb->update($wpdb->prefix.'sale_customers', $data, ['id'=>$id]);
        return new WP_REST_Response(['success'=>true]);
    }

    public static function delete_customer( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $id    = (int)$req->get_param('id');
        $count = (int)$wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM {$wpdb->prefix}sales WHERE customer_id=%d AND status!='cancelled'", $id
        ));
        if ($count > 0) return new WP_REST_Response(['message'=>'این مشتری دارای فروش فعال است'], 409);
        $wpdb->delete($wpdb->prefix.'sale_customers', ['id'=>$id]);
        return new WP_REST_Response(['success'=>true]);
    }

    /* ══════════════════════════════════════════════════════════
       فروش
    ══════════════════════════════════════════════════════════ */
    public static function get_sales( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $pre    = $wpdb->prefix;
        $wheres = ["s.status != 'cancelled'"];
        $args   = [];

        if ($v = $req->get_param('status'))      { $wheres[]='s.status=%s';       $args[]=sanitize_text_field($v); }
        if ($v = $req->get_param('project_id'))  { $wheres[]='u.project_id=%d';   $args[]=(int)$v; }
        $uid = acl_current_user_id();
        if ( ! acl_append_scope_where( $uid, 'project', 'u.project_id', $wheres, $args ) ) {
            return new WP_REST_Response( [ 'data' => [] ] );
        }
        if ($v = $req->get_param('customer_id')) { $wheres[]='s.customer_id=%d';  $args[]=(int)$v; }

        $where = 'WHERE '.implode(' AND ',$wheres);
        $sql   = "SELECT s.*, c.name AS customer_name, c.phone AS customer_phone,
                         u.unit_number, u.floor, u.type AS unit_type,
                         u.area_sqm, p.name AS project_name
                  FROM {$pre}sales s
                  JOIN {$pre}sale_units u ON u.id=s.unit_id
                  LEFT JOIN {$pre}sale_customers c ON c.id=s.customer_id
                  LEFT JOIN {$pre}pc_projects p ON p.id=u.project_id
                  {$where}
                  ORDER BY s.updated_at DESC";

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

        return new WP_REST_Response(['data'=>$rows??[]]);
    }

    public static function get_sale( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $pre  = $wpdb->prefix;
        $id   = (int)$req->get_param('id');
        $sale = $wpdb->get_row($wpdb->prepare(
            "SELECT s.*, c.name AS customer_name, c.phone AS customer_phone,
                    c.national_id AS customer_national_id,
                    u.unit_number, u.floor, u.type AS unit_type,
                    u.area_sqm, u.area_useful_sqm,
                    p.name AS project_name
             FROM {$pre}sales s
             JOIN {$pre}sale_units u ON u.id=s.unit_id
             LEFT JOIN {$pre}sale_customers c ON c.id=s.customer_id
             LEFT JOIN {$pre}pc_projects p ON p.id=u.project_id
             WHERE s.id=%d", $id
        ), ARRAY_A);
        if (!$sale) return new WP_REST_Response(['message'=>'فروش یافت نشد'], 404);
        $deny = acl_deny_entity_project( acl_current_user_id(), 'sale_units', (int) $sale['unit_id'] );
        if ( $deny ) return $deny;
        return new WP_REST_Response(['data'=>$sale]);
    }

    public static function create_sale( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $pre     = $wpdb->prefix;
        $unit_id = (int)$req->get_param('unit_id');
        $cust_id = (int)$req->get_param('customer_id');

        // بررسی واحد
        $unit = $wpdb->get_row($wpdb->prepare(
            "SELECT id, status FROM {$pre}sale_units WHERE id=%d", $unit_id
        ), ARRAY_A);
        if (!$unit) return new WP_REST_Response(['message'=>'واحد یافت نشد'], 404);
        if (!in_array($unit['status'],['available'])) {
            return new WP_REST_Response(['message'=>'این واحد در دسترس نیست'], 409);
        }

        $data = [
            'unit_id'            => $unit_id,
            'customer_id'        => $cust_id,
            'contract_id'        => $req->get_param('contract_id') ? (int)$req->get_param('contract_id') : null,
            'sale_price'         => (float)($req->get_param('sale_price') ?: 0),
            'payment_type'       => sanitize_text_field($req->get_param('payment_type') ?: 'installment'),
            'reservation_date'   => sanitize_text_field($req->get_param('reservation_date')   ?: date('Y-m-d')),
            'sale_contract_date' => sanitize_text_field($req->get_param('sale_contract_date') ?: ''),
            'status'             => 'reserved',
            'notes'              => sanitize_textarea_field($req->get_param('notes') ?: ''),
        ];
        if (empty($data['sale_contract_date'])) unset($data['sale_contract_date']);

        $wpdb->insert("{$pre}sales", $data);
        $sale_id = $wpdb->insert_id;

        // به‌روزرسانی وضعیت واحد
        $wpdb->update("{$pre}sale_units", ['status'=>'reserved'], ['id'=>$unit_id]);

        return new WP_REST_Response(['id'=>$sale_id,'success'=>true], 201);
    }

    public static function update_sale( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $id   = (int)$req->get_param('id');
        $pre  = $wpdb->prefix;
        $keys = ['contract_id','sale_price','payment_type','paid_amount',
                 'reservation_date','sale_contract_date','transfer_date','transfer_deed_date','status','notes'];
        $data = [];
        foreach ($keys as $k) {
            $v = $req->get_param($k);
            if ($v === null) continue;
            $floats = ['sale_price','paid_amount'];
            $ints   = ['contract_id'];
            $data[$k] = in_array($k,$floats) ? (float)$v : (in_array($k,$ints) ? (int)$v : sanitize_textarea_field((string)$v));
        }
        $wpdb->update("{$pre}sales", $data, ['id'=>$id]);

        // همگام‌سازی وضعیت واحد
        if (!empty($data['status'])) {
            $unit_id = (int)$wpdb->get_var($wpdb->prepare("SELECT unit_id FROM {$pre}sales WHERE id=%d",$id));
            $unit_status = match($data['status']) {
                'active'    => 'sold',
                'completed' => 'transferred',
                'cancelled' => 'available',
                default     => 'reserved',
            };
            $wpdb->update("{$pre}sale_units", ['status'=>$unit_status], ['id'=>$unit_id]);
        }

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

    public static function cancel_sale( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $pre  = $wpdb->prefix;
        $id   = (int)$req->get_param('id');
        $sale = $wpdb->get_row($wpdb->prepare("SELECT unit_id,status FROM {$pre}sales WHERE id=%d",$id), ARRAY_A);
        if (!$sale) return new WP_REST_Response(['message'=>'یافت نشد'],404);
        if ($sale['status'] === 'completed') return new WP_REST_Response(['message'=>'فروش تکمیل‌شده قابل لغو نیست'],409);
        $wpdb->update("{$pre}sales",      ['status'=>'cancelled'],  ['id'=>$id]);
        $wpdb->update("{$pre}sale_units", ['status'=>'available'],  ['id'=>$sale['unit_id']]);
        return new WP_REST_Response(['success'=>true]);
    }

    public static function transfer_unit( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $pre  = $wpdb->prefix;
        $id   = (int)$req->get_param('id');
        $data = [
            'status'             => 'completed',
            'transfer_date'      => sanitize_text_field($req->get_param('transfer_date')      ?: date('Y-m-d')),
            'transfer_deed_date' => sanitize_text_field($req->get_param('transfer_deed_date') ?: ''),
        ];
        if (empty($data['transfer_deed_date'])) unset($data['transfer_deed_date']);
        $wpdb->update("{$pre}sales", $data, ['id'=>$id]);
        $unit_id = (int)$wpdb->get_var($wpdb->prepare("SELECT unit_id FROM {$pre}sales WHERE id=%d",$id));
        $wpdb->update("{$pre}sale_units", ['status'=>'transferred'], ['id'=>$unit_id]);
        return new WP_REST_Response(['success'=>true]);
    }

    /* ══════════════════════════════════════════════════════════
       داشبورد
    ══════════════════════════════════════════════════════════ */
    public static function get_dashboard( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $pre = $wpdb->prefix;

        $units   = $wpdb->get_results("SELECT status, COUNT(*) AS cnt, COALESCE(SUM(base_price),0) AS total FROM {$pre}sale_units GROUP BY status", ARRAY_A);
        $sales   = $wpdb->get_results("SELECT status, COUNT(*) AS cnt, COALESCE(SUM(sale_price),0) AS total, COALESCE(SUM(paid_amount),0) AS paid FROM {$pre}sales GROUP BY status", ARRAY_A);
        $recent  = $wpdb->get_results("SELECT s.*, c.name AS customer_name, u.unit_number, u.floor FROM {$pre}sales s JOIN {$pre}sale_units u ON u.id=s.unit_id LEFT JOIN {$pre}sale_customers c ON c.id=s.customer_id WHERE s.status!='cancelled' ORDER BY s.created_at DESC LIMIT 5", ARRAY_A);

        return new WP_REST_Response([
            'unit_stats'  => $units,
            'sale_stats'  => $sales,
            'recent_sales'=> $recent,
        ]);
    }
}
