<?php
ob_start();
include("../../../include/startup.php");
ob_clean();
header('Content-Type: application/json');
error_reporting(0);

function recalculateMachineDatesforassbly($conn, $machineId) {
    set_time_limit(300); // Avoid timeout

    $shiftsByDay = [];
    $shiftResult = mysqli_query($conn, "SELECT * FROM working_hours");
    while ($row = mysqli_fetch_assoc($shiftResult)) {
        $day = (int)$row['day_shifts'];
        $shiftsByDay[$day][] = $row;
    }

    $currentDateStr = date('Y-m-d');
    $tasks = [];

    $taskResult = mysqli_query($conn,
        "SELECT id, total_hours  AS hours_to_schedule
         FROM assbly_machine_table
         WHERE machine_id = $machineId 
           AND finished = 0 
         ORDER BY priority"
    );

    while ($row = mysqli_fetch_assoc($taskResult)) {
        $tasks[] = $row;
    }

    $currentDateTime = strtotime(date('Y-m-d') . ' 00:00:00');

    foreach ($tasks as $task) {
        $hoursRemaining = floatval($task['hours_to_schedule']);
        $dateHoursMap = [];
        $taskStartTime = null;
        $taskEndTime = null;
        $firstShiftUsed = null;

        while ($hoursRemaining > 0) {
            $currentDate = date('Y-m-d', $currentDateTime);
            $dayOfWeek = date('w', $currentDateTime);

            if (!isset($shiftsByDay[$dayOfWeek])) {
                $currentDateTime = strtotime($currentDate . ' +1 day');
                continue;
            }

            foreach ($shiftsByDay[$dayOfWeek] as $shift) {
                $shiftStart = strtotime($currentDate . ' ' . $shift['start_time']);
                $shiftEnd   = strtotime($currentDate . ' ' . $shift['end_time']);
                $shiftName  = $shift['shift_name'];

                if ($shiftEnd <= $currentDateTime) continue;

                $actualStart = max($currentDateTime, $shiftStart);
                $availableSeconds = max(0, $shiftEnd - $actualStart);
                $availableHours = $availableSeconds / 3600;

                if ($availableHours <= 0) continue;

                $allocatable = min($hoursRemaining, $availableHours);

                if (!$taskStartTime) {
                    $taskStartTime = $actualStart;
                    $firstShiftUsed = $shiftName;
                }

                $taskEndTime = $actualStart + ($allocatable * 3600);
                $hoursRemaining -= $allocatable;

                // Add to map
                $dateOnly = date('Y-m-d', $actualStart);
                if (!isset($dateHoursMap[$dateOnly])) {
                    $dateHoursMap[$dateOnly] = 0;
                }
                $dateHoursMap[$dateOnly] += $allocatable;

                // Update current pointer
                $currentDateTime = $taskEndTime;

                if ($hoursRemaining <= 0) break;
            }

            if ($hoursRemaining > 0) {
                $currentDateTime = strtotime(date('Y-m-d', $currentDateTime) . ' +1 day 00:00:00');
            }
        }

        $remainingHoursStr = '';
        foreach ($dateHoursMap as $date => $hrs) {
            $remainingHoursStr .= $date . '=' . round($hrs, 2) . ',';
        }
        $remainingHoursStr = rtrim($remainingHoursStr, ',');

        $startStr = date('Y-m-d H:i:s', $taskStartTime);
        $endStr   = date('Y-m-d H:i:s', $taskEndTime);

        $query = "UPDATE assbly_machine_table SET
            start_date = '$startStr',
            end_date = '$endStr',
            shift_ids = '$firstShiftUsed',
            remaing_hours = '$remainingHoursStr'
            WHERE id = {$task['id']}";

        mysqli_query($conn, $query);
    }
}

