<?php
namespace Thirty\controllers;

class PhotoController {
    
    public static function form() { 
        require_auth(); 
        view('photos/upload'); 
    }
    
    public static function upload() {
        require_auth(); 
        verify_csrf(); 
        global $DB, $CONFIG;
        
        // Validar archivo
        if (empty($_FILES['photo']) || (($_FILES['photo']['error'] ?? UPLOAD_ERR_OK) !== UPLOAD_ERR_OK)) { 
            set_flash('Selecciona una imagen válida.'); 
            redirect(base_url('/photos/upload')); 
        }
        
        $tmp = $_FILES['photo']['tmp_name']; 
        $size = (int)($_FILES['photo']['size'] ?? 0); 
        
        if ($size <= 0) { 
            set_flash('Archivo vacío.'); 
            redirect(base_url('/photos/upload')); 
        }
        
        if ($size > ($CONFIG['UPLOAD_MAX_MB'] * 1024 * 1024)) { 
            set_flash('Archivo demasiado grande.'); 
            redirect(base_url('/photos/upload')); 
        }
        
        // Validar tipo MIME
        $mime = 'application/octet-stream'; 
        if (class_exists('finfo')) { 
            $fi = new \finfo(FILEINFO_MIME_TYPE); 
            $mime = $fi->file($tmp) ?: $mime; 
        }
        
        $allowed = [
            'image/jpeg' => 'jpg',
            'image/png' => 'png', 
            'image/webp' => 'webp'
        ]; 
        
        if (!isset($allowed[$mime])) { 
            set_flash('Formato no soportado (JPG/PNG/WEBP).'); 
            redirect(base_url('/photos/upload')); 
        }
        
        // Guardar archivo
        $ext = $allowed[$mime]; 
        $filename = bin2hex(random_bytes(12)) . '.' . $ext; 
        $rel = 'uploads/photos/' . $filename; 
        $dest = PUBLIC_PATH . '/' . $rel; 
        
        if (!is_dir(dirname($dest))) {
            mkdir(dirname($dest), 0775, true);
        }
        
        if (!move_uploaded_file($tmp, $dest)) { 
            set_flash('No se pudo guardar el archivo.'); 
            redirect(base_url('/photos/upload')); 
        }
        
        // Procesar datos del formulario
        $text = trim($_POST['text'] ?? ''); 
        $vis = (($_POST['visibility'] ?? 'friends') === 'private' ? 'private' : 'friends'); 
        $uid = user()['id'];
        
        // Guardar en base de datos
        $DB->beginTransaction(); 
        try { 
            $DB->prepare('INSERT INTO posts (user_id, text, visibility) VALUES (?, ?, ?)')
               ->execute([$uid, $text === '' ? null : $text, $vis]); 
            $postId = (int)$DB->lastInsertId(); 
            
            $DB->prepare('INSERT INTO photos (post_id, owner_id, storage_rel_path, width, height, nsfw_flag) VALUES (?, ?, ?, ?, ?, 0)')
               ->execute([$postId, $uid, $rel, 0, 0]); 
            
            $DB->commit(); 
        } catch (\Throwable $e) { 
            $DB->rollBack(); 
            // Eliminar archivo subido en caso de error
            if (file_exists($dest)) {
                unlink($dest);
            }
            set_flash('Error al guardar la foto.'); 
            redirect(base_url('/photos/upload')); 
        }
        
        set_flash('¡Foto subida!'); 
        redirect(base_url('/profile'));
    }
    
