<?php
/**
 * CRM_Controller.php — مدیریت ارتباط با مشتری
 * لیدها | فعالیت‌ها | یادآورها
 */

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

class CRM_Controller {

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

        // ── لیدها ────────────────────────────────────────────
        register_rest_route($ns, '/crm/leads', [
            ['methods'=>'GET',  'callback'=>[self::class,'get_leads'],   'permission_callback'=>$p],
            ['methods'=>'POST', 'callback'=>[self::class,'create_lead'], 'permission_callback'=>$p],
        ]);
        register_rest_route($ns, '/crm/leads/(?P<id>\d+)', [
            ['methods'=>'GET',    'callback'=>[self::class,'get_lead'],    'permission_callback'=>$p],
            ['methods'=>'PUT',    'callback'=>[self::class,'update_lead'], 'permission_callback'=>$p],
            ['methods'=>'DELETE', 'callback'=>[self::class,'delete_lead'], 'permission_callback'=>$p],
        ]);
        register_rest_route($ns, '/crm/leads/(?P<id>\d+)/move', [
            'methods'=>'POST', 'callback'=>[self::class,'move_stage'], 'permission_callback'=>$p,
        ]);
        register_rest_route($ns, '/crm/leads/(?P<id>\d+)/convert', [
            'methods'=>'POST', 'callback'=>[self::class,'convert_lead'], 'permission_callback'=>$p,
        ]);
        register_rest_route($ns, '/crm/leads/(?P<id>\d+)/units', [
            'methods'=>'GET', 'callback'=>[self::class,'matching_units'], 'permission_callback'=>$p,
        ]);

        // ── فعالیت‌ها ─────────────────────────────────────────
        register_rest_route($ns, '/crm/leads/(?P<id>\d+)/activities', [
            ['methods'=>'GET',  'callback'=>[self::class,'get_activities'],   'permission_callback'=>$p],
            ['methods'=>'POST', 'callback'=>[self::class,'create_activity'],  'permission_callback'=>$p],
        ]);
        register_rest_route($ns, '/crm/activities/(?P<act_id>\d+)', [
            ['methods'=>'DELETE', 'callback'=>[self::class,'delete_activity'], 'permission_callback'=>$p],
        ]);

        // ── یادآورها ─────────────────────────────────────────
        register_rest_route($ns, '/crm/leads/(?P<id>\d+)/reminders', [
            ['methods'=>'GET',  'callback'=>[self::class,'get_reminders'],   'permission_callback'=>$p],
            ['methods'=>'POST', 'callback'=>[self::class,'create_reminder'], 'permission_callback'=>$p],
        ]);
        register_rest_route($ns, '/crm/reminders/(?P<rem_id>\d+)', [
            ['methods'=>'PUT',    'callback'=>[self::class,'update_reminder'], 'permission_callback'=>$p],
            ['methods'=>'DELETE', 'callback'=>[self::class,'delete_reminder'], 'permission_callback'=>$p],
        ]);