// ── Handle priority update action ──────────────────────────────────────────
if (isset($_REQUEST['action']) && $_REQUEST['action'] == 'update_assmbly_task_priority') {
    $taskId               = intval($_REQUEST['task_id']);
    $newMachineId         = intval($_REQUEST['new_machine_id']);
    $partId               = intval($_REQUEST['part_id']);
    $workOrderId          = intval($_REQUEST['work_order_id']);
    $leftNeighborPriority = isset($_REQUEST['left_neighbor_priority']) ? intval($_REQUEST['left_neighbor_priority']) : null;
    $leftNeighborTaskId   = isset($_REQUEST['left_neighbor_task_id'])  ? intval($_REQUEST['left_neighbor_task_id'])  : null;
    $today = date('Y-m-d');

    $draggedTask = $conn->query("SELECT * FROM assbly_machine_table WHERE id = $taskId")->fetch_assoc();
    if (!$draggedTask) {
        echo json_encode(['status' => 'error', 'message' => 'Task not found']);
        exit;
    }

    // Repack original machine priorities (excluding dragged task)
    $originalTasks = [];
    $originalResult = mysqli_query($conn, "
        SELECT id, priority FROM assbly_machine_table 
        WHERE machine_id = {$draggedTask['machine_id']} 
          AND end_date >= '$today'
        ORDER BY priority
    ");
    while ($row = mysqli_fetch_assoc($originalResult)) $originalTasks[] = $row;

    $cases = [];
    $newPriority = 1;
    foreach ($originalTasks as $task) {
        if ($task['id'] != $taskId) {
            $cases[] = "WHEN {$task['id']} THEN $newPriority";
            $newPriority++;
        }
    }
    if (!empty($cases)) {
        $ids = implode(',', array_column($originalTasks, 'id'));
        mysqli_query($conn, "UPDATE assbly_machine_table 
            SET priority = CASE id " . implode(' ', $cases) . " END
            WHERE id IN ($ids)");
    }

    // Make room on destination machine
    $insertPriority = ($leftNeighborPriority !== null) ? $leftNeighborPriority + 1 : 1;
    mysqli_query($conn, "UPDATE assbly_machine_table 
        SET priority = priority + 1 
        WHERE machine_id = $newMachineId 
          AND end_date >= '$today'
          AND priority >= $insertPriority");

    // Move the task
    mysqli_query($conn, "UPDATE assbly_machine_table SET 
        machine_id = $newMachineId,
        priority   = $insertPriority
        WHERE id = $taskId");

    // Recalculate
    if ($draggedTask['machine_id'] != $newMachineId) {
        recalculateMachineDatesforassbly($conn, $draggedTask['machine_id']);
    }
    recalculateMachineDatesforassbly($conn, $newMachineId);

    ob_clean();
    echo json_encode(['status' => 'success', 'message' => 'Task priorities and dates updated successfully']);
    ob_end_flush();
    exit();
}

// ── Main data fetch ─────────────────────────────────────────────────────────
try {
    $current_page = isset($_GET['current_page']) ? max(1, (int)$_GET['current_page']) : 1;
    $per_page     = isset($_GET['per_page'])     ? max(1, (int)$_GET['per_page'])     : 50;
    $offset       = max(0, ($current_page - 1) * $per_page);

    $start_date = isset($_GET['start_date']) ? $_GET['start_date'] : date('Y-m-d');
    $work_order = isset($_GET['work_order']) ? trim($_GET['work_order']) : '';
    $product    = isset($_GET['product'])    ? trim($_GET['product'])    : '';
    $machine_id = isset($_GET['machine'])    ? (int)$_GET['machine']    : 0;
    $priority   = isset($_GET['priority'])   ? (int)$_GET['priority']   : 0;

    $where_conditions = ["mmt.end_date >= '$start_date'", "(mmt.is_break = 0 OR mmt.is_break IS NULL)"];

    if (!empty($work_order)) {
        $work_order_safe = $conn->real_escape_string($work_order);
        $where_conditions[] = "(wo.work_order_no LIKE '%$work_order_safe%')";
    }
    if (!empty($product)) {
        $product_safe = $conn->real_escape_string($product);
        $where_conditions[] = "(mmt.product_name LIKE '%$product_safe%' OR won.work_order_name LIKE '%$product_safe%')";
    }
    if ($machine_id > 0) $where_conditions[] = "mmt.machine_id = $machine_id";
    if ($priority   > 0) $where_conditions[] = "mmt.priority = $priority";

    $where_clause = implode(' AND ', $where_conditions);

    $count_result   = $conn->query("SELECT COUNT(DISTINCT mmt.id) as total
        FROM assbly_machine_table mmt
        LEFT JOIN work_order wo ON mmt.work_order_id = wo.id
        LEFT JOIN work_order_name won ON mmt.work_order_id = won.work_order_id AND mmt.part_id = won.part_id
        LEFT JOIN station_detail_table sd ON mmt.machine_id = sd.id
        WHERE $where_clause");
    if (!$count_result) throw new Exception($conn->error);

    $total_records = $count_result->fetch_assoc()['total'];
    $total_pages   = ceil($total_records / $per_page);

    $query = "SELECT 
        mmt.machine_id AS task,
        mmt.id as task_id,
        wo.work_order_no,
        mmt.part_id,
        wo.require_date,
        mmt.setup_hours,
        mmt.priority,
        mmt.total_hours AS hours_to_schedule,
        mmt.total_hours,
        mmt.work_order_id,
        mmt.product_name,
        mmt.quantity,
        mmt.finished,
        mmt.set_id,
        won.work_order_name,
        mmt.shift_ids AS shift_name,
        DATE(mmt.start_date) AS start_date,
        DATE(mmt.end_date) AS end_date,
        TIME(mmt.start_date) AS start_time,
        mmt.is_break,
        mmt.break_reason,
        mmt.is_breakdown_affected,
        mmt.breakdown_hours,
        mb.id as breakdown_id,
        mb.breakdown_reason as machine_breakdown_reason,
        m.end_date as manufacture_end_date,
        m.description as manufacture_description,
        m.parent_ids,
        im.part_number as parent_part_number,
        sd.resource_code as machine_name,
        GROUP_CONCAT(DISTINCT wocr.work_order_no ORDER BY wocr.work_order_no SEPARATOR ', ') as customer_order_nos,
        COALESCE((
            SELECT SUM(apcl.quantity)
            FROM assbly_part_count_log apcl
            WHERE apcl.work_order_id = wo.id
              AND apcl.assbly_machine_table_id = mmt.id
              AND apcl.part_id = mmt.part_id
              AND apcl.type = 'ok'
              AND apcl.id IN (
                SELECT MAX(apcl2.id)
                FROM assbly_part_count_log apcl2
                WHERE apcl2.engineer_id = apcl.engineer_id
                  AND apcl2.work_order_id = apcl.work_order_id
                  AND apcl2.assbly_machine_table_id = apcl.assbly_machine_table_id
                  AND apcl2.part_id = apcl.part_id
                  AND apcl2.type = 'ok'
                GROUP BY apcl2.engineer_id
              )
        ), 0) as quantity_made
    FROM assbly_machine_table mmt
    LEFT JOIN work_order wo ON mmt.work_order_id = wo.id
    LEFT JOIN work_order_name won ON mmt.work_order_id = won.work_order_id AND mmt.part_id = won.part_id
    LEFT JOIN machine_breakdown mb ON mmt.machine_id = mb.machine_id AND mb.is_active = 1
    LEFT JOIN station_detail_table sd ON mmt.machine_id = sd.id
    LEFT JOIN (
        SELECT m1.part_id, m1.work_order_id, m1.end_date, m1.description, m1.parent_ids
        FROM manufacture_machine_table m1
        INNER JOIN (
            SELECT part_id, work_order_id, MAX(end_date) as max_end_date
            FROM manufacture_machine_table
            GROUP BY part_id, work_order_id
        ) m2 ON m1.part_id = m2.part_id 
            AND m1.work_order_id = m2.work_order_id 
            AND m1.end_date = m2.max_end_date
    ) m ON mmt.part_id = m.part_id AND mmt.work_order_id = m.work_order_id
    LEFT JOIN item_management im ON m.parent_ids = im.id
    LEFT JOIN work_order_customer_ref_mapping wocr ON mmt.work_order_id = wocr.work_order_id
    WHERE $where_clause
    GROUP BY 
        mmt.id, mmt.machine_id, wo.work_order_no, mmt.part_id, mmt.setup_hours,
        mmt.priority, mmt.total_hours, mmt.work_order_id,
        mmt.product_name, mmt.quantity, mmt.finished, mmt.set_id,
        won.work_order_name, mmt.shift_ids, mmt.start_date,
        mmt.end_date, mmt.is_break, mmt.break_reason, mmt.is_breakdown_affected,
        mmt.breakdown_hours, mb.id, mb.breakdown_reason, m.end_date,
        m.description, im.part_number, sd.resource_code
    ORDER BY mmt.priority ASC, mmt.start_date ASC
    LIMIT $per_page OFFSET $offset";

    $result = $conn->query($query);
    if (!$result) throw new Exception($conn->error);

    $work_orders = [];
    while ($row = $result->fetch_assoc()) $work_orders[] = $row;

    ob_clean();
    echo json_encode([
        'success' => true,
        'data' => $work_orders,
        'pagination' => [
            'current_page' => $current_page,
            'per_page'     => $per_page,
            'total_records'=> $total_records,
            'total_pages'  => $total_pages,
            'offset'       => $offset,
            'showing_from' => $offset + 1,
            'showing_to'   => min($offset + $per_page, $total_records)
        ]
    ]);

} catch (Exception $e) {
    ob_clean();
    echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}

ob_end_flush();
?>