<?php
namespace App\Models;

use PDO;
use DateTime;

/**
 * Modelo de asignaciones/rotaciones
 */
class Assignment extends BaseModel
{
    protected $table = 'assignments';
    
    /**
     * Crea una nueva asignación
     */
    public function create($data)
    {
        $sql = "INSERT INTO assignments (user_id, week_number, year, start_date, end_date, order_position) 
                VALUES (:user_id, :week_number, :year, :start_date, :end_date, :order_position)";
        
        $stmt = $this->db->prepare($sql);
        
        return $stmt->execute([
            'user_id' => $data['user_id'],
            'week_number' => $data['week_number'],
            'year' => $data['year'],
            'start_date' => $data['start_date'],
            'end_date' => $data['end_date'],
            'order_position' => $data['order_position'] ?? 0
        ]);
    }
    
    /**
     * Actualiza una asignación
     */
    public function update($id, $data)
    {
        $fields = [];
        $params = ['id' => $id];
        
        if (isset($data['user_id'])) {
            $fields[] = "user_id = :user_id";
            $params['user_id'] = $data['user_id'];
        }
        
        if (isset($data['order_position'])) {
            $fields[] = "order_position = :order_position";
            $params['order_position'] = $data['order_position'];
        }
        
        if (empty($fields)) {
            return false;
        }
        
        $sql = "UPDATE assignments SET " . implode(', ', $fields) . " WHERE id = :id";
        $stmt = $this->db->prepare($sql);
        
        return $stmt->execute($params);
    }
    
    /**
     * Obtiene la asignación de una semana específica
     */
    public function getByWeek($year, $weekNumber)
    {
        $sql = "SELECT a.*, u.full_name, u.username 
                FROM assignments a 
                INNER JOIN users u ON a.user_id = u.id 
                WHERE a.year = ? AND a.week_number = ?";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$year, $weekNumber]);
        return $stmt->fetch();
    }
    
    /**
     * Obtiene las próximas N asignaciones
     */
    public function getUpcoming($limit = 8)
    {
        $today = date('Y-m-d');
        
        $sql = "SELECT a.*, u.full_name, u.username 
                FROM assignments a 
                INNER JOIN users u ON a.user_id = u.id 
                WHERE a.start_date >= :today 
                ORDER BY a.start_date ASC 
                LIMIT :limit";
        
        $stmt = $this->db->prepare($sql);
        $stmt->bindValue(':today', $today);
        $stmt->bindValue(':limit', $limit, PDO::PARAM_INT);
        $stmt->execute();
        
        return $stmt->fetchAll();
    }
    
    /**
     * Obtiene todas las asignaciones futuras
     */
    public function getFuture()
    {
        $today = date('Y-m-d');
        
        $sql = "SELECT a.*, u.full_name, u.username 
                FROM assignments a 
                INNER JOIN users u ON a.user_id = u.id 
                WHERE a.start_date >= :today 
                ORDER BY a.start_date ASC";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute(['today' => $today]);
        
        return $stmt->fetchAll();
    }
    
    /**
     * Obtiene la última asignación
     */
    public function getLatest()
    {
        $sql = "SELECT a.*, u.full_name, u.username 
                FROM assignments a 
                INNER JOIN users u ON a.user_id = u.id 
                ORDER BY a.year DESC, a.week_number DESC 
                LIMIT 1";
        
        $stmt = $this->db->query($sql);
        return $stmt->fetch();
    }
    
    /**
     * Obtiene asignaciones de un usuario
     */
    public function getByUser($userId)
    {
        $sql = "SELECT a.*, u.full_name, u.username 
                FROM assignments a 
                INNER JOIN users u ON a.user_id = u.id 
                WHERE a.user_id = ? 
                ORDER BY a.start_date DESC";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute([$userId]);
        
        return $stmt->fetchAll();
    }
    
    /**
     * Busca asignaciones por nombre de usuario
     */
    public function searchByName($name)
    {
        $sql = "SELECT a.*, u.full_name, u.username 
                FROM assignments a 
                INNER JOIN users u ON a.user_id = u.id 
                WHERE u.full_name LIKE :name1 OR u.username LIKE :name2 
                ORDER BY a.start_date ASC";
        
        $stmt = $this->db->prepare($sql);
        $term = "%$name%";
        $stmt->execute(['name1' => $term, 'name2' => $term]);
        
        return $stmt->fetchAll();
    }
    
    /**
     * Reorganiza el orden de las asignaciones (drag & drop)
     */
    public function reorder($assignments)
    {
        $this->db->beginTransaction();
        
        try {
            foreach ($assignments as $position => $assignmentId) {
                $stmt = $this->db->prepare("UPDATE assignments SET order_position = ? WHERE id = ?");
                $stmt->execute([$position, $assignmentId]);
            }
            
            $this->db->commit();
            return true;
        } catch (\Exception $e) {
            $this->db->rollBack();
            return false;
        }
    }
    
    /**
     * Verifica si ya existe una asignación para una semana
     */
    public function existsForWeek($year, $weekNumber)
    {
        $stmt = $this->db->prepare("SELECT COUNT(*) as count FROM assignments WHERE year = ? AND week_number = ?");
        $stmt->execute([$year, $weekNumber]);
        $result = $stmt->fetch();
        return $result['count'] > 0;
    }
    
    /**
     * Elimina asignaciones futuras
     */
    public function deleteFuture()
    {
        $today = date('Y-m-d');
        $stmt = $this->db->prepare("DELETE FROM assignments WHERE start_date > ?");
        return $stmt->execute([$today]);
    }
    
    /**
     * Obtiene la asignación de la semana actual
     */
    public function getCurrentWeek()
    {
        $today = date('Y-m-d');
        
        $sql = "SELECT a.*, u.full_name, u.username 
                FROM assignments a 
                INNER JOIN users u ON a.user_id = u.id 
                WHERE :today BETWEEN a.start_date AND a.end_date";
        
        $stmt = $this->db->prepare($sql);
        $stmt->execute(['today' => $today]);
        
        return $stmt->fetch();
    }
    /**
     * Elimina asignaciones que comienzan después de una fecha dada
     */
    public function deleteFutureAssignments($dateLimit)
    {
        $stmt = $this->db->prepare("DELETE FROM assignments WHERE start_date > ?");
        return $stmt->execute([$dateLimit]);
    }
}