        // ── داشبورد و یادآورهای امروز ──────────────────────
        register_rest_route($ns, '/crm/dashboard', [
            'methods'=>'GET', 'callback'=>[self::class,'get_dashboard'], 'permission_callback'=>$p,
        ]);
        register_rest_route($ns, '/crm/reminders/today', [
            'methods'=>'GET', 'callback'=>[self::class,'get_today_reminders'], 'permission_callback'=>$p,
        ]);
    }

    /* ══════════════════════════════════════════════════════════
       لیدها
    ══════════════════════════════════════════════════════════ */
    public static function get_leads( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $pre    = $wpdb->prefix;
        $wheres = ["l.status != 'converted' AND l.status != 'lost'"];
        $args   = [];

        if ($req->get_param('include_all')) $wheres = ['1=1'];
        if ($v=$req->get_param('status'))     { $wheres[]='l.status=%s'; $args[]=sanitize_text_field($v); }
        if ($v=$req->get_param('source'))     { $wheres[]='l.source=%s'; $args[]=sanitize_text_field($v); }
        if ($v=$req->get_param('lead_channel')) { $wheres[]='l.lead_channel=%s'; $args[]=sanitize_text_field($v); }
        if ($v=$req->get_param('arag_order_id')) { $wheres[]='l.arag_order_id=%d'; $args[]=(int)$v; }
        if ($v=$req->get_param('project_id')) { $wheres[]='l.project_id=%d'; $args[]=(int)$v; }
        $uid = acl_current_user_id();
        if ( ! acl_append_scope_where( $uid, 'project', 'l.project_id', $wheres, $args ) ) {
            return new WP_REST_Response( [ 'data' => [], 'total' => 0 ] );
        }
        if ($v=$req->get_param('assigned'))   { $wheres[]='l.assigned_user_id=%d'; $args[]=(int)$v; }
        if ($v=$req->get_param('search'))     {
            $wheres[]='(l.name LIKE %s OR l.phone LIKE %s OR l.email LIKE %s)';
            $s="%$v%"; $args[]=$s; $args[]=$s; $args[]=$s;
        }

        $where = 'WHERE '.implode(' AND ',$wheres);
        $sql   = "SELECT l.*,
                    p.name AS project_name,
                    DATEDIFF(CURDATE(), l.last_contact_date) AS days_since_contact,
                    (SELECT COUNT(*) FROM {$pre}crm_activities a WHERE a.lead_id=l.id) AS activity_count,
                    (SELECT COUNT(*) FROM {$pre}crm_reminders r WHERE r.lead_id=l.id AND r.status='pending') AS pending_reminders
                  FROM {$pre}crm_leads l
                  LEFT JOIN {$pre}pc_projects p ON p.id=l.project_id
                  {$where}
                  ORDER BY l.score DESC, l.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??[],'total'=>count($rows??[])]);
    }

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

        $lead = $wpdb->get_row($wpdb->prepare(
            "SELECT l.*, p.name AS project_name
             FROM {$pre}crm_leads l
             LEFT JOIN {$pre}pc_projects p ON p.id=l.project_id
             WHERE l.id=%d", $id
        ),ARRAY_A);
        if (!$lead) return new WP_REST_Response(['message'=>'لید یافت نشد'],404);

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

        $lead['activities'] = $wpdb->get_results($wpdb->prepare(
            "SELECT * FROM {$pre}crm_activities WHERE lead_id=%d ORDER BY activity_date DESC",
            $id
        ),ARRAY_A);

        $lead['reminders'] = $wpdb->get_results($wpdb->prepare(
            "SELECT * FROM {$pre}crm_reminders WHERE lead_id=%d ORDER BY due_date ASC",
            $id
        ),ARRAY_A);

        $lead['days_since_contact'] = $lead['last_contact_date']
            ? (int)round((time()-strtotime($lead['last_contact_date']))/86400) : null;

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

    public static function create_lead( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $data = self::_lead_data($req);
        if (empty($data['name'])) return new WP_REST_Response(['message'=>'نام الزامی است'],400);
        $deny = acl_deny_scope( acl_current_user_id(), 'project', ! empty( $data['project_id'] ) ? (int) $data['project_id'] : null, 'crm.view' );
        if ( $deny ) return $deny;
        $wpdb->insert($wpdb->prefix.'crm_leads', $data);
        return new WP_REST_Response(['id'=>$wpdb->insert_id,'success'=>true],201);
    }

    public static function update_lead( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $id   = (int)$req->get_param('id');
        $deny = acl_deny_entity_project( acl_current_user_id(), 'crm_leads', $id, 'crm.view' );
        if ( $deny ) return $deny;
        $data = self::_lead_data($req, false);
        if ( isset( $data['project_id'] ) ) {
            $deny = acl_deny_scope( acl_current_user_id(), 'project', $data['project_id'] ? (int) $data['project_id'] : null, 'crm.view' );
            if ( $deny ) return $deny;
        }
        if ($data) $wpdb->update($wpdb->prefix.'crm_leads',$data,['id'=>$id]);
        return new WP_REST_Response(['success'=>true]);
    }

    public static function delete_lead( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $id = (int)$req->get_param('id');
        $deny = acl_deny_entity_project( acl_current_user_id(), 'crm_leads', $id, 'crm.view' );
        if ( $deny ) return $deny;
        $wpdb->delete($wpdb->prefix.'crm_activities', ['lead_id'=>$id]);
        $wpdb->delete($wpdb->prefix.'crm_reminders',  ['lead_id'=>$id]);
        $wpdb->delete($wpdb->prefix.'crm_leads',      ['id'=>$id]);
        return new WP_REST_Response(['success'=>true]);
    }

    public static function move_stage( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $id     = (int)$req->get_param('id');
        $status = sanitize_text_field($req->get_param('status')?:'new_lead');
        $wpdb->update($wpdb->prefix.'crm_leads',
            ['status'=>$status,'updated_at'=>current_time('mysql')],
            ['id'=>$id]
        );
        return new WP_REST_Response(['success'=>true]);
    }

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

        $wpdb->update("{$pre}crm_leads",[
            'status'               => 'converted',
            'converted_to_sale_id' => $sale_id,
        ],['id'=>$id]);

        // افزودن یادداشت تبدیل
        $wpdb->insert("{$pre}crm_activities",[
            'lead_id'       => $id,
            'type'          => 'note',
            'direction'     => 'outbound',
            'subject'       => 'لید تبدیل به مشتری شد',
            'body'          => $sale_id ? 'فروش #'.$sale_id : '',
            'activity_date' => current_time('mysql'),
            'result'        => 'positive',
        ]);

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

    public static function matching_units( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $pre  = $wpdb->prefix;
        $id   = (int)$req->get_param('id');
        $lead = $wpdb->get_row($wpdb->prepare(
            "SELECT budget_min,budget_max,preferred_type,preferred_area_sqm FROM {$pre}crm_leads WHERE id=%d",$id
        ),ARRAY_A);
        if (!$lead) return new WP_REST_Response(['data'=>[]]);

        $wheres = ["u.status='available'"];
        $args   = [];
        if ($lead['preferred_type'] && $lead['preferred_type']!=='any') {
            $wheres[]='u.type=%s'; $args[]=$lead['preferred_type'];
        }
        if ($lead['budget_min'] && $lead['budget_min']>0) {
            $wheres[]='u.base_price >= %f'; $args[]=(float)$lead['budget_min'];
        }
        if ($lead['budget_max'] && $lead['budget_max']>0) {
            $wheres[]='u.base_price <= %f'; $args[]=(float)$lead['budget_max'];
        }

        $where = 'WHERE '.implode(' AND ',$wheres);
        $sql   = "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} ORDER BY u.base_price LIMIT 10";
        $rows  = $args ? $wpdb->get_results($wpdb->prepare($sql,...$args),ARRAY_A) : $wpdb->get_results($sql,ARRAY_A);
        return new WP_REST_Response(['data'=>$rows??[]]);
    }

    private static function _lead_data( WP_REST_Request $req, bool $all=true ): array {
        $keys = ['type','name','phone','phone2','email','address','source','status',
                 'budget_min','budget_max','preferred_type','preferred_floor',
                 'preferred_area','preferred_area_sqm','project_id',
                 'assigned_user_id','assigned_user_name','last_contact_date',
                 'next_followup','score','notes'];
        $floats = ['budget_min','budget_max','preferred_area_sqm'];
        $ints   = ['project_id','assigned_user_id','score'];
        $data   = [];
        foreach ($keys as $k) {
            $v = $req->get_param($k);
            if ($v===null && !$all) continue;
            if ($v===null) continue; // skip nulls always
            $data[$k] = in_array($k,$ints) ? (int)$v
                      : (in_array($k,$floats) ? (float)$v
                      : sanitize_textarea_field((string)$v));
        }
        return $data;
    }

    /* ══════════════════════════════════════════════════════════
       فعالیت‌ها
    ══════════════════════════════════════════════════════════ */
    public static function get_activities( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $rows = $wpdb->get_results($wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}crm_activities WHERE lead_id=%d ORDER BY activity_date DESC",
            (int)$req->get_param('id')
        ),ARRAY_A);
        return new WP_REST_Response(['data'=>$rows??[]]);
    }

    public static function create_activity( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $pre  = $wpdb->prefix;
        $id   = (int)$req->get_param('id');
        $data = [
            'lead_id'        => $id,
            'type'           => sanitize_text_field($req->get_param('type')      ?:'call'),
            'direction'      => sanitize_text_field($req->get_param('direction') ?:'outbound'),
            'subject'        => sanitize_text_field($req->get_param('subject')   ?:''),
            'body'           => sanitize_textarea_field($req->get_param('body')  ?:''),
            'activity_date'  => sanitize_text_field($req->get_param('activity_date') ?: current_time('mysql')),
            'duration_min'   => $req->get_param('duration_min') ? (int)$req->get_param('duration_min') : null,
            'result'         => sanitize_text_field($req->get_param('result')      ?:'neutral'),
            'next_action'    => sanitize_text_field($req->get_param('next_action') ?:''),
            'created_by_name'=> sanitize_text_field($req->get_param('created_by_name') ?:''),
        ];
        foreach ($data as $k=>$v) { if ($v===''||$v===null) unset($data[$k]); }
        $data['lead_id']  = $id;
        $data['type']     = sanitize_text_field($req->get_param('type')?:'call');
        $data['direction']= sanitize_text_field($req->get_param('direction')?:'outbound');
        $data['subject']  = sanitize_text_field($req->get_param('subject')?:'');
        $data['result']   = sanitize_text_field($req->get_param('result')?:'neutral');
        $data['activity_date'] = sanitize_text_field($req->get_param('activity_date')?:current_time('mysql'));

        if (!$data['subject']) return new WP_REST_Response(['message'=>'موضوع الزامی است'],400);
        $wpdb->insert("{$pre}crm_activities",$data);

        // به‌روزرسانی آخرین تماس
        $wpdb->update("{$pre}crm_leads",['last_contact_date'=>date('Y-m-d')],['id'=>$id]);

        // به‌روزرسانی امتیاز
        self::_recalc_score($id);

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

    public static function delete_activity( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $wpdb->delete($wpdb->prefix.'crm_activities',['id'=>(int)$req->get_param('act_id')]);
        return new WP_REST_Response(['success'=>true]);
    }

    /* ══════════════════════════════════════════════════════════
       یادآورها
    ══════════════════════════════════════════════════════════ */
    public static function get_reminders( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $rows = $wpdb->get_results($wpdb->prepare(
            "SELECT * FROM {$wpdb->prefix}crm_reminders WHERE lead_id=%d ORDER BY due_date ASC",
            (int)$req->get_param('id')
        ),ARRAY_A);
        return new WP_REST_Response(['data'=>$rows??[]]);
    }

    public static function create_reminder( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $id   = (int)$req->get_param('id');
        $data = [
            'lead_id'  => $id,
            'title'    => sanitize_text_field($req->get_param('title')?:''),
            'due_date' => sanitize_text_field($req->get_param('due_date')?:date('Y-m-d')),
            'due_time' => sanitize_text_field($req->get_param('due_time')?:''),
            'status'   => 'pending',
            'notes'    => sanitize_textarea_field($req->get_param('notes')?:''),
        ];
        if (!$data['title'])  return new WP_REST_Response(['message'=>'عنوان الزامی است'],400);
        if (empty($data['due_time'])) unset($data['due_time']);
        $wpdb->insert($wpdb->prefix.'crm_reminders',$data);
        // ذخیره تاریخ پیگیری در لید
        $wpdb->update($wpdb->prefix.'crm_leads',['next_followup'=>$data['due_date']],['id'=>$id]);
        return new WP_REST_Response(['id'=>$wpdb->insert_id,'success'=>true],201);
    }

    public static function update_reminder( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $data=[];
        foreach (['title','due_date','due_time','status','notes'] as $k) {
            $v=$req->get_param($k); if($v!==null) $data[$k]=sanitize_textarea_field((string)$v);
        }
        $wpdb->update($wpdb->prefix.'crm_reminders',$data,['id'=>(int)$req->get_param('rem_id')]);
        return new WP_REST_Response(['success'=>true]);
    }

    public static function delete_reminder( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $wpdb->delete($wpdb->prefix.'crm_reminders',['id'=>(int)$req->get_param('rem_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;

        $by_status = $wpdb->get_results(
            "SELECT status, COUNT(*) AS cnt FROM {$pre}crm_leads GROUP BY status",ARRAY_A
        );
        $by_source = $wpdb->get_results(
            "SELECT source, COUNT(*) AS cnt FROM {$pre}crm_leads WHERE status NOT IN ('converted','lost') GROUP BY source ORDER BY cnt DESC",ARRAY_A
        );
        $cold = $wpdb->get_results(
            "SELECT id,name,phone,last_contact_date,DATEDIFF(CURDATE(),last_contact_date) AS days
             FROM {$pre}crm_leads
             WHERE status NOT IN ('converted','lost') AND last_contact_date IS NOT NULL
               AND DATEDIFF(CURDATE(),last_contact_date) > 7
             ORDER BY days DESC LIMIT 10",ARRAY_A
        );
        $today_rem = $wpdb->get_results(
            "SELECT r.*, l.name AS lead_name, l.phone AS lead_phone
             FROM {$pre}crm_reminders r
             JOIN {$pre}crm_leads l ON l.id=r.lead_id
             WHERE r.status='pending' AND r.due_date <= CURDATE()
             ORDER BY r.due_date, r.due_time LIMIT 20",ARRAY_A
        );

        return new WP_REST_Response([
            'by_status'  => $by_status,
            'by_source'  => $by_source,
            'cold_leads' => $cold,
            'overdue_reminders' => $today_rem,
        ]);
    }

    public static function get_today_reminders( WP_REST_Request $req ): WP_REST_Response {
        global $wpdb;
        $rows = $wpdb->get_results(
            "SELECT r.*, l.name AS lead_name, l.phone AS lead_phone, l.status AS lead_status
             FROM {$wpdb->prefix}crm_reminders r
             JOIN {$wpdb->prefix}crm_leads l ON l.id=r.lead_id
             WHERE r.status='pending' AND r.due_date <= CURDATE()
             ORDER BY r.due_date, r.due_time",ARRAY_A
        );
        return new WP_REST_Response(['data'=>$rows??[]]);
    }

    /* ── امتیازدهی خودکار ────────────────────────────────── */
    private static function _recalc_score( int $lead_id ): void {
        global $wpdb;
        $pre   = $wpdb->prefix;
        $lead  = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$pre}crm_leads WHERE id=%d",$lead_id),ARRAY_A);
        if (!$lead) return;

        $score = 0;
        // اطلاعات تماس
        if ($lead['phone'])       $score += 10;
        if ($lead['email'])       $score += 5;
        if ($lead['budget_min'])  $score += 15;
        if ($lead['project_id'])  $score += 10;
        // مرحله پایپ‌لاین
        $stage_score = ['new_lead'=>0,'interested'=>10,'visited'=>20,'negotiating'=>30,'proposed'=>40,'reserved'=>50];
        $score += $stage_score[$lead['status']] ?? 0;
        // تعداد فعالیت‌ها
        $acts = (int)$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$pre}crm_activities WHERE lead_id=%d",$lead_id));
        $score += min($acts*2, 20);

        $wpdb->update("{$pre}crm_leads",['score'=>min($score,100)],['id'=>$lead_id]);
    }
}
