<?php

declare(strict_types=1);

require_once __DIR__ . '/../includes/api_service.php';
require_once __DIR__ . '/../includes/local_store.php';
require_once __DIR__ . '/../includes/pdf_generator.php';
require_once __DIR__ . '/../includes/invoice_pdf_generator.php';
require_once __DIR__ . '/../includes/registration_wizard.php';

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    json_response(['success' => false, 'message' => 'Method not allowed'], 405);
}

$token = trim($_POST['token'] ?? '');
$signerName = trim($_POST['signer_name'] ?? '');
$signatureData = $_POST['signature_data'] ?? '';
$signatureMethod = $_POST['signature_method'] ?? 'draw';
$ownerIndex = (int)($_POST['owner_index'] ?? 0);
$agreed = $_POST['agreed'] ?? '';
$registrationEmail = trim($_POST['registration_email'] ?? '');

if ($token === '' || $signerName === '' || $agreed !== '1') {
    json_response(['success' => false, 'message' => 'Please complete all required fields and confirmations.']);
}

if ($signatureData === '' || !str_starts_with($signatureData, 'data:image/')) {
    json_response(['success' => false, 'message' => 'Invalid signature data.']);
}

if ($registrationEmail !== '' && !filter_var($registrationEmail, FILTER_VALIDATE_EMAIL)) {
    json_response(['success' => false, 'message' => 'Please enter a valid email address or leave the field empty.']);
}

try {
    $contract = api_find_contract($token);
} catch (Throwable $e) {
    json_response(['success' => false, 'message' => api_error_message($e)], 502);
}

if (!$contract) {
    json_response(['success' => false, 'message' => 'Record not found.'], 404);
}

$contract = api_ensure_local_contract_record($contract, $token);
$token = local_store_resolve_token($contract, $token);

if ($registrationEmail !== '') {
    $emailUpdates = ['registration_email' => $registrationEmail];
    if (trim((string)($contract['email'] ?? '')) === '') {
        $emailUpdates['email'] = $registrationEmail;
        $emailUpdates['partner_email'] = $registrationEmail;
    }
    local_store_update($token, $emailUpdates);
    $contract = array_merge($contract, $emailUpdates);
}

if (($contract['status'] ?? '') === 'signed') {
    json_response(['success' => false, 'message' => 'This registration has already been completed.']);
}

$existingSignatures = api_get_signatures_for_token($token);
$ownerCount = registration_owner_count($contract);
$expectedIndex = count($existingSignatures);

if ($ownerIndex !== $expectedIndex) {
    json_response(['success' => false, 'message' => 'Please complete the signatures in order.']);
}

$config = app_config();
$signatureFilename = $token . '_owner_' . $ownerIndex . '_' . time() . '.png';
$signaturePath = $config['signatures_dir'] . '/' . $signatureFilename;

$imageData = preg_replace('#^data:image/\w+;base64,#', '', $signatureData);
$decoded = base64_decode($imageData, true);

if ($decoded === false) {
    json_response(['success' => false, 'message' => 'Could not process signature image.']);
}

file_put_contents($signaturePath, $decoded);
prepare_signature_image_for_pdf($signaturePath);

$ip = client_ip();
if ($ip === 'unknown') {
    $linkAccess = is_array($contract['link_last_access'] ?? null) ? $contract['link_last_access'] : [];
    $accessIp = trim((string)($linkAccess['ip_address'] ?? ''));
    if ($accessIp !== '') {
        $ip = $accessIp;
    }
}
$userAgent = $_POST['user_agent'] ?? ($_SERVER['HTTP_USER_AGENT'] ?? 'unknown');
$screenResolution = $_POST['screen_resolution'] ?? '';
$timezone = $_POST['timezone'] ?? '';
$signedAt = date('Y-m-d H:i:s');
$isFinal = ($ownerIndex + 1) >= $ownerCount;
$locationFields = location_audit_fields(contract_link_location($contract));
$signToken = trim((string)($contract['sign_token'] ?? $contract['token'] ?? $token));

$signedPdfFilename = $token . '_signed.pdf';
$signedPdfPath = $config['signed_dir'] . '/' . $signedPdfFilename;

