<?php

namespace App\Models;

use CodeIgniter\Model;

class SearchRequestModel extends Model
{
    protected $table = 'property_search_requests';
    protected $primaryKey = 'id';
    
    protected $useAutoIncrement = true;
    
    protected $returnType = 'array';
    protected $useSoftDeletes = false;
    
    protected $allowedFields = [
        'name', 'email', 'phone', 'message', 'search_criteria', 'consents', 
        'consent_timestamp', 'date', 'status', 'readed', 'agent_id', 
        'assigned_at', 'completed_at', 'last_reply', 'updated_at'
    ];
    
    /**
     * Get search requests with agent details and sorting
     */
    public function getSearchRequestsWithDetails($userId = null, $isAdmin = false, $limit = 20, $offset = 0)
    {
        $builder = $this->db->table($this->table . ' sr')
            ->select('sr.*, u.name_surname as agent_name, u.mail as agent_email, u.phone as agent_phone,
                     (SELECT COUNT(*) FROM search_request_replies WHERE request_id = sr.id) as reply_count')
            ->join('user u', 'sr.agent_id = u.id', 'left');
        
        if (!$isAdmin && $userId !== null) {
            $builder->where('sr.agent_id', $userId);
        }
        
        $builder->orderBy("CASE 
            WHEN sr.status = 'pending' THEN 1 
            WHEN sr.status = 'assigned' THEN 2 
            WHEN sr.status = 'completed' THEN 3 
            ELSE 4 
        END", 'ASC');
        
        $builder->orderBy('sr.date', 'DESC');
        
        return $builder->limit($limit, $offset)
                      ->get()
                      ->getResultArray();
    }

    /**
     * Get search request details with replies
     */
    public function getRequestWithReplies($requestId, $userId = null, $isAdmin = false)
    {
        $request = $this->db->table($this->table . ' sr')
            ->select('sr.*, u.name_surname as agent_name, u.mail as agent_email, u.phone as agent_phone')
            ->join('user u', 'sr.agent_id = u.id', 'left')
            ->where('sr.id', $requestId)
            ->get()
            ->getRowArray();
        
        if (!$request) {
            return null;
        }
        
        if (!$isAdmin && $userId !== null && $request['agent_id'] != $userId) {
            return null;
        }
        
        $replies = $this->db->table('search_request_replies r')
            ->select('r.*, u.name_surname as user_name, u.type as user_type')
            ->join('user u', 'r.user_id = u.id', 'left')
            ->where('r.request_id', $requestId)
            ->orderBy('r.created_at', 'ASC')
            ->get()
            ->getResultArray();
        
        $this->update($requestId, ['readed' => 1]);
        
        $request['replies'] = $replies;
        
        return $request;
    }
    
    /**
     * Assign request to agent
     */
    public function assignToAgent($requestId, $agentId, $note, $userId)
    {
        $request = $this->find($requestId);
        if (!$request) {
            return false;
        }
        
        $userModel = model('App\Models\UserModel');
        $user = $userModel->find($userId);
        
        if (!$user || $user['type'] !== 'ADMIN') {
            return false;
        }
        
        $agent = $userModel->find($agentId);
        if (!$agent || $agent['type'] !== 'AGENT') {
            return false;
        }
        
        $success = $this->update($requestId, [
            'status' => 'assigned',
            'agent_id' => $agentId,
            'assigned_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s')
        ]);
        
        if ($success && !empty($note)) {
            $this->addReply($requestId, $userId, $note, true);
        }
        
        if ($success) {
            $this->sendAssignmentNotification($request, $agent, $note);
        }
        
        return $success;
    }
    
    /**
     * Add a reply to a search request
     */
    public function addReply($requestId, $userId, $message, $isSystemMessage = false)
    {
        $request = $this->find($requestId);
        if (!$request) {
            return false;
        }
        
        $userModel = model('App\Models\UserModel');
        $user = $userModel->find($userId);
        
        if (!$user) {
            return false;
        }
        
        $isAdmin = $user['type'] === 'ADMIN';
        if (!$isAdmin && $request['agent_id'] != $userId) {
            return false;
        }
        
        $replyData = [
            'request_id' => $requestId,
            'user_id' => $userId,
            'message' => $message,
            'created_at' => date('Y-m-d H:i:s'),
            'is_system_message' => $isSystemMessage ? 1 : 0
        ];
        
        $this->db->table('search_request_replies')->insert($replyData);
        $replyId = $this->db->insertID();
        
        $this->update($requestId, [
            'last_reply' => $message,
            'updated_at' => date('Y-m-d H:i:s')
        ]);
        
        if ($replyId && !$isSystemMessage) {
            $this->sendReplyNotifications($request, [
                'id' => $replyId,
                'user_id' => $userId,
                'message' => $message
            ]);
        }
        
        return $replyId;
    }

    /**
     * Complete a search request
     */
    public function completeRequest($requestId, $userId)
    {
        $request = $this->find($requestId);
        if (!$request) {
            return false;
        }
        
        $userModel = model('App\Models\UserModel');
        $user = $userModel->find($userId);
        
        if (!$user) {
            return false;
        }
        
        $isAdmin = $user['type'] === 'ADMIN';
        if (!$isAdmin && $request['agent_id'] != $userId) {
            return false;
        }
        
        $success = $this->update($requestId, [
            'status' => 'completed',
            'completed_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s')
        ]);
        
        return $success;
    }

