<?php
/**
 * ZLO Platform - Case Study Controller
 */

declare(strict_types=1);

require_once __DIR__ . '/../core/Router.php';

class CaseStudyController
{
    private Database $db;
    
    public function __construct()
    {
        $this->db = new Database();
    }
    
    /**
     * Get all case studies (public)
     */
    public function index(array $params): array
    {
        $query = Router::getQuery();
        $page = (int) ($query['page'] ?? 1);
        $limit = (int) ($query['limit'] ?? 10);
        $industry = $query['industry'] ?? null;
        $solution = $query['solution'] ?? null;
        
        $sql = "SELECT cs.*, i.name as industry_name, i.slug as industry_slug, s.title as solution_name 
                FROM case_studies cs 
                LEFT JOIN industries i ON cs.industry_id = i.id 
                LEFT JOIN solutions s ON cs.solution_id = s.id 
                WHERE cs.published = 1";
        
        $params = [];
        
        if ($industry) {
            $sql .= " AND i.slug = ?";
            $params[] = $industry;
        }
        
        if ($solution) {
            $sql .= " AND s.slug = ?";
            $params[] = $solution;
        }
        
        $sql .= " ORDER BY cs.published_at DESC";
        
        // Count total
        $countSql = str_replace("SELECT cs.*, i.name as industry_name, i.slug as industry_slug, s.title as solution_name", "SELECT COUNT(*) as total", $sql);
        $countSql = preg_replace('/ORDER BY.*$/', '', $countSql);
        $totalResult = $this->db->fetchOne($countSql, $params);
        $total = (int) ($totalResult['total'] ?? 0);
        
        // Add pagination
        $offset = ($page - 1) * $limit;
        $sql .= " LIMIT ? OFFSET ?";
        $params[] = $limit;
        $params[] = $offset;
        
        $caseStudies = $this->db->fetchAll($sql, $params);
        
        // Parse JSON fields
        foreach ($caseStudies as &$cs) {
            $cs['results'] = json_decode($cs['results'] ?? '[]', true);
            $cs['metrics'] = json_decode($cs['metrics'] ?? '[]', true);
        }
        
        return [
            'case_studies' => $caseStudies,
            'pagination' => [
                'current_page' => $page,
                'per_page' => $limit,
                'total' => $total,
                'last_page' => (int) ceil($total / $limit),
                'from' => $offset + 1,
                'to' => min($offset + $limit, $total)
            ]
        ];
    }
    
    /**
     * Get single case study (public)
     */
    public function show(array $params): ?array
    {
        $slug = $params['slug'] ?? '';
        
        if (!$slug) {
            http_response_code(400);
            return ['error' => 'Slug is required'];
        }
        
        $sql = "SELECT cs.*, i.name as industry_name, i.slug as industry_slug, s.title as solution_name, s.slug as solution_slug 
                FROM case_studies cs 
                LEFT JOIN industries i ON cs.industry_id = i.id 
                LEFT JOIN solutions s ON cs.solution_id = s.id 
                WHERE cs.slug = ? AND cs.published = 1";
        
        $caseStudy = $this->db->fetchOne($sql, [$slug]);
        
        if (!$caseStudy) {
            http_response_code(404);
            return ['error' => 'Case study not found'];
        }
        
        // Increment views
        $this->db->query("UPDATE case_studies SET views = views + 1 WHERE id = ?", [$caseStudy['id']]);
        
        // Parse JSON fields
        $caseStudy['results'] = json_decode($caseStudy['results'] ?? '[]', true);
        $caseStudy['metrics'] = json_decode($caseStudy['metrics'] ?? '[]', true);
        
        // Get related case studies
        $sql = "SELECT cs.id, cs.title, cs.slug, cs.image, cs.client_name 
                FROM case_studies cs 
                WHERE cs.id != ? AND cs.published = 1 
                AND (cs.industry_id = ? OR cs.solution_id = ?) 
                ORDER BY cs.published_at DESC LIMIT 3";
        
        $caseStudy['related'] = $this->db->fetchAll($sql, [
            $caseStudy['id'],
            $caseStudy['industry_id'],
            $caseStudy['solution_id']
        ]);
        
        return $caseStudy;
    }
    