$contractPdfFilename = '';
$auditRecords = [];
if ($isFinal) {
    $signaturePaths = [];

    foreach ($existingSignatures as $existing) {
        $image = $config['signatures_dir'] . '/' . basename((string)($existing['signature_image'] ?? ''));
        if (is_file($image)) {
            $signaturePaths[] = $image;
        }
    }
    $signaturePaths[] = $signaturePath;

    foreach ($signaturePaths as $path) {
        prepare_signature_image_for_pdf($path);
    }

    try {
        $contractPdfFilename = generate_contract_pdf_for_record($contract);
        $contractPdfPath = $config['contracts_dir'] . '/' . $contractPdfFilename;

        if (!is_file($contractPdfPath)) {
            json_response(['success' => false, 'message' => 'Contract PDF could not be generated. Check uploads/contracts permissions.']);
        }

        $auditRecords = signature_audit_records($existingSignatures);
        $auditRecords[] = array_merge([
            'signer_name' => $signerName,
            'signed_at' => $signedAt,
            'ip_address' => $ip,
            'user_agent' => $userAgent,
            'screen_resolution' => $screenResolution,
            'timezone' => $timezone,
            'signature_method' => $signatureMethod,
        ], $locationFields);

        append_signatures_to_pdf(
            $contractPdfPath,
            $signaturePaths,
            $signedPdfPath,
            $auditRecords,
            invoice_contract_is($contract) ? 'invoice' : 'partner'
        );

        if (!is_file($signedPdfPath) || filesize($signedPdfPath) < 1024) {
            json_response(['success' => false, 'message' => 'Signed PDF could not be saved. Check uploads/signed permissions.']);
        }

        contract_delete_unsigned_pdf(
            array_merge($contract, ['status' => 'signed', 'signed_pdf_path' => $signedPdfFilename]),
            $contractPdfPath
        );
    } catch (Throwable $e) {
        json_response(['success' => false, 'message' => $e->getMessage()]);
    }
}

$termsAcceptedAt = $signedAt;

$apiPayload = array_merge([
    'contract_id' => $contract['id'] ?? null,
    'contract_token' => $token,
    'owner_index' => $ownerIndex,
    'owner_count' => $ownerCount,
    'signer_name' => $signerName,
    'signature_image' => $signatureFilename,
    'signature_method' => $signatureMethod,
    'ip_address' => $ip,
    'user_agent' => $userAgent,
    'screen_resolution' => $screenResolution,
    'timezone' => $timezone,
    'signed_at' => $signedAt,
    'terms_accepted' => true,
    'terms_accepted_at' => $termsAcceptedAt,
    'agreed' => true,
    'is_final' => $isFinal,
    'signed_pdf_path' => $isFinal ? $signedPdfFilename : '',
    'signed_pdf_url' => $isFinal ? contract_public_pdf_url($contract) : '',
    'server_data' => [
        'remote_addr' => $_SERVER['REMOTE_ADDR'] ?? '',
        'http_accept_language' => $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '',
        'http_referer' => $_SERVER['HTTP_REFERER'] ?? '',
    ],
], $locationFields);

$apiSyncError = null;
$apiDebug = null;

try {
    local_store_save_owner_signature($token, $apiPayload);

    if ($isFinal && $signedPdfFilename !== '' && is_file($signedPdfPath)) {
        $finalUpdates = [
            'pdf_path' => '',
            'signed_pdf_path' => $signedPdfFilename,
            'contract_status' => 'signed',
        ];

        if ($locationFields !== []) {
            $finalUpdates['customer_location'] = $locationFields;
        }

        local_store_update($token, $finalUpdates);
    }
} catch (Throwable $e) {
    json_response(['success' => false, 'message' => api_error_message($e)], 502);
}

$contract = local_store_find($token) ?? $contract;

$emailResult = null;
if ($isFinal && is_file($signedPdfPath)) {
    try {
        require_once __DIR__ . '/../includes/contract_email_service.php';
        $emailResult = contract_send_registration_emails($contract, [
            'signed_pdf_path' => $signedPdfPath,
            'audit_records' => $auditRecords,
            'signed_at' => $signedAt,
        ]);
    } catch (Throwable $e) {
        require_once __DIR__ . '/../includes/resend_client.php';
        $emailResult = [
            'enabled' => email_is_enabled(),
            'error' => $e->getMessage(),
        ];
    }
}

