<?php
/**
 * PolicyService
 * Business logic for Policy Management, Immutability, Versioning, and Acceptance
 */

require_once __DIR__ . '/../Models/UserAgreement.php';
require_once __DIR__ . '/../Models/UserAgreementAcceptance.php';
require_once __DIR__ . '/../Models/ActivityLog.php';

class PolicyService {
    private UserAgreement $agreementModel;
    private UserAgreementAcceptance $acceptanceModel;
    private ActivityLog $activityLog;

    public function __construct() {
        $this->agreementModel = new UserAgreement();
        $this->acceptanceModel = new UserAgreementAcceptance();
        $this->activityLog = new ActivityLog();
    }

    public function getAllActivePolicies(): array {
        return $this->agreementModel->getAllActivePolicies();
    }

    public function getPolicy(string $type, ?string $version = null): ?array {
        $policy = $this->agreementModel->getPolicyByTypeAndVersion($type, $version);
        if ($policy) {
            $policy['versions'] = $this->agreementModel->getVersionsByType($type);
        }
        return $policy;
    }

    public function getAdminPolicies(array $filters = [], int $page = 1, int $perPage = 20): array {
        $page = max(1, $page);
        $offset = ($page - 1) * $perPage;

        $total = $this->agreementModel->countAdminPolicies($filters);
        $policies = $this->agreementModel->getAdminPolicies($filters, $perPage, $offset);

        return [
            'policies' => $policies,
            'total' => $total,
            'page' => $page,
            'pages' => ceil($total / $perPage),
            'filters' => $filters
        ];
    }

    public function createDraft(array $data, int $adminId): array {
        $type = $data['type'] ?? 'customer';
        $title = trim($data['title'] ?? '');
        $version = trim($data['version'] ?? '');
        $content = trim($data['content'] ?? '');

        if (!array_key_exists($type, UserAgreement::$types)) {
            return ['success' => false, 'message' => 'ประเภทนโยบายไม่ถูกต้อง'];
        }

        if (empty($title)) {
            return ['success' => false, 'message' => 'กรุณากรอกชื่อนโยบาย'];
        }

        if (empty($version)) {
            return ['success' => false, 'message' => 'กรุณาระบุเวอร์ชัน (เช่น 1.1.0)'];
        }

        if (empty($content)) {
            return ['success' => false, 'message' => 'กรุณากรอกเนื้อหานโยบาย'];
        }

        // Check if version already exists for this type
        $existing = $this->agreementModel->fetchOne("SELECT id FROM `user_agreements` WHERE type = :type AND version = :ver", [
            ':type' => $type,
            ':ver' => $version
        ]);

        if ($existing) {
            return ['success' => false, 'message' => "เวอร์ชัน {$version} สำหรับนโยบายนี้มีอยู่ในระบบแล้ว กรุณากำหนดเลขเวอร์ชันใหม่"];
        }

        $id = $this->agreementModel->createDraft([
            'type' => $type,
            'title' => $title,
            'version' => $version,
            'content' => $content
        ], $adminId);

        $this->activityLog->record($adminId, 'policy_draft_created', 'user_agreement', $id, "Created draft policy {$type} v{$version}");

        return [
            'success' => true,
            'message' => "สร้างแบบร่างเวอร์ชัน {$version} เรียบร้อยแล้ว",
            'policy_id' => $id
        ];
    }

    public function updateDraft(int $id, array $data, int $adminId): array {
        $policy = $this->agreementModel->findById($id);
        if (!$policy) {
            return ['success' => false, 'message' => 'ไม่พบนโยบาย'];
        }

        if ($policy['status'] !== 'draft') {
            return ['success' => false, 'message' => 'ไม่อนุญาตให้แก้ไขนโยบายเวอร์ชันที่เผยแพร่แล้ว (Published versions are immutable) หากต้องการเปลี่ยนแปลง กรุณาสร้างเวอร์ชันใหม่'];
        }

        $title = trim($data['title'] ?? $policy['title']);
        $content = trim($data['content'] ?? $policy['content']);

        if (empty($title)) {
            return ['success' => false, 'message' => 'กรุณากรอกชื่อนโยบาย'];
        }

        if (empty($content)) {
            return ['success' => false, 'message' => 'กรุณากรอกเนื้อหานโยบาย'];
        }

        $this->agreementModel->updateDraft($id, [
            'title' => $title,
            'content' => $content
        ], $adminId);

        return [
            'success' => true,
            'message' => 'บันทึกการแก้ไขแบบร่างเรียบร้อยแล้ว'
        ];
    }

    public function publish(int $id, int $adminId): array {
        $policy = $this->agreementModel->findById($id);
        if (!$policy) {
            return ['success' => false, 'message' => 'ไม่พบนโยบาย'];
        }

        $success = $this->agreementModel->publish($id, $adminId);
        if (!$success) {
            return ['success' => false, 'message' => 'ไม่สามารถเผยแพร่นโยบายได้'];
        }

        $this->activityLog->record($adminId, 'policy_published', 'user_agreement', $id, "Published policy {$policy['type']} v{$policy['version']}");

        return [
            'success' => true,
            'message' => "เผยแพร่นโยบายเวอร์ชัน {$policy['version']} เรียบร้อยแล้ว (เวอร์ชันเดิมถูกย้ายไปที่เก็บประวัติ)"
        ];
    }

    public function archive(int $id, int $adminId): array {
        $this->agreementModel->archive($id, $adminId);
        return [
            'success' => true,
            'message' => 'ย้ายนโยบายเข้าสู่สถานะเก็บถาวร (Archive) เรียบร้อยแล้ว'
        ];
    }

    public function getHistory(int $id): array {
        return $this->agreementModel->getHistory($id);
    }

    public function getAcceptances(int $id, int $page = 1, int $perPage = 50): array {
        $page = max(1, $page);
        $offset = ($page - 1) * $perPage;

        $total = $this->acceptanceModel->countAcceptances($id);
        $acceptances = $this->acceptanceModel->getAcceptancesByAgreement($id, $perPage, $offset);

        return [
            'acceptances' => $acceptances,
            'total' => $total,
            'page' => $page,
            'pages' => ceil($total / $perPage)
        ];
    }

    public function recordUserAcceptance(int $userId, string $type): bool {
        $policy = $this->agreementModel->getLatestActive($type);
        if ($policy) {
            $this->agreementModel->recordAcceptance($userId, (int)$policy['id'], $type, $policy['version']);
            return true;
        }
        return false;
    }
}