    /**
     * Get assigned requests for agent
     */
    public function getAssignedRequests($agentId, $limit = 20, $offset = 0)
    {
        return $this->db->table($this->table . ' sr')
            ->select('sr.*, 
                     (SELECT COUNT(*) FROM search_request_replies WHERE request_id = sr.id) as reply_count')
            ->where('sr.agent_id', $agentId)
            ->where('sr.status !=', 'completed')
            ->orderBy('sr.assigned_at', 'DESC')
            ->limit($limit, $offset)
            ->get()
            ->getResultArray();
    }

    /**
     * Update search criteria
     */
    public function updateSearchCriteria($requestId, $searchCriteria, $userId)
    {
        $request = $this->find($requestId);
        if (!$request) {
            return false;
        }
        
        $userModel = model('App\Models\UserModel');
        $user = $userModel->find($userId);
        
        if (!$user) {
            return false;
        }
        
        $isAdmin = $user['type'] === 'ADMIN';
        if (!$isAdmin && $request['agent_id'] != $userId) {
            return false;
        }
        
        $success = $this->update($requestId, [
            'search_criteria' => $searchCriteria,
            'updated_at' => date('Y-m-d H:i:s')
        ]);
        
        if ($success) {
            $this->addReply($requestId, $userId, 'Arama kriterleri güncellendi.', true);
        }
        
        return $success;
    }
    
    /**
     * Send notification for new search request
     */
    public function sendNewSearchRequestNotifications($request)
    {
        try {
            $notificationService = service('NotificationService');
            $userModel = model('App\Models\UserModel');
            
            // Parse search criteria for notification
            $searchCriteria = json_decode($request['search_criteria'], true);
            $criteriaText = $this->formatSearchCriteriaForNotification($searchCriteria);
            
            // Notification data
            $notificationData = [
                'request_id' => $request['id'],
                'click_action' => 'OPEN_SEARCH_REQUEST_DETAIL',
                'notification_type' => 'new_search_request'
            ];
            
            // Get admin users
            $admins = $userModel->where('type', 'ADMIN')->findAll();
            
            // Notify all admins
            foreach ($admins as $admin) {
                // Add to notifications table
                $notificationModel = model('App\Models\NotificationModel');
                $notificationModel->addNotification([
                    'user_id' => $admin['id'],
                    'title' => 'Yeni Mülk Arama Talebi',
                    'body' => $request['name'] . ' - ' . $criteriaText,
                    'data' => json_encode($notificationData),
                    'target' => 'new_search_request',
                    'status' => 'sent',
                    'created_by' => null
                ]);
                
                // Send FCM notification
                $notificationService->sendToUser(
                    $admin['id'],
                    'Yeni Mülk Arama Talebi',
                    $request['name'] . ' - ' . $criteriaText,
                    $notificationData
                );
            }
        } catch (\Exception $e) {
            log_message('error', 'New search request notification error: ' . $e->getMessage());
        }
    }
    
    /**
     * Send assignment notification
     */
    private function sendAssignmentNotification($request, $agent, $note)
    {
        try {
            $notificationService = service('NotificationService');
            
            $searchCriteria = json_decode($request['search_criteria'], true);
            $criteriaText = $this->formatSearchCriteriaForNotification($searchCriteria);
            
            $notificationData = [
                'request_id' => $request['id'],
                'click_action' => 'OPEN_SEARCH_REQUEST_DETAIL',
                'notification_type' => 'request_assigned'
            ];
            
            $title = 'Size Mülk Arama Talebi Atandı';
            $body = $request['name'] . ' - ' . $criteriaText;
            if (!empty($note)) {
                $body .= ' - Not: ' . $note;
            }
            
            $notificationModel = model('App\Models\NotificationModel');
            $notificationModel->addNotification([
                'user_id' => $agent['id'],
                'title' => $title,
                'body' => $body,
                'data' => json_encode($notificationData),
                'target' => 'request_assigned',
                'status' => 'sent',
                'created_by' => null
            ]);
            
            $notificationService->sendToUser(
                $agent['id'],
                $title,
                $body,
                $notificationData
            );
            
            return true;
        } catch (\Exception $e) {
            log_message('error', 'Assignment notification error: ' . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Send reply notifications
     */
    private function sendReplyNotifications($request, $reply = null)
    {
        try {
            $notificationService = service('NotificationService');
            $userModel = model('App\Models\UserModel');
            
            $searchCriteria = json_decode($request['search_criteria'], true);
            $criteriaText = $this->formatSearchCriteriaForNotification($searchCriteria);
            
            if ($reply) {
                $user = $userModel->find($reply['user_id']);
                
                if ($user) {
                    $isAgent = $user['type'] === 'AGENT';
                    
                    $shortMessage = mb_strlen($reply['message']) > 100 
                        ? mb_substr($reply['message'], 0, 97) . '...' 
                        : $reply['message'];
                    
                    $title = 'Arama Talebine Yeni Cevap: ' . $criteriaText;
                    $body = $user['name_surname'] . ': ' . $shortMessage;
                    
                    $data = [
                        'request_id' => $request['id'],
                        'reply_id' => $reply['id'],
                        'click_action' => 'OPEN_SEARCH_REQUEST_DETAIL',
                        'notification_type' => 'search_request_reply'
                    ];
                    
                    if ($isAgent) {
                        $admins = $userModel->where('type', 'ADMIN')->findAll();
                        
                        foreach ($admins as $admin) {
                            $notificationModel = model('App\Models\NotificationModel');
                            $notificationModel->addNotification([
                                'user_id' => $admin['id'],
                                'title' => $title,
                                'body' => $body,
                                'data' => json_encode($data),
                                'target' => 'search_request_reply',
                                'status' => 'sent'
                            ]);
                            
                            $notificationService->sendToUser(
                                $admin['id'],
                                $title,
                                $body,
                                $data
                            );
                        }
                    } else {
                        if (!empty($request['agent_id'])) {
                            $notificationModel = model('App\Models\NotificationModel');
                            $notificationModel->addNotification([
                                'user_id' => $request['agent_id'],
                                'title' => $title,
                                'body' => $body,
                                'data' => json_encode($data),
                                'target' => 'search_request_reply',
                                'status' => 'sent'
                            ]);
                            
                            $notificationService->sendToUser(
                                $request['agent_id'],
                                $title,
                                $body,
                                $data
                            );
                        }
                    }
                }
            }
            
            return true;
        } catch (\Exception $e) {
            log_message('error', 'Reply notification error: ' . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Format search criteria for notification with category and location names
     * ✅ DÜZELTİLDİ: treefield tablosunu kullanıyor
     */
    private function formatSearchCriteriaForNotification($criteria)
    {
        if (empty($criteria)) {
            return 'Genel arama';
        }
        
        $important = [];
        
        // Get category name from ID (treefield tablosundan)
        if (!empty($criteria['search_category']) || !empty($criteria['field_4'])) {
            $categoryId = $criteria['search_category'] ?? $criteria['field_4'];
            $categoryName = $this->getCategoryNameById($categoryId);
            if ($categoryName) {
                $important[] = $categoryName;
            }
        }
        
        // Get location name from ID (çoklu lokasyon desteği)
        if (!empty($criteria['search_location']) || !empty($criteria['field_5']) || !empty($criteria['location_id'])) {
            // location_id'yi de kontrol et
            $locationIds = $criteria['search_location'] ?? $criteria['field_5'] ?? $criteria['location_id'];
            
            // Virgülle ayrılmış lokasyon ID'lerini kontrol et
            if (strpos($locationIds, ',') !== false) {
                $locationIdArray = explode(',', $locationIds);
                $locationNames = [];
                
                foreach ($locationIdArray as $locationId) {
                    $locationId = trim($locationId);
                    if (!empty($locationId)) {
                        $locationName = $this->getLocationNameById($locationId);
                        if ($locationName) {
                            $locationNames[] = $locationName;
                        }
                    }
                }
                
                if (!empty($locationNames)) {
                    if (count($locationNames) == 1) {
                        $important[] = $locationNames[0];
                    } else if (count($locationNames) <= 2) {
                        $important[] = implode(', ', $locationNames);
                    } else {
                        $important[] = $locationNames[0] . ', ' . $locationNames[1] . ' +' . (count($locationNames) - 2);
                    }
                }
            } else {
                // Tek lokasyon
                $locationName = $this->getLocationNameById($locationIds);
                if ($locationName) {
                    $important[] = $locationName;
                }
            }
        }
        
        // Add price range
        if (!empty($criteria['field_6_min'])) {
            $important[] = 'Min: ' . $this->formatPrice($criteria['field_6_min']);
        }
        if (!empty($criteria['field_6_max'])) {
            $important[] = 'Max: ' . $this->formatPrice($criteria['field_6_max']);
        }
        
        // Add room info
        if (!empty($criteria['field_7'])) {
            $important[] = $criteria['field_7'] . ' oda';
        }
        
        // Add search term
        if (!empty($criteria['search'])) {
            $searchTerm = mb_strlen($criteria['search']) > 20 
                ? mb_substr($criteria['search'], 0, 17) . '...' 
                : $criteria['search'];
            $important[] = '"' . $searchTerm . '"';
        }
        
        return !empty($important) ? implode(' • ', $important) : 'Mülk arama talebi';
    }

    /**
     * Get category name by ID from treefield table
     * ✅ DÜZELTİLDİ: treefield tablosunu kullanıyor
     */
    private function getCategoryNameById($categoryId)
    {
        try {
            if (empty($categoryId)) {
                return null;
            }
            
            // treefield tablosundan kategori bilgisini al (field_id = 79 kategoriler için)
            $result = $this->db->table('treefield t')
                ->select('tl.value as title')
                ->join('treefield_lang tl', 't.id = tl.treefield_id', 'left')
                ->where('t.id', $categoryId)
                ->where('t.field_id', 79) // Category field ID
               ->get()
                ->getRowArray();
            
            return $result ? $result['title'] : null;
        } catch (\Exception $e) {
            log_message('error', 'Error getting category name: ' . $e->getMessage());
            return null;
        }
    }

    /**
     * Get location name by ID from treefield table
     * ✅ DÜZELTİLDİ: Tam adres formatı (Mahalle, İlçe, İl)
     */
    private function getLocationNameById($locationId)
    {
        try {
            if (empty($locationId)) {
                return null;
            }
            
            // treefield tablosundan lokasyon bilgisini al (field_id = 64 lokasyonlar için)
            $result = $this->db->table('treefield t')
                ->select('t.id, t.level, t.parent_id, tl.value as title')
                ->join('treefield_lang tl', 't.id = tl.treefield_id', 'left')
                ->where('t.id', $locationId)
                ->where('t.field_id', 64) // Location field ID
                
                ->get()
                ->getRowArray();
            
            if (!$result) {
                return null;
            }
            
            // Seviyeye göre tam adres oluştur
            $locationNames = [$result['title']];
            
            // Eğer mahalle ise (level = 2), ilçe ve il adlarını da ekle
            if ($result['level'] == 2 && !empty($result['parent_id'])) {
                $district = $this->db->table('treefield t')
                    ->select('t.parent_id, tl.value as title')
                    ->join('treefield_lang tl', 't.id = tl.treefield_id', 'left')
                    ->where('t.id', $result['parent_id'])
                    ->where('t.field_id', 64)
              
                    ->get()
                    ->getRowArray();
                
                if ($district) {
                    $locationNames[] = $district['title'];
                    
                    // İl adını da ekle
                    if (!empty($district['parent_id'])) {
                        $province = $this->db->table('treefield t')
                            ->select('tl.value as title')
                            ->join('treefield_lang tl', 't.id = tl.treefield_id', 'left')
                            ->where('t.id', $district['parent_id'])
                            ->where('t.field_id', 64)
                          
                            ->get()
                            ->getRowArray();
                        
                        if ($province) {
                            $locationNames[] = $province['title'];
                        }
                    }
                }
            }
            // Eğer ilçe ise (level = 1), il adını da ekle
            else if ($result['level'] == 1 && !empty($result['parent_id'])) {
                $province = $this->db->table('treefield t')
                    ->select('tl.value as title')
                    ->join('treefield_lang tl', 't.id = tl.treefield_id', 'left')
                    ->where('t.id', $result['parent_id'])
                    ->where('t.field_id', 64)
                 
                    ->get()
                    ->getRowArray();
                
                if ($province) {
                    $locationNames[] = $province['title'];
                }
            }
            
            return implode(', ', $locationNames);
        } catch (\Exception $e) {
            log_message('error', 'Error getting location name: ' . $e->getMessage());
            return null;
        }
    }
    
    /**
     * Format price for display
     */
    private function formatPrice($value)
    {
        try {
            $price = intval(str_replace(['.', ','], '', $value));
            if ($price >= 1000000) {
                return '€' . number_format($price / 1000000, 1) . 'M';
            } elseif ($price >= 1000) {
                return '€' . number_format($price / 1000, 0) . 'B';
            } else {
                return '€' . $price;
            }
        } catch (\Exception $e) {
            return '€' . $value;
        }
    }
    
    /**
     * Get count of unread search requests
     */
    public function getUnreadCount($userId = null, $isAdmin = false)
    {
        $builder = $this->where('readed', 0);
        
        if (!$isAdmin && $userId !== null) {
            $builder->where('agent_id', $userId);
        }
        
        return $builder->countAllResults();
    }
}