$customerContext = [
    'post' => [
        'token' => $token,
        'owner_index' => $ownerIndex,
        'signer_name' => $signerName,
        'signature_method' => $signatureMethod,
        'agreed' => $agreed,
        'registration_email' => $registrationEmail !== '' ? $registrationEmail : ($contract['registration_email'] ?? ''),
        'user_agent' => $userAgent,
        'screen_resolution' => $screenResolution,
        'timezone' => $timezone,
    ],
    'request' => [
        'remote_addr' => $_SERVER['REMOTE_ADDR'] ?? '',
        'http_accept_language' => $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '',
        'http_referer' => $_SERVER['HTTP_REFERER'] ?? '',
        'request_method' => $_SERVER['REQUEST_METHOD'] ?? '',
        'request_uri' => $_SERVER['REQUEST_URI'] ?? '',
    ],
    'location' => $locationFields,
    'audit_records' => $auditRecords,
];

if (api_partner_sign_enabled()) {
    $termsAccepted = $agreed === '1';
    $rawData = api_build_partner_sign_raw_data(
        $contract,
        $signToken,
        $apiPayload,
        $signatureFilename,
        $isFinal,
        $contractPdfFilename,
        $isFinal ? $signedPdfFilename : '',
        $customerContext
    );
    if ($isFinal) {
        $requestBody = api_build_partner_sign_request_body($rawData, $termsAccepted);
        $apiDebug = api_partner_sign_debug_snapshot($signToken, $requestBody);
        $apiDebug['partner_api_enabled'] = true;
        $apiDebug['agreed_post'] = $agreed;
        $apiDebug['is_final'] = true;
    }

    try {
        api_submit_partner_contract_sign($signToken, $rawData, $termsAccepted);
        if ($apiDebug !== null) {
            $apiDebug['synced'] = true;
            $apiDebug['error'] = null;
        }
        local_store_update($token, ['partner_api_signed' => true]);
    } catch (Throwable $e) {
        $apiSyncError = api_error_message($e);
        if ($apiDebug !== null) {
            $apiDebug['synced'] = false;
            $apiDebug['error'] = $apiSyncError;
            $apiDebug['status_code'] = $e instanceof ApiException ? $e->statusCode : 500;
            $apiDebug['api_response'] = $e instanceof ApiException ? $e->response : null;
            $lastRequest = api_get_last_request_debug();
            if ($lastRequest !== null) {
                $apiDebug['transport'] = $lastRequest;
            }
        }

        if (api_legacy_sign_enabled()) {
            try {
                api_save_signature($token, $apiPayload);

                if ($isFinal && is_file($signedPdfPath)) {
                    api_update_contract($token, [
                        'pdf_path' => '',
                        'signed_pdf_path' => $signedPdfFilename,
                        'pdf_url' => contract_public_pdf_url($contract),
                    ]);
                }

                $apiSyncError = null;
                if ($apiDebug !== null) {
                    $apiDebug['synced'] = true;
                    $apiDebug['error'] = null;
                    $apiDebug['fallback'] = 'legacy_sign';
                }
            } catch (Throwable $legacyError) {
                $apiSyncError = api_error_message($legacyError);
            }
        }
    }

    if ($apiDebug !== null && ($apiDebug['transport'] ?? null) === null) {
        $lastRequest = api_get_last_request_debug();
        if ($lastRequest !== null) {
            $apiDebug['transport'] = $lastRequest;
        }
    }
} elseif (api_legacy_sign_enabled()) {
    try {
        api_save_signature($token, $apiPayload);

        if ($isFinal && is_file($signedPdfPath)) {
            api_update_contract($token, [
                'pdf_path' => '',
                'signed_pdf_path' => $signedPdfFilename,
                'pdf_url' => contract_public_pdf_url($contract),
            ]);
        }
    } catch (Throwable $e) {
        $apiSyncError = api_error_message($e);
    }
}

$response = [
    'success' => true,
    'message' => $isFinal ? 'Registration completed successfully.' : 'Signature saved.',
    'owner_index' => $ownerIndex,
    'next_owner_index' => $isFinal ? null : ($ownerIndex + 1),
    'is_final' => $isFinal,
    'signed_at' => $signedAt,
    'signed_pdf_url' => $isFinal ? $apiPayload['signed_pdf_url'] : null,
    'api_synced' => $apiSyncError === null,
    'api_warning' => $apiSyncError,
    'email' => $emailResult,
];

json_response($response);
