<?php
if (file_exists('../../../' . ($_REQUEST['tenant'] ?? '') . '/config.php')) {
    require_once('../../../' . $_REQUEST['tenant'] . '/config.php');
}

if (file_exists(__DIR__ . '/../../functions/logging.php')) {
    require_once __DIR__ . '/../../functions/logging.php';
}

header('Content-Type: application/json; charset=utf-8');

function reportReviewJson(bool $ok, string $message = '', array $extra = []): void
{
    echo json_encode(array_merge(['ok' => $ok, 'message' => $message], $extra));
    exit;
}

function reportReviewTableReady(): bool
{
    if (empty($GLOBALS['con']) || !($GLOBALS['con'] instanceof mysqli)) {
        return false;
    }

    $stmt = $GLOBALS['con']->prepare("SELECT `id` FROM `report_review_actions` LIMIT 1");
    if (!$stmt) {
        return false;
    }
    $ok = $stmt->execute();
    $stmt->close();
    return $ok;
}

function reportReviewFetchReport(int $repitem): ?array
{
    $stmt = $GLOBALS['con']->prepare("
        SELECT
            a.`repitem`,
            a.`repnumber`,
            a.`clientnumber`,
            a.`itemnumber`,
            a.`insdate`,
            a.`esname` AS surveyor_id,
            i.`desc` AS item_name,
            i.`plantnumber`,
            i.`serialnumber`,
            i.`subloc`,
            l.`locname`,
            s.`forename`,
            s.`surname`,
            s.`email`,
            s.`phone1`,
            s.`mobile`
        FROM `reportitems` a
        LEFT JOIN `itemdetails` i ON a.`itemnumber` = i.`itemnumber`
        LEFT JOIN `locations` l ON i.`locnumber` = l.`locnumber`
        LEFT JOIN `surveyor` s ON a.`esname` = s.`id`
        WHERE a.`repitem` = ? AND a.`delivery` = 0
        LIMIT 1
    ");
    if (!$stmt) {
        return null;
    }
    $stmt->bind_param('i', $repitem);
    $stmt->execute();
    $res = $stmt->get_result();
    $row = $res ? $res->fetch_assoc() : null;
    $stmt->close();
    return $row ?: null;
}

function reportReviewFetchReports(array $repitems, int $clientnumber): array
{
    $repitems = array_values(array_unique(array_filter(array_map('intval', $repitems), static function ($repitem) {
        return $repitem > 0;
    })));
    if (empty($repitems) || $clientnumber <= 0) {
        return [];
    }

    $ph = implode(',', array_fill(0, count($repitems), '?'));
    $types = str_repeat('i', count($repitems) + 1);
    $params = array_merge($repitems, [$clientnumber]);
    $stmt = $GLOBALS['con']->prepare("
        SELECT
            a.`repitem`,
            a.`repnumber`,
            a.`clientnumber`,
            a.`itemnumber`,
            a.`insdate`,
            a.`esname` AS surveyor_id,
            i.`desc` AS item_name,
            i.`plantnumber`,
            i.`serialnumber`,
            i.`subloc`,
            l.`locname`,
            s.`forename`,
            s.`surname`,
            s.`email`,
            s.`phone1`,
            s.`mobile`
        FROM `reportitems` a
        LEFT JOIN `itemdetails` i ON a.`itemnumber` = i.`itemnumber`
        LEFT JOIN `locations` l ON i.`locnumber` = l.`locnumber`
        LEFT JOIN `surveyor` s ON a.`esname` = s.`id`
        WHERE a.`repitem` IN ($ph) AND a.`clientnumber` = ? AND a.`delivery` = 0
        ORDER BY ABS(a.`repitem`) DESC
    ");
    if (!$stmt) {
        return [];
    }
    $stmt->bind_param($types, ...$params);
    if (!$stmt->execute()) {
        $stmt->close();
        return [];
    }
    $res = $stmt->get_result();
    $reports = [];
    while ($row = $res->fetch_assoc()) {
        $reports[] = $row;
    }
    $stmt->close();
    return $reports;
}

function reportReviewLog(string $action, string $message, array $report, array $context = []): void
{
    if (!function_exists('enrep_log')) {
        return;
    }

    $location = trim((string)($report['locname'] ?? '') . ' ' . (string)($report['subloc'] ?? ''));
    enrep_log('report_review', $action, $message, array_merge([
        'entity_type' => 'reportitems',
        'entity_id' => (string)($report['repnumber'] ?? ''),
        'clientnumber' => (int)($report['clientnumber'] ?? 0),
        'itemnumber' => (int)($report['itemnumber'] ?? 0),
        'subject' => 'Report ' . (string)($report['repnumber'] ?? ''),
        'repitem' => (int)($report['repitem'] ?? 0),
        'repnumber' => (string)($report['repnumber'] ?? ''),
        'item_name' => (string)($report['item_name'] ?? ''),
        'plantnumber' => (string)($report['plantnumber'] ?? ''),
        'serialnumber' => (string)($report['serialnumber'] ?? ''),
        'location' => $location,
        'surveyor_id' => (int)($report['surveyor_id'] ?? 0),
    ], $context));
}

if (!reportReviewTableReady()) {
    reportReviewJson(false, 'Report review action table is not installed yet.');
}

$action = trim((string)($_POST['action'] ?? ''));
$now = time();
$userId = (int)($_SESSION['userid'] ?? 0);
$userType = (string)($_SESSION['usertype'] ?? '');

if ($action === 'list_surveyor') {
    if ($userId <= 0 || $userType !== 'surveyor') {
        reportReviewJson(false, 'Not authorised.');
    }

    $stmt = $GLOBALS['con']->prepare("
        SELECT
            rra.`id`,
            rra.`repitem`,
            rra.`repnumber`,
            rra.`clientnumber`,
            rra.`itemnumber`,
            rra.`status`,
            rra.`admin_note`,
            rra.`surveyor_response`,
            rra.`created_at`,
            rra.`updated_at`,
            cd.`clientname`,
            i.`desc` AS item_name,
            i.`plantnumber`,
            i.`serialnumber`,
            i.`subloc`,
            i.`locnumber`,
            l.`locname`,
            ri.`insdate`,
            ri.`reptype` AS formnumber
        FROM `report_review_actions` rra
        LEFT JOIN `clientdetails` cd ON rra.`clientnumber` = cd.`clientnumber`
        LEFT JOIN `itemdetails` i ON rra.`itemnumber` = i.`itemnumber`
        LEFT JOIN `locations` l ON i.`locnumber` = l.`locnumber`
        LEFT JOIN `reportitems` ri ON rra.`repitem` = ri.`repitem`
        WHERE rra.`surveyor_id` = ? AND rra.`status` IN ('pending', 'responded')
        ORDER BY rra.`updated_at` DESC, rra.`created_at` DESC
    ");
    if (!$stmt) {
        reportReviewJson(false, 'Unable to load review actions.');
    }
    $stmt->bind_param('i', $userId);
    $stmt->execute();
    $res = $stmt->get_result();
    $notes = [];
    while ($row = $res->fetch_assoc()) {
        $row['id'] = (int)$row['id'];
        $row['repitem'] = (int)$row['repitem'];
        $row['clientnumber'] = (int)$row['clientnumber'];
        $row['itemnumber'] = (int)$row['itemnumber'];
        $row['locnumber'] = (int)($row['locnumber'] ?? 0);
        $row['formnumber'] = trim((string)($row['formnumber'] ?? ''));
        $row['created_at'] = (int)$row['created_at'];
        $row['updated_at'] = (int)$row['updated_at'];
        $row['insdate'] = (int)($row['insdate'] ?? 0);
        $notes[] = $row;
    }
    $stmt->close();
    reportReviewJson(true, '', ['notes' => $notes]);
}

if ($action === 'ready_bulk') {
    $clientnumber = (int)($_POST['clientnumber'] ?? 0);
    $repitemsJson = (string)($_POST['repitems'] ?? '[]');
    $repitems = json_decode($repitemsJson, true);
    if ($clientnumber <= 0 || !is_array($repitems) || empty($repitems)) {
        reportReviewJson(false, 'No reports were selected.');
    }

    $reports = reportReviewFetchReports($repitems, $clientnumber);
    if (empty($reports)) {
        reportReviewJson(false, 'No selected outstanding reports were found.');
    }

    $status = 'ready';
    $empty = '';
    $updated = 0;
    $stmt = $GLOBALS['con']->prepare("
        INSERT INTO `report_review_actions`
            (`repitem`, `repnumber`, `clientnumber`, `itemnumber`, `surveyor_id`, `status`, `admin_note`, `surveyor_response`, `created_by`, `created_at`, `updated_by`, `updated_at`)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ON DUPLICATE KEY UPDATE
            `status` = VALUES(`status`),
            `admin_note` = '',
            `surveyor_response` = '',
            `surveyor_id` = VALUES(`surveyor_id`),
            `updated_by` = VALUES(`updated_by`),
            `updated_at` = VALUES(`updated_at`)
    ");
    if (!$stmt) {
        reportReviewJson(false, 'Unable to mark selected reports ready.');
    }

    foreach ($reports as $report) {
        $reportRepitem = (int)$report['repitem'];
        $reportRepnumber = (string)$report['repnumber'];
        $reportClientnumber = (int)$report['clientnumber'];
        $reportItemnumber = (int)$report['itemnumber'];
        $reportSurveyorId = (int)$report['surveyor_id'];
        $stmt->bind_param('isiiisssiiii', $reportRepitem, $reportRepnumber, $reportClientnumber, $reportItemnumber, $reportSurveyorId, $status, $empty, $empty, $userId, $now, $userId, $now);
        if ($stmt->execute()) {
            $updated++;
        }
    }
    $stmt->close();

    if ($updated > 0 && function_exists('enrep_log')) {
        $itemLines = [];
        foreach ($reports as $report) {
            $location = trim((string)($report['locname'] ?? '') . ' ' . (string)($report['subloc'] ?? ''));
            $itemLines[] = 'Report ' . (string)$report['repnumber']
                . ' - Item ' . (int)$report['itemnumber']
                . ' - ' . trim((string)($report['item_name'] ?? ''))
                . ' - Plant ' . trim((string)($report['plantnumber'] ?? ''))
                . ' - Serial ' . trim((string)($report['serialnumber'] ?? ''))
                . ($location !== '' ? ' - ' . $location : '');
        }
        enrep_log('report_review', 'ready_bulk', 'Marked ' . $updated . ' selected outstanding report item(s) as ready to send for ' . getClientName($clientnumber, 'name') . ".\n\nItems:\n" . implode("\n", $itemLines), [
            'entity_type' => 'reportitems',
            'entity_id' => (string)$clientnumber,
            'clientnumber' => $clientnumber,
            'subject' => 'Reports marked ready to send',
            'repitems' => $repitems,
            'items' => $reports,
        ]);
    }

    reportReviewJson(true, '', ['updated' => $updated]);
}

$repitem = (int)($_POST['repitem'] ?? 0);
if ($repitem <= 0) {
    reportReviewJson(false, 'Invalid report item.');
}

$report = reportReviewFetchReport($repitem);
if (!$report) {
    reportReviewJson(false, 'Outstanding report was not found.');
}

if ($action === 'ready') {
    $status = 'ready';
    $empty = '';
    $reportRepitem = (int)$report['repitem'];
    $reportRepnumber = (string)$report['repnumber'];
    $reportClientnumber = (int)$report['clientnumber'];
    $reportItemnumber = (int)$report['itemnumber'];
    $reportSurveyorId = (int)$report['surveyor_id'];
    $stmt = $GLOBALS['con']->prepare("
        INSERT INTO `report_review_actions`
            (`repitem`, `repnumber`, `clientnumber`, `itemnumber`, `surveyor_id`, `status`, `admin_note`, `surveyor_response`, `created_by`, `created_at`, `updated_by`, `updated_at`)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ON DUPLICATE KEY UPDATE
            `status` = VALUES(`status`),
            `admin_note` = '',
            `surveyor_response` = '',
            `surveyor_id` = VALUES(`surveyor_id`),
            `updated_by` = VALUES(`updated_by`),
            `updated_at` = VALUES(`updated_at`)
    ");
    if (!$stmt) {
        reportReviewJson(false, 'Unable to mark report ready.');
    }
    $stmt->bind_param('isiiisssiiii', $reportRepitem, $reportRepnumber, $reportClientnumber, $reportItemnumber, $reportSurveyorId, $status, $empty, $empty, $userId, $now, $userId, $now);
    $ok = $stmt->execute();
    $stmt->close();
    if (!$ok) {
        reportReviewJson(false, 'Unable to mark report ready.');
    }
    reportReviewLog('ready', 'Marked report ' . $report['repnumber'] . ' as ready to send.', $report);
    reportReviewJson(true);
}

if ($action === 'note') {
    $note = trim((string)($_POST['note'] ?? ''));
    if ($note === '') {
        reportReviewJson(false, 'Please add an action note.');
    }
    $status = 'pending';
    $empty = '';
    $reportRepitem = (int)$report['repitem'];
    $reportRepnumber = (string)$report['repnumber'];
    $reportClientnumber = (int)$report['clientnumber'];
    $reportItemnumber = (int)$report['itemnumber'];
    $reportSurveyorId = (int)$report['surveyor_id'];
    $stmt = $GLOBALS['con']->prepare("
        INSERT INTO `report_review_actions`
            (`repitem`, `repnumber`, `clientnumber`, `itemnumber`, `surveyor_id`, `status`, `admin_note`, `surveyor_response`, `created_by`, `created_at`, `updated_by`, `updated_at`)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
        ON DUPLICATE KEY UPDATE
            `status` = VALUES(`status`),
            `admin_note` = VALUES(`admin_note`),
            `surveyor_response` = '',
            `surveyor_id` = VALUES(`surveyor_id`),
            `updated_by` = VALUES(`updated_by`),
            `updated_at` = VALUES(`updated_at`)
    ");
    if (!$stmt) {
        reportReviewJson(false, 'Unable to save surveyor note.');
    }
    $stmt->bind_param('isiiisssiiii', $reportRepitem, $reportRepnumber, $reportClientnumber, $reportItemnumber, $reportSurveyorId, $status, $note, $empty, $userId, $now, $userId, $now);
    $ok = $stmt->execute();
    $stmt->close();
    if (!$ok) {
        reportReviewJson(false, 'Unable to save surveyor note.');
    }
    reportReviewLog('note_sent', 'Sent correction note for report ' . $report['repnumber'] . '.', $report, ['note' => $note]);
    reportReviewJson(true);
}

if ($action === 'cancel') {
    $stmt = $GLOBALS['con']->prepare("DELETE FROM `report_review_actions` WHERE `repitem` = ? LIMIT 1");
    if (!$stmt) {
        reportReviewJson(false, 'Unable to cancel action.');
    }
    $stmt->bind_param('i', $repitem);
    $ok = $stmt->execute();
    $stmt->close();
    if (!$ok) {
        reportReviewJson(false, 'Unable to cancel action.');
    }
    reportReviewLog('cancelled', 'Cancelled correction action for report ' . $report['repnumber'] . '.', $report);
    reportReviewJson(true);
}

if ($action === 'respond' || $action === 'complete') {
    if ($userId <= 0 || $userType !== 'surveyor' || $userId !== (int)$report['surveyor_id']) {
        reportReviewJson(false, 'Not authorised.');
    }

    if ($action === 'respond') {
        $response = trim((string)($_POST['response'] ?? ''));
        if ($response === '') {
            reportReviewJson(false, 'Please add your response.');
        }
        $status = 'responded';
        $stmt = $GLOBALS['con']->prepare("UPDATE `report_review_actions` SET `status`=?, `surveyor_response`=?, `updated_by`=?, `updated_at`=? WHERE `repitem`=? AND `surveyor_id`=? LIMIT 1");
        if (!$stmt) {
            reportReviewJson(false, 'Unable to save response.');
        }
        $stmt->bind_param('ssiiii', $status, $response, $userId, $now, $repitem, $userId);
        $ok = $stmt->execute();
        $stmt->close();
        if (!$ok) {
            reportReviewJson(false, 'Unable to save response.');
        }
        reportReviewLog('responded', 'Surveyor responded to correction note for report ' . $report['repnumber'] . '.', $report, ['response' => $response]);
        reportReviewJson(true);
    }

    $status = 'complete';
    $stmt = $GLOBALS['con']->prepare("UPDATE `report_review_actions` SET `status`=?, `updated_by`=?, `updated_at`=? WHERE `repitem`=? AND `surveyor_id`=? LIMIT 1");
    if (!$stmt) {
        reportReviewJson(false, 'Unable to complete action.');
    }
    $stmt->bind_param('siiii', $status, $userId, $now, $repitem, $userId);
    $ok = $stmt->execute();
    $stmt->close();
    if (!$ok) {
        reportReviewJson(false, 'Unable to complete action.');
    }
    reportReviewLog('completed', 'Surveyor marked correction action complete for report ' . $report['repnumber'] . '.', $report);
    reportReviewJson(true);
}

reportReviewJson(false, 'Unknown review action.');
