<?php
require_once 'config/database.php';
require_once 'CommunicationSenderController.php';

class CommunicationsController {
    private $conn;

    public function __construct() {
        $database = new Database();
        $this->conn = $database->getConnection();
    }

    // ────────────────────────────── MESSAGES ──────────────────────────────

    public function getMessages($filters) {
        try {
            $limit  = $filters['limit'] ?? 20;
            $offset = $filters['offset'] ?? 0;
            $page   = $filters['page'] ?? 1;
            if ($offset == 0 && $page > 1) $offset = ($page - 1) * $limit;

            $query = "SELECT m.*, CONCAT(u.first_name, ' ', u.last_name) as sender_name
                      FROM messages m
                      LEFT JOIN users u ON m.user_id = u.id
                      WHERE 1=1";

            $params = [];
            $count_params = [];

            // Search
            if (!empty($filters['search'])) {
                $search = "%{$filters['search']}%";
                $query .= " AND (m.subject LIKE :search OR m.content LIKE :search OR m.from LIKE :search OR m.to LIKE :search)";
                $params[':search'] = $search;
                $count_params[':search'] = $search;
            }

            // Filters
            if (!empty($filters['type'])) {
                $query .= " AND m.type = :type";
                $params[':type'] = $filters['type'];
                $count_params[':type'] = $filters['type'];
            }
            if (!empty($filters['status'])) {
                $query .= " AND m.status = :status";
                $params[':status'] = $filters['status'];
                $count_params[':status'] = $filters['status'];
            }
            if ($filters['filter'] ?? '' === 'starred') {
                $query .= " AND m.is_starred = 1";
            }
            if ($filters['filter'] ?? '' === 'unread') {
                $query .= " AND m.is_read = 0";
            }

            $query .= " ORDER BY m.sent_at DESC LIMIT :limit OFFSET :offset";
            $params[':limit'] = (int)$limit;
            $params[':offset'] = (int)$offset;

            $stmt = $this->conn->prepare($query);
            foreach ($params as $k => $v) {
                $type = ($k === ':limit' || $k === ':offset') ? PDO::PARAM_INT : PDO::PARAM_STR;
                $stmt->bindValue($k, $v, $type);
            }
            $stmt->execute();
            $messages = $stmt->fetchAll(PDO::FETCH_ASSOC);

            // Count
            $count_query = "SELECT COUNT(*) as total FROM messages m WHERE 1=1";
            if (!empty($count_params)) {
                foreach ($count_params as $k => $v) {
                    $count_query .= " AND (m.subject LIKE $k OR m.content LIKE $k OR m.from LIKE $k OR m.to LIKE $k)";
                }
            }
            $stmt_count = $this->conn->prepare($count_query);
            foreach ($count_params as $k => $v) {
                $stmt_count->bindValue($k, $v, PDO::PARAM_STR);
            }
            $stmt_count->execute();
            $total = $stmt_count->fetch(PDO::FETCH_ASSOC)['total'];

            $unread = $this->countMessages(['is_read' => 0]);
            $starred = $this->countMessages(['is_starred' => 1]);

            return json_encode([
                'status' => 'success',
                'data' => [
                    'messages' => $messages,
                    'unread'   => $unread,
                    'starred'  => $starred,
                    'pagination' => [
                        'current_page' => (int)$page,
                        'total_pages'  => $total > 0 ? ceil($total / $limit) : 1,
                        'total_records'=> (int)$total
                    ]
                ]
            ], JSON_PRETTY_PRINT);

        } catch (Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    public function sendMessage($data, $user_id) {
        if (empty($data['to']) || empty($data['content'])) {
            return $this->error('Recipient and content are required');
        }

        try {

            // Create sender instance (load keys from config/env)
            $sender = new CommunicationSenderController(
                $_ENV['BREVO_API_KEY'] ?? 'YOUR_KEY',
                $_ENV['TWILIO_ACCOUNT_SID'] ?? 'YOUR_SID',
                $_ENV['TWILIO_AUTH_TOKEN'] ?? 'YOUR_TOKEN',
                $_ENV['TWILIO_PHONE_NUMBER'] ?? '+1234567890'
            );

            // $result = null;
            switch ($data['type']) {
                case 'email':
                    $result = $sender->sendEmail(
                        $data['to'],
                        $data['subject'] ?? 'Communication from IPS',
                        '', // toName optional
                        $data['content'],
                        'noreply@ips.gov', // fromEmail
                        'IPS System' // fromName
                    );
                    break;
                case 'sms':
                    $result = $sender->sendSMS(
                        $data['phone'] ?? $data['to'],
                        $data['content']
                    );
                    break;
                default:
                    return $this->error('Unsupported communication type');
            }

            if ($result['status'] === 'success') {
            //     // Log success and return
            //     // ... insert into DB ...
            //     $query = "INSERT INTO messages 
            //             (user_id, type, subject, content, `to`, `from`, status, priority, 
            //             related_invoice, related_appointment, sent_at, is_starred, is_read)
            //             VALUES 
            //             (:user_id, :type, :subject, :content, :to, :from, 'sent', :priority, 
            //             :related_invoice, :related_appointment, NOW(), 0, 1)";

            //     $stmt = $this->conn->prepare($query);
            //     $stmt->bindValue(':user_id', $user_id ?? 1, PDO::PARAM_INT);
            //     $stmt->bindValue(':type', $data['type'] ?? 'internal', PDO::PARAM_STR);
            //     $stmt->bindValue(':subject', $data['subject'] ?? null, PDO::PARAM_STR);
            //     $stmt->bindValue(':content', $data['content'], PDO::PARAM_STR);
            //     $stmt->bindValue(':to', $data['to'], PDO::PARAM_STR);
            //     $stmt->bindValue(':from', $data['from'] ?? ('Unknown' . ' (IPO)'), PDO::PARAM_STR);
            //     $stmt->bindValue(':priority', $data['priority'] ?? 'medium', PDO::PARAM_STR);
            //     $stmt->bindValue(':related_invoice', $data['related_invoice'] ?? null, PDO::PARAM_STR);
            //     $stmt->bindValue(':related_appointment', $data['related_appointment'] ?? null, PDO::PARAM_STR);

            //     $stmt->execute();
            //     $id = $this->conn->lastInsertId();

            //     $message = $this->getMessageById($id);
            //     return json_encode(['status' => 'success', 'data' => $message]);
            //  return json_encode(['status' => 'success', 'data' => $result['data']]);
            // } else {
            //     return $result; // error response
            // }

            $query = "INSERT INTO messages 
                        (user_id, type, subject, content, `to`, `from`, status, priority, 
                        related_invoice, related_appointment, sent_at, is_starred, is_read)
                        VALUES 
                        (:user_id, :type, :subject, :content, :to, :from, 'sent', :priority, 
                        :related_invoice, :related_appointment, NOW(), 0, 1)";

                $stmt = $this->conn->prepare($query);
                $stmt->bindValue(':user_id', $user_id ?? 1, PDO::PARAM_INT);
                $stmt->bindValue(':type', $data['type'] ?? 'internal', PDO::PARAM_STR);
                $stmt->bindValue(':subject', $data['subject'] ?? null, PDO::PARAM_STR);
                $stmt->bindValue(':content', $data['content'], PDO::PARAM_STR);
                $stmt->bindValue(':to', $data['to'], PDO::PARAM_STR);
                $stmt->bindValue(':from', $data['from'] ?? ('Unknown' . ' (IPO)'), PDO::PARAM_STR);
                $stmt->bindValue(':priority', $data['priority'] ?? 'medium', PDO::PARAM_STR);
                $stmt->bindValue(':related_invoice', $data['related_invoice'] ?? null, PDO::PARAM_STR);
                $stmt->bindValue(':related_appointment', $data['related_appointment'] ?? null, PDO::PARAM_STR);

                $stmt->execute();
                $id = $this->conn->lastInsertId();

                $message = $this->getMessageById($id);
                return json_encode(['status' => 'success', 'data' => $message]);
            } else {
                return $result; // error response
            }
        } catch (Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    public function getMessage($id) {
        try {
            $message = $this->getMessageById($id);
            if (!$message) return $this->error('Message not found', 404);

            // Mark as read
            $this->conn->prepare("UPDATE messages SET is_read = 1 WHERE id = ?")
                       ->execute([$id]);

            return json_encode(['status' => 'success', 'data' => $message]);
        } catch (Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    public function toggleStar($id) {
        try {
            $stmt = $this->conn->prepare("UPDATE messages SET is_starred = NOT is_starred WHERE id = ?");
            $stmt->execute([$id]);
            $message = $this->getMessageById($id);
            return json_encode(['status' => 'success', 'data' => $message]);
        } catch (Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    public function markAsRead($id) {
        try {
            $stmt = $this->conn->prepare("UPDATE messages SET is_read = 1 WHERE id = ?");
            $stmt->execute([$id]);
            return json_encode(['status' => 'success', 'message' => 'Marked as read']);
        } catch (Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    // ────────────────────────────── TEMPLATES ──────────────────────────────

    public function getTemplates($filters) {
        try {
            $query = "SELECT * FROM message_templates ORDER BY usage_count DESC, last_used_at DESC";
            $stmt = $this->conn->prepare($query);
            $stmt->execute();
            $templates = $stmt->fetchAll(PDO::FETCH_ASSOC);

            return json_encode(['status' => 'success', 'data' => $templates]);
        } catch (Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    public function createTemplate($data) {
        if (empty($data['name']) || empty($data['content'])) {
            return $this->error('Name and content are required');
        }

        try {
            $query = "INSERT INTO message_templates 
                      (name, category, type, subject, content, variables, usage_count, last_used_at)
                      VALUES 
                      (:name, :category, :type, :subject, :content, :variables, 0, NULL)";

            $stmt = $this->conn->prepare($query);
            $stmt->bindValue(':name', $data['name']);
            $stmt->bindValue(':category', $data['category'] ?? 'general');
            $stmt->bindValue(':type', $data['type'] ?? 'email');
            $stmt->bindValue(':subject', $data['subject'] ?? null);
            $stmt->bindValue(':content', $data['content']);
            $stmt->bindValue(':variables', json_encode($data['variables'] ?? []));

            $stmt->execute();
            $id = $this->conn->lastInsertId();

            return json_encode([
                'status' => 'success',
                'data' => $this->getTemplateById($id)
            ]);
        } catch (Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    public function getTemplate($id) {
        try {
            $template = $this->getTemplateById($id);
            return $template
                ? json_encode(['status' => 'success', 'data' => $template])
                : $this->error('Template not found', 404);
        } catch (Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    public function updateTemplate($id, $data) {
        try {
            $query = "UPDATE message_templates SET 
                      name = :name,
                      category = :category,
                      type = :type,
                      subject = :subject,
                      content = :content,
                      variables = :variables
                      WHERE id = :id";

            $stmt = $this->conn->prepare($query);
            $stmt->bindValue(':id', $id, PDO::PARAM_INT);
            $stmt->bindValue(':name', $data['name'] ?? '');
            $stmt->bindValue(':category', $data['category'] ?? 'general');
            $stmt->bindValue(':type', $data['type'] ?? 'email');
            $stmt->bindValue(':subject', $data['subject'] ?? null);
            $stmt->bindValue(':content', $data['content'] ?? '');
            $stmt->bindValue(':variables', json_encode($data['variables'] ?? []));

            $stmt->execute();

            return json_encode([
                'status' => 'success',
                'data' => $this->getTemplateById($id)
            ]);
        } catch (Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    public function deleteTemplate($id) {
        try {
            $stmt = $this->conn->prepare("DELETE FROM message_templates WHERE id = ?");
            $stmt->execute([$id]);
            return json_encode(['status' => 'success', 'message' => 'Template deleted']);
        } catch (Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    public function useTemplate($id) {
        try {
            $stmt = $this->conn->prepare("UPDATE message_templates 
                                          SET usage_count = usage_count + 1, last_used_at = NOW()
                                          WHERE id = ?");
            $stmt->execute([$id]);

            return json_encode([
                'status' => 'success',
                'data' => $this->getTemplateById($id)
            ]);
        } catch (Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    // ────────────────────────────── CONTACTS ──────────────────────────────

    public function getContacts() {
        try {
            $stmt = $this->conn->prepare("SELECT u.id, u.first_name, u.last_name, u.email, u.phone, u.nin, u.profile_photo, u.status, u.role_id, u.last_login, r.name as role 
                    FROM users u 
                    JOIN roles r ON u.role_id = r.id ");
            // $stmt = $this->conn->prepare("SELECT u.id, u.first_name, u.last_name, u.email, u.phone, u.nin, u.profile_photo, u.status, u.role_id, u.last_login, r.name as role, FROM communication_contacts ORDER BY name");
            $stmt->execute();
            $contacts = $stmt->fetchAll(PDO::FETCH_ASSOC);

            return json_encode(['status' => 'success', 'data' => $contacts]);
        } catch (Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    // ────────────────────────────── HELPERS ──────────────────────────────

    private function getMessageById($id) {
        $stmt = $this->conn->prepare("
            SELECT m.*, CONCAT(u.first_name, ' ', u.last_name) as sender_name
            FROM messages m
            LEFT JOIN users u ON m.user_id = u.id
            WHERE m.id = ?
        ");
        $stmt->execute([$id]);
        return $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
    }

    private function getTemplateById($id) {
        $stmt = $this->conn->prepare("SELECT * FROM message_templates WHERE id = ?");
        $stmt->execute([$id]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if ($row) $row['variables'] = json_decode($row['variables'], true);
        return $row;
    }

    private function countMessages($where) {
        $query = "SELECT COUNT(*) FROM messages WHERE ";
        $clauses = [];
        $params = [];
        foreach ($where as $k => $v) {
            $ph = ":{$k}";
            $clauses[] = "$k = $ph";
            $params[$ph] = $v;
        }
        $query .= implode(' AND ', $clauses);

        $stmt = $this->conn->prepare($query);
        foreach ($params as $k => $v) {
            $stmt->bindValue($k, $v, PDO::PARAM_INT);
        }
        $stmt->execute();
        return (int)$stmt->fetchColumn();
    }

    private function error($message, $code = 400) {
        http_response_code($code);
        return json_encode(['status' => 'error', 'message' => $message]);
    }
}