    /**
     * Get featured case studies (public)
     */
    public function featured(array $params): array
    {
        $query = Router::getQuery();
        $limit = (int) ($query['limit'] ?? 3);
        
        $sql = "SELECT cs.*, i.name as industry_name, s.title as solution_name 
                FROM case_studies cs 
                LEFT JOIN industries i ON cs.industry_id = i.id 
                LEFT JOIN solutions s ON cs.solution_id = s.id 
                WHERE cs.published = 1 
                ORDER BY cs.views DESC, cs.published_at DESC 
                LIMIT ?";
        
        $caseStudies = $this->db->fetchAll($sql, [$limit]);
        
        foreach ($caseStudies as &$cs) {
            $cs['results'] = json_decode($cs['results'] ?? '[]', true);
            $cs['metrics'] = json_decode($cs['metrics'] ?? '[]', true);
        }
        
        return $caseStudies;
    }
    
    /**
     * Get industries (public)
     */
    public function industries(array $params): array
    {
        $sql = "SELECT i.*, COUNT(cs.id) as case_study_count 
                FROM industries i 
                LEFT JOIN case_studies cs ON i.id = cs.industry_id AND cs.published = 1 
                WHERE i.status = 'active' 
                GROUP BY i.id 
                ORDER BY i.name";
        
        return $this->db->fetchAll($sql);
    }
    
    /**
     * Create case study (admin)
     */
    public function create(array $params): array
    {
        AuthController::requirePermission('solutions.create');
        
        $body = Router::getBody();
        $security = new Security();
        
        // Validate required fields
        $required = ['title', 'client_name', 'problem', 'solution'];
        foreach ($required as $field) {
            if (empty($body[$field])) {
                http_response_code(400);
                return ['error' => "Field {$field} is required"];
            }
        }
        
        // Generate slug
        $slug = $this->generateSlug($body['title']);
        
        $data = [
            'title' => $security->sanitize($body['title']),
            'slug' => $slug,
            'client_name' => $security->sanitize($body['client_name']),
            'client_logo' => !empty($body['client_logo']) ? $security->sanitize($body['client_logo']) : null,
            'industry_id' => !empty($body['industry_id']) ? (int) $body['industry_id'] : null,
            'solution_id' => !empty($body['solution_id']) ? (int) $body['solution_id'] : null,
            'problem' => $security->sanitize($body['problem']),
            'solution' => $security->sanitize($body['solution']),
            'results' => !empty($body['results']) ? json_encode($body['results']) : null,
            'metrics' => !empty($body['metrics']) ? json_encode($body['metrics']) : null,
            'image' => !empty($body['image']) ? $security->sanitize($body['image']) : null,
            'testimonial' => !empty($body['testimonial']) ? $security->sanitize($body['testimonial']) : null,
            'testimonial_author' => !empty($body['testimonial_author']) ? $security->sanitize($body['testimonial_author']) : null,
            'testimonial_role' => !empty($body['testimonial_role']) ? $security->sanitize($body['testimonial_role']) : null,
            'published' => $body['published'] ?? false,
            'created_at' => date('Y-m-d H:i:s')
        ];
        
        if ($data['published']) {
            $data['published_at'] = date('Y-m-d H:i:s');
        }
        
        try {
            $id = $this->db->insert('case_studies', $data);
            
            http_response_code(201);
            return $this->getById($id);
        } catch (Exception $e) {
            http_response_code(500);
            return ['error' => 'Failed to create case study'];
        }
    }
    