    public static function mine() {
        require_auth(); 
        global $DB; 
        $uid = user()['id'];
        
        $st = $DB->prepare('
            SELECT 
                ph.id as photo_id,
                po.id as post_id, 
                ph.storage_rel_path, 
                po.created_at, 
                po.text, 
                po.visibility 
            FROM photos ph 
            JOIN posts po ON po.id = ph.post_id 
            WHERE ph.owner_id = ? 
            ORDER BY po.created_at DESC
        '); 
        $st->execute([$uid]); 
        $rows = $st->fetchAll();
        
        view('photos/mine', ['photos' => $rows]);
    }
    
    public static function update() {
        require_auth();
        verify_csrf();
        global $DB;
        
        $user = user();
        $photo_id = (int)($_POST['photo_id'] ?? 0);
        $text = trim($_POST['text'] ?? '');
        $visibility = $_POST['visibility'] ?? 'friends';
        
        if ($photo_id <= 0) {
            set_flash('ID de foto inválido.');
            redirect(base_url('/profile'));
        }
        
        // Verificar que la foto pertenece al usuario
        $check_stmt = $DB->prepare('
            SELECT p.id, po.user_id, po.id as post_id
            FROM photos p 
            JOIN posts po ON po.id = p.post_id 
            WHERE p.id = ? AND po.user_id = ?
        ');
        $check_stmt->execute([$photo_id, $user['id']]);
        $photo = $check_stmt->fetch();
        
        if (!$photo) {
            set_flash('Foto no encontrada o no tienes permisos.');
            redirect(base_url('/profile'));
        }
        
        // Actualizar el post asociado
        $update_stmt = $DB->prepare('
            UPDATE posts 
            SET text = ?, visibility = ? 
            WHERE id = ?
        ');
        $success = $update_stmt->execute([
            $text === '' ? null : $text, 
            $visibility, 
            $photo['post_id']
        ]);
        
        if ($success) {
            set_flash('Foto actualizada correctamente.');
        } else {
            set_flash('Error al actualizar la foto.');
        }
        
        redirect(base_url('/profile'));
    }
    
    public static function delete() {
        require_auth();
        verify_csrf();
        global $DB;
        
        $user = user();
        $photo_id = (int)($_POST['photo_id'] ?? 0);
        
        if ($photo_id <= 0) {
            set_flash('ID de foto inválido.');
            redirect(base_url('/profile'));
        }
        
        // Verificar que la foto pertenece al usuario y obtener información
        $check_stmt = $DB->prepare('
            SELECT p.id, p.storage_rel_path, po.user_id, p.post_id
            FROM photos p 
            JOIN posts po ON po.id = p.post_id 
            WHERE p.id = ? AND po.user_id = ?
        ');
        $check_stmt->execute([$photo_id, $user['id']]);
        $photo = $check_stmt->fetch();
        
        if (!$photo) {
            set_flash('Foto no encontrada o no tienes permisos.');
            redirect(base_url('/profile'));
        }
        
        $DB->beginTransaction();
        try {
            // Eliminar likes y comentarios primero
            $DB->prepare('DELETE FROM post_likes WHERE post_id = ?')->execute([$photo['post_id']]);
            $DB->prepare('DELETE FROM post_comments WHERE post_id = ?')->execute([$photo['post_id']]);
            
            // Eliminar la foto
            $DB->prepare('DELETE FROM photos WHERE id = ?')->execute([$photo_id]);
            
            // Eliminar el post
            $DB->prepare('DELETE FROM posts WHERE id = ?')->execute([$photo['post_id']]);
            
            // Eliminar archivo físico
            $file_path = PUBLIC_PATH . '/' . $photo['storage_rel_path'];
            if (file_exists($file_path)) {
                unlink($file_path);
            }
            
            $DB->commit();
            set_flash('Foto eliminada correctamente.');
            
        } catch (\Throwable $e) {
            $DB->rollBack();
            set_flash('Error al eliminar la foto.');
        }
        
        redirect(base_url('/profile'));
    }
    
    // MÉTODO PARA MOSTRAR FOTO INDIVIDUAL
    public static function show($id) {
        require_auth();
        global $DB;
        
        $user = user();
        $photo_id = (int)$id;
        
        // Obtener información completa de la foto
        $photo_stmt = $DB->prepare('
            SELECT 
                p.id,
                p.storage_rel_path,
                p.owner_id,
                po.id as post_id,
                po.text,
                po.visibility,
                po.created_at,
                u.nick as user_nick,
                u.first_name,
                u.last_name,
                prof.avatar_url,
                (SELECT COUNT(*) FROM post_likes WHERE post_id = po.id) as like_count,
                (SELECT COUNT(*) FROM post_comments WHERE post_id = po.id) as comment_count,
                EXISTS(SELECT 1 FROM post_likes WHERE post_id = po.id AND user_id = ?) as user_liked
            FROM photos p 
            JOIN posts po ON po.id = p.post_id
            JOIN users u ON u.id = po.user_id
            LEFT JOIN profiles prof ON prof.user_id = u.id
            WHERE p.id = ?
        ');
        $photo_stmt->execute([$user['id'], $photo_id]);
        $photo = $photo_stmt->fetch();
        
        if (!$photo) {
            http_response_code(404);
            echo 'Foto no encontrada';
            return;
        }
        
        // Verificar visibilidad
        if ($photo['visibility'] === 'private' && $photo['owner_id'] !== $user['id']) {
            http_response_code(403);
            echo 'No tienes permiso para ver esta foto';
            return;
        }
        
        // Obtener comentarios - INCLUYE parent_id
        $comments_stmt = $DB->prepare('
            SELECT 
                pc.id,
                pc.body,
                pc.created_at,
                pc.parent_id,
                pc.user_id,
                u.nick,
                u.first_name,
                u.last_name,
                prof.avatar_url
            FROM post_comments pc
            JOIN users u ON u.id = pc.user_id
            LEFT JOIN profiles prof ON prof.user_id = u.id
            WHERE pc.post_id = ?
            ORDER BY pc.created_at ASC
        ');
        $comments_stmt->execute([$photo['post_id']]);
        $comments = $comments_stmt->fetchAll();
        
        // Obtener personas que dieron like
        $likes_stmt = $DB->prepare('
            SELECT 
                u.nick,
                u.first_name,
                u.last_name,
                prof.avatar_url
            FROM post_likes pl
            JOIN users u ON u.id = pl.user_id
            LEFT JOIN profiles prof ON prof.user_id = u.id
            WHERE pl.post_id = ?
            ORDER BY pl.created_at DESC
        ');
        $likes_stmt->execute([$photo['post_id']]);
        $likes = $likes_stmt->fetchAll();
        
        // Obtener información de amigos para verificar si puede interactuar
        $is_friend = false;
        $is_owner = ($photo['owner_id'] === $user['id']);
        
        if (!$is_owner) {
            $friend_stmt = $DB->prepare('
                SELECT 1 FROM friendships 
                WHERE (user_id = ? AND friend_id = ?) OR (user_id = ? AND friend_id = ?)
            ');
            $friend_stmt->execute([$user['id'], $photo['owner_id'], $photo['owner_id'], $user['id']]);
            $is_friend = (bool)$friend_stmt->fetchColumn();
        }
        
        view('photos/show', [
            'photo' => $photo,
            'comments' => $comments,
            'likes' => $likes,
            'is_owner' => $is_owner,
            'is_friend' => $is_friend,
            'can_interact' => $is_owner || $is_friend || $photo['visibility'] === 'friends'
        ]);
    }
    
    // MÉTODO PARA DAR LIKE
    public static function like($id) {
        require_auth();
        verify_csrf();
        global $DB;
        
        $user = user();
        $photo_id = (int)$id;
        
        // Obtener post_id de la foto
        $post_stmt = $DB->prepare('
            SELECT po.id, po.user_id, po.visibility 
            FROM photos p 
            JOIN posts po ON po.id = p.post_id 
            WHERE p.id = ?
        ');
        $post_stmt->execute([$photo_id]);
        $post = $post_stmt->fetch();
        
        if (!$post) {
            http_response_code(404);
            echo 'Foto no encontrada';
            return;
        }
        
        // Verificar permisos
        if ($post['visibility'] === 'private' && $post['user_id'] !== $user['id']) {
            http_response_code(403);
            echo 'No tienes permiso para interactuar con esta foto';
            return;
        }
        
        if ($post['visibility'] === 'friends' && $post['user_id'] !== $user['id']) {
            $friend_stmt = $DB->prepare('
                SELECT 1 FROM friendships 
                WHERE (user_id = ? AND friend_id = ?) OR (user_id = ? AND friend_id = ?)
            ');
            $friend_stmt->execute([$user['id'], $post['user_id'], $post['user_id'], $user['id']]);
            if (!$friend_stmt->fetchColumn()) {
                http_response_code(403);
                echo 'No tienes permiso para interactuar con esta foto';
                return;
            }
        }
        
        // Verificar si ya dio like
        $like_stmt = $DB->prepare('SELECT 1 FROM post_likes WHERE post_id = ? AND user_id = ?');
        $like_stmt->execute([$post['id'], $user['id']]);
        
        if ($like_stmt->fetchColumn()) {
            // Quitar like
            $delete_stmt = $DB->prepare('DELETE FROM post_likes WHERE post_id = ? AND user_id = ?');
            $delete_stmt->execute([$post['id'], $user['id']]);
        } else {
            // Dar like
            $insert_stmt = $DB->prepare('INSERT INTO post_likes (post_id, user_id) VALUES (?, ?)');
            $insert_stmt->execute([$post['id'], $user['id']]);
        }
        
        redirect(base_url('/photo?id=' . $photo_id));
    }
    
    // MÉTODO PARA COMENTAR - MANEJA RESPUESTAS
    public static function comment($id) {
        require_auth();
        verify_csrf();
        global $DB;
        
        $user = user();
        $photo_id = (int)$id;
        $body = trim($_POST['body'] ?? '');
        $parentId = isset($_POST['parent_id']) ? (int)$_POST['parent_id'] : null;
        
        if (empty($body)) {
            set_flash('El comentario no puede estar vacío.');
            redirect(base_url('/photo?id=' . $photo_id));
        }
        
        if (strlen($body) > 600) {
            set_flash('El comentario es demasiado largo.');
            redirect(base_url('/photo?id=' . $photo_id));
        }
        
        // Obtener post_id de la foto
        $post_stmt = $DB->prepare('
            SELECT po.id, po.user_id, po.visibility 
            FROM photos p 
            JOIN posts po ON po.id = p.post_id 
            WHERE p.id = ?
        ');
        $post_stmt->execute([$photo_id]);
        $post = $post_stmt->fetch();
        
        if (!$post) {
            http_response_code(404);
            echo 'Foto no encontrada';
            return;
        }
        
        // Verificar permisos
        if ($post['visibility'] === 'private' && $post['user_id'] !== $user['id']) {
            http_response_code(403);
            echo 'No tienes permiso para interactuar con esta foto';
            return;
        }
        
        if ($post['visibility'] === 'friends' && $post['user_id'] !== $user['id']) {
            $friend_stmt = $DB->prepare('
                SELECT 1 FROM friendships 
                WHERE (user_id = ? AND friend_id = ?) OR (user_id = ? AND friend_id = ?)
            ');
            $friend_stmt->execute([$user['id'], $post['user_id'], $post['user_id'], $user['id']]);
            if (!$friend_stmt->fetchColumn()) {
                http_response_code(403);
                echo 'No tienes permiso para interactuar con esta foto';
                return;
            }
        }
        
        // Si es una respuesta, verificar que el comentario padre existe
        if ($parentId) {
            $parent_stmt = $DB->prepare('SELECT id FROM post_comments WHERE id = ? AND post_id = ?');
            $parent_stmt->execute([$parentId, $post['id']]);
            if (!$parent_stmt->fetch()) {
                set_flash('El comentario padre no existe.');
                redirect(base_url('/photo?id=' . $photo_id));
            }
        }
        
        // Insertar comentario - INCLUYE parent_id
        $comment_stmt = $DB->prepare('INSERT INTO post_comments (post_id, user_id, body, parent_id) VALUES (?, ?, ?, ?)');
        $comment_stmt->execute([$post['id'], $user['id'], $body, $parentId]);
        
        $commentId = $DB->lastInsertId();
        
        // Crear notificación para el dueño de la foto (si no es el mismo y es comentario principal)
        if ($post['user_id'] !== $user['id'] && $parentId === null) {
            $notification_stmt = $DB->prepare('
                INSERT INTO notifications (user_id, type, payload) 
                VALUES (?, "comment", ?)
            ');
            $payload = json_encode([
                'photo_id' => $photo_id,
                'from_user_id' => $user['id'],
                'body' => $body,
                'comment_id' => $commentId
            ]);
            $notification_stmt->execute([$post['user_id'], $payload]);
        }
        
        // Si es una respuesta, notificar al autor del comentario padre
        if ($parentId) {
            $parentAuthorStmt = $DB->prepare('SELECT user_id FROM post_comments WHERE id = ?');
            $parentAuthorStmt->execute([$parentId]);
            $parentAuthor = $parentAuthorStmt->fetchColumn();
            
            if ($parentAuthor && $parentAuthor != $user['id'] && $parentAuthor != $post['user_id']) {
                $notification_stmt = $DB->prepare('
                    INSERT INTO notifications (user_id, type, payload) 
                    VALUES (?, "comment_reply", ?)
                ');
                $payload = json_encode([
                    'photo_id' => $photo_id,
                    'from_user_id' => $user['id'],
                    'body' => $body,
                    'comment_id' => $commentId,
                    'parent_comment_id' => $parentId
                ]);
                $notification_stmt->execute([$parentAuthor, $payload]);
            }
        }
        
        set_flash('Comentario añadido.');
        redirect(base_url('/photo?id=' . $photo_id));
    }
    
    // MÉTODO PARA ELIMINAR COMENTARIOS
    public static function delete_comment() {
        require_auth();
        verify_csrf();
        global $DB;
        
        $user = user();
        $comment_id = (int)($_POST['comment_id'] ?? 0);
        
        if ($comment_id <= 0) {
            set_flash('ID de comentario inválido.');
            redirect($_SERVER['HTTP_REFERER'] ?? base_url('/feed'));
        }
        
        // Verificar permisos
        $comment_stmt = $DB->prepare('
            SELECT pc.id, pc.user_id, pc.post_id, p.user_id as post_owner_id 
            FROM post_comments pc 
            JOIN posts p ON p.id = pc.post_id 
            WHERE pc.id = ?
        ');
        $comment_stmt->execute([$comment_id]);
        $comment = $comment_stmt->fetch();
        
        if (!$comment) {
            set_flash('Comentario no encontrado.');
            redirect($_SERVER['HTTP_REFERER'] ?? base_url('/feed'));
        }
        
        $canDelete = ($comment['user_id'] == $user['id']) || ($comment['post_owner_id'] == $user['id']);
        
        if (!$canDelete) {
            set_flash('No tienes permisos para eliminar este comentario.');
            redirect($_SERVER['HTTP_REFERER'] ?? base_url('/feed'));
        }
        
        // Eliminar comentario
        $delete_stmt = $DB->prepare('DELETE FROM post_comments WHERE id = ?');
        $delete_stmt->execute([$comment_id]);
        
        set_flash('Comentario eliminado.');
        redirect($_SERVER['HTTP_REFERER'] ?? base_url('/feed'));
    }
}