<?php
namespace EasyChat\Library\Commerce;

final class WebasystCommerceContextProvider 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');
        try {
            $ids=array(); $evidence='';
            if ($emails) {
                $rows=$this->rows($this->db->query("SELECT DISTINCT `contact_id` FROM `{$this->prefix}wa_contact_emails` WHERE `email` IN (".$this->quoted($emails).") LIMIT 3"));
                foreach($rows as $row) $ids[(int)$row['contact_id']]=(int)$row['contact_id'];
                if ($rows) $evidence='email';
            }
            if ($phones) {
                $rows=$this->rows($this->db->query("SELECT DISTINCT `contact_id` FROM `{$this->prefix}wa_contact_data` WHERE `field`='phone' AND `value` IN (".$this->quoted($phones).") LIMIT 3"));
                foreach($rows as $row) $ids[(int)$row['contact_id']]=(int)$row['contact_id'];
                if ($rows && $evidence==='') $evidence='phone';
            }
            $ids=array_values(array_filter($ids));
            if (count($ids)>1) return $this->unresolved('ambiguous');
            return count($ids)===1 ? $this->matched((string)$ids[0],'contact_id',$evidence) : $this->unresolved('not_found');
        } catch (\Throwable $e) { return $this->unresolved('unavailable'); }
    }

    public function findOrders(array $ref, int $limit=3): array
    {
        if (($ref['kind']??'')!=='contact_id' || (int)($ref['id']??0)<=0) return array();
        $limit=$this->limit($limit); $where='o.`contact_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.`create_datetime`,o.`update_datetime`,o.`state_id`,o.`total`,o.`currency`,o.`paid_datetime` FROM `{$this->prefix}shop_order` o WHERE {$where} ORDER BY o.`create_datetime` 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`,`product_id`,`name`,`quantity` FROM `{$this->prefix}shop_order_items` 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'];$state=(string)$r['state_id'];return array('id'=>$id,'number'=>$id,'date'=>(string)$r['create_datetime'],'updated_at'=>(string)($r['update_datetime']??$r['create_datetime']),'status'=>$this->state($state),'total'=>$this->money($r['total']??0,(string)($r['currency']??'')),'payment'=>!empty($r['paid_datetime'])?'Оплачен':'Не оплачен','delivery'=>'','payment_status'=>!empty($r['paid_datetime'])?'paid':'pending','refund_status'=>strpos(strtolower($state),'refund')!==false?'full':'none','fulfillment_status'=>$this->fulfillment($state),'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'=>'webasyst_shop_script','index_policy'=>'native_or_diagnostic','recommended'=>array('wa_contact_emails.email','wa_contact_data.field/value','shop_order.contact_id','shop_order_items.order_id')); }

    private function state(string $state): string
    {
        $map=array('new'=>'Новый','processing'=>'В обработке','paid'=>'Оплачен','sent'=>'Отправлен','shipped'=>'Отправлен','completed'=>'Выполнен','refunded'=>'Возвращён','deleted'=>'Удалён');
        return $map[strtolower($state)]??$this->boundedText($state,80);
    }

    private function trackingForOrders(array $ids): array
    {
        try{$rows=$this->rows($this->db->query("SELECT `order_id`,`name`,`value` FROM `{$this->prefix}shop_order_params` WHERE `order_id` IN (".implode(',',array_map('intval',$ids)).") AND `name` IN ('tracking_number','shipping_tracking_number','tracking_provider','shipping_name')"));}catch(\Throwable $e){return array();}
        $meta=array();foreach($rows as$row)$meta[(string)$row['order_id']][(string)$row['name']]=(string)$row['value'];$result=array();foreach($meta as$id=>$values){$number=trim((string)($values['tracking_number']??$values['shipping_tracking_number']??''));if(!preg_match('/^[A-Za-z0-9-]{5,40}$/',$number))continue;$result[$id][]=array('carrier'=>$this->boundedText($values['tracking_provider']??$values['shipping_name']??'',80),'tracking_number'=>$number,'status'=>'unknown');}return$result;
    }
    private function fulfillment(string $state): string
    {
        $state=strtolower($state);return array('new'=>'new','processing'=>'processing','paid'=>'processing','sent'=>'shipped','shipped'=>'shipped','completed'=>'delivered','refunded'=>'returned','deleted'=>'cancelled')[$state]??'unknown';
    }
}