    /**
     * Update case study (admin)
     */
    public function update(array $params): ?array
    {
        AuthController::requirePermission('solutions.edit');
        
        $id = (int) ($params['id'] ?? 0);
        
        if (!$id) {
            http_response_code(400);
            return ['error' => 'Case study ID is required'];
        }
        
        $body = Router::getBody();
        $security = new Security();
        
        $data = [];
        
        if (!empty($body['title'])) {
            $data['title'] = $security->sanitize($body['title']);
            $data['slug'] = $this->generateSlug($body['title'], $id);
        }
        if (!empty($body['client_name'])) {
            $data['client_name'] = $security->sanitize($body['client_name']);
        }
        if (isset($body['problem'])) {
            $data['problem'] = $security->sanitize($body['problem']);
        }
        if (isset($body['solution'])) {
            $data['solution'] = $security->sanitize($body['solution']);
        }
        if (!empty($body['results'])) {
            $data['results'] = json_encode($body['results']);
        }
        if (!empty($body['metrics'])) {
            $data['metrics'] = json_encode($body['metrics']);
        }
        if (isset($body['published'])) {
            $data['published'] = $body['published'] ? 1 : 0;
            if ($body['published']) {
                $existing = $this->getById($id);
                if ($existing && !$existing['published_at']) {
                    $data['published_at'] = date('Y-m-d H:i:s');
                }
            }
        }
        
        try {
            $this->db->update('case_studies', $data, "id = ?", [$id]);
            return $this->getById($id);
        } catch (Exception $e) {
            http_response_code(500);
            return ['error' => 'Failed to update case study'];
        }
    }
    
    /**
     * Delete case study (admin)
     */
    public function delete(array $params): array
    {
        AuthController::requirePermission('solutions.delete');
        
        $id = (int) ($params['id'] ?? 0);
        
        if (!$id) {
            http_response_code(400);
            return ['error' => 'Case study ID is required'];
        }
        
        try {
            $this->db->delete('case_studies', "id = ?", [$id]);
            return ['message' => 'Case study deleted successfully'];
        } catch (Exception $e) {
            http_response_code(500);
            return ['error' => 'Failed to delete case study'];
        }
    }
    
    /**
     * Get case study by ID
     */
    private function getById(int $id): ?array
    {
        $sql = "SELECT cs.*, i.name as industry_name, s.title as solution_name 
                FROM case_studies cs 
                LEFT JOIN industries i ON cs.industry_id = i.id 
                LEFT JOIN solutions s ON cs.solution_id = s.id 
                WHERE cs.id = ?";
        
        $caseStudy = $this->db->fetchOne($sql, [$id]);
        
        if ($caseStudy) {
            $caseStudy['results'] = json_decode($caseStudy['results'] ?? '[]', true);
            $caseStudy['metrics'] = json_decode($caseStudy['metrics'] ?? '[]', true);
        }
        
        return $caseStudy;
    }
    
    /**
     * Generate unique slug
     */
    private function generateSlug(string $title, ?int $excludeId = null): string
    {
        $slug = $this->slugify($title);
        $originalSlug = $slug;
        $counter = 1;
        
        while (true) {
            $sql = "SELECT id FROM case_studies WHERE slug = ?";
            $params = [$slug];
            
            if ($excludeId) {
                $sql .= " AND id != ?";
                $params[] = $excludeId;
            }
            
            $existing = $this->db->fetchOne($sql, $params);
            
            if (!$existing) {
                break;
            }
            
            $slug = $originalSlug . '-' . $counter;
            $counter++;
        }
        
        return $slug;
    }
    
    /**
     * Convert title to slug
     */
    private function slugify(string $text): string
    {
        $text = preg_replace('~[^\pL\d]+~u', '-', $text);
        $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
        $text = preg_replace('~[^-\w]+~', '', $text);
        $text = trim($text, '-');
        $text = preg_replace('~-+~', '-', $text);
        $text = strtolower($text);
        
        return $text ?: 'n-a';
    }
}
