<?php
namespace EasyChat\Library\Commerce;

final class BitrixCommerceContextProvider extends AbstractCommerceContextProvider
{
    public function capabilities(): array { return array('customer'=>true,'orders'=>true,'order_items'=>true,'read_only'=>true); }

    public function resolveCustomer(array $lookup): array
    {
        $emails=$this->emails($lookup); $phones=$this->phones($lookup);
        if (!$emails && !$phones) return $this->unresolved('not_found');
        $conditions=array();
        if ($emails) $conditions[]="`EMAIL` IN (".$this->quoted($emails).")";
        if ($phones) { $q=$this->quoted($phones); $conditions[]="`PERSONAL_PHONE` IN ({$q})"; $conditions[]="`PERSONAL_MOBILE` IN ({$q})"; }
        try {
            $rows=$this->rows($this->db->query("SELECT `ID`,`EMAIL`,`PERSONAL_PHONE`,`PERSONAL_MOBILE` FROM `{$this->prefix}user` WHERE ".implode(' OR ',$conditions)." ORDER BY `ID` DESC LIMIT 3"));
            $ids=array_values(array_unique(array_filter(array_map(function($r){return (int)($r['ID']??0);},$rows))));
            if (count($ids)>1) return $this->unresolved('ambiguous');
            if (!$ids) return $this->unresolved('not_found');
            $email=mb_strtolower(trim((string)($rows[0]['EMAIL']??'')),'UTF-8');
            return $this->matched((string)$ids[0],'user_id',in_array($email,$emails,true)?'email':'phone');
        } catch (\Throwable $e) { return $this->unresolved('unavailable'); }
    }

    public function findOrders(array $ref,int $limit=3): array
    {
        if (($ref['kind']??'')!=='user_id'||(int)($ref['id']??0)<=0)return array();
        $limit=$this->limit($limit);$where='o.`USER_ID`='.(int)$ref['id'];
        if(!empty($ref['order_id']))$where.=' AND o.`ID`='.(int)$ref['order_id'];
        try {
            $orders=$this->rows($this->db->query("SELECT o.`ID`,o.`ACCOUNT_NUMBER`,o.`DATE_INSERT`,o.`DATE_UPDATE`,o.`STATUS_ID`,o.`PRICE`,o.`CURRENCY`,o.`PAYED`,o.`ALLOW_DELIVERY`,o.`CANCELED`,COALESCE(sl.`NAME`,'') AS `STATUS_NAME` FROM `{$this->prefix}sale_order` o LEFT JOIN `{$this->prefix}sale_status_lang` sl ON sl.`STATUS_ID`=o.`STATUS_ID` AND sl.`LID`='ru' WHERE {$where} ORDER BY o.`DATE_INSERT` DESC,o.`ID` DESC LIMIT {$limit}"));
            if(!$orders)return array();$ids=array_map(function($r){return(int)$r['ID'];},$orders);
            $items=$this->groupItems($this->rows($this->db->query("SELECT `ORDER_ID` AS `order_id`,`PRODUCT_ID` AS `product_id`,`NAME` AS `name`,`QUANTITY` AS `quantity` FROM `{$this->prefix}sale_basket` WHERE `ORDER_ID` IN (".implode(',',$ids).") ORDER BY `ID`")));
            $tracking=$this->trackingForOrders($ids);
            return array_map(function($r)use($items,$tracking){$id=(string)$r['ID'];$cancelled=(string)($r['CANCELED']??'')==='Y';return array('id'=>$id,'number'=>(string)($r['ACCOUNT_NUMBER']?:$id),'date'=>(string)$r['DATE_INSERT'],'updated_at'=>(string)($r['DATE_UPDATE']??$r['DATE_INSERT']),'status'=>$this->boundedText($r['STATUS_NAME']?:('Статус '.$r['STATUS_ID']),80),'total'=>$this->money($r['PRICE']??0,(string)($r['CURRENCY']??'')),'payment'=>(string)$r['PAYED']==='Y'?'Оплачен':'Не оплачен','delivery'=>(string)$r['ALLOW_DELIVERY']==='Y'?'Доставка разрешена':'Ожидает оформления','payment_status'=>(string)$r['PAYED']==='Y'?'paid':'pending','refund_status'=>'unknown','fulfillment_status'=>$cancelled?'cancelled':((string)$r['ALLOW_DELIVERY']==='Y'?'ready':'processing'),'shipments'=>$tracking[$id]??array(),'items'=>array_slice($items[$id]??array(),0,20));},$orders);
        } catch(\Throwable $e){return array();}
    }

    public function health(): array{return array('ready'=>true,'schema'=>'bitrix_sale','index_policy'=>'native_or_diagnostic','recommended'=>array('user.EMAIL','sale_order.USER_ID','sale_basket.ORDER_ID','sale_status_lang.STATUS_ID/LID'));}

    private function trackingForOrders(array $ids): array
    {
        if(!$ids)return array();$tables=array($this->prefix.'sale_order_delivery'=>array('ORDER_ID','TRACKING_NUMBER','DELIVERY_NAME'),$this->prefix.'sale_shipment'=>array('ORDER_ID','TRACKING_NUMBER','DELIVERY_NAME'));$result=array();foreach($tables as$table=>$columns){try{$exists=$this->row($this->db->query("SHOW TABLES LIKE '".$this->db->escape($table)."'"));if(!$exists)continue;$rows=$this->rows($this->db->query("SELECT `ORDER_ID`,`TRACKING_NUMBER`,`DELIVERY_NAME` FROM `{$table}` WHERE `ORDER_ID` IN (".implode(',',array_map('intval',$ids)).") AND `TRACKING_NUMBER`<>''"));foreach($rows as$row){$number=trim((string)($row['TRACKING_NUMBER']??''));if(!preg_match('/^[A-Za-z0-9-]{5,40}$/',$number))continue;$result[(string)$row['ORDER_ID']][]=array('carrier'=>$this->boundedText($row['DELIVERY_NAME']??'',80),'tracking_number'=>$number,'status'=>'unknown');}if($rows)break;}catch(\Throwable $e){continue;}}return$result;
    }
}
