<?php
session_start();
require_once '../config/database.php';

if (!isset($_SESSION['user_id'])) {
    header('Location: ../login.php');
    exit;
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    header('Location: ../dashboard.php');
    exit;
}

$id            = isset($_POST['id']) ? (int)$_POST['id'] : 0;
$loan_code     = trim($_POST['loan_code'] ?? '');
$loan_date     = trim($_POST['loan_date'] ?? '');
$customer_id   = isset($_POST['customer_id']) ? (int)$_POST['customer_id'] : 0;
$loan_amount   = str_replace(',', '', trim($_POST['loan_amount'] ?? ''));
$borrow_days   = trim($_POST['borrow_days'] ?? '');
$interest_rate = trim($_POST['interest_rate'] ?? '');
$repay_date    = trim($_POST['repay_date'] ?? '');
$status        = trim($_POST['status'] ?? 'active');
$note          = trim($_POST['note'] ?? '');

$errors = [];
$existingLoan = null;
$customerName = '';

function normalizeDateInput($value) {
    $value = trim((string)$value);

    if ($value === '') {
        return '';
    }

    if (preg_match('/^(\d{2})\/(\d{2})\/(\d{4})$/', $value, $matches)) {
        return $matches[3] . '-' . $matches[2] . '-' . $matches[1];
    }

    if (preg_match('/^(\d{2})-(\d{2})-(\d{4})$/', $value, $matches)) {
        return $matches[3] . '-' . $matches[2] . '-' . $matches[1];
    }

    return $value;
}

function redirectBackToEdit($id, array $errors, array $old = []) {
    $_SESSION['form_errors'] = $errors;

    if (!empty($old)) {
        $_SESSION['form_old'] = $old;
    }

    header('Location: edit.php?id=' . (int)$id);
    exit;
}

function getMimeTypeSafe($tmpName) {
    if (!function_exists('finfo_open')) {
        return 'application/octet-stream';
    }

    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    if (!$finfo) {
        return 'application/octet-stream';
    }

    $mimeType = finfo_file($finfo, $tmpName);
    finfo_close($finfo);

    return $mimeType ?: 'application/octet-stream';
}

if ($id <= 0) {
    $_SESSION['form_errors'] = ['Invalid loan ID.'];
    header('Location: ../dashboard.php');
    exit;
}

$loan_date = normalizeDateInput($loan_date);
$repay_date = normalizeDateInput($repay_date);

try {
    $stmt = $pdo->prepare("
        SELECT *
        FROM loans
        WHERE id = ?
        LIMIT 1
    ");
    $stmt->execute([$id]);
    $existingLoan = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$existingLoan) {
        throw new Exception('Loan not found.');
    }

    // Lock these values from DB, not from user input
    $loan_code = trim((string)($existingLoan['loan_code'] ?? ''));
    $customer_id = (int)($existingLoan['customer_id'] ?? 0);

} catch (Exception $e) {
    $_SESSION['form_errors'] = [$e->getMessage()];
    header('Location: ../dashboard.php');
    exit;
}

if ($loan_date === '') {
    $errors[] = 'Loan date is required.';
} else {
    $dateObj = DateTime::createFromFormat('Y-m-d', $loan_date);
    if (!$dateObj || $dateObj->format('Y-m-d') !== $loan_date) {
        $errors[] = 'Invalid loan date format.';
    }
}

if ($repay_date === '') {
    $errors[] = 'Repay date is required.';
} else {
    $dateObj = DateTime::createFromFormat('Y-m-d', $repay_date);
    if (!$dateObj || $dateObj->format('Y-m-d') !== $repay_date) {
        $errors[] = 'Invalid repay date format.';
    }
}

if ($customer_id <= 0) {
    $errors[] = 'Customer is required.';
}

if ($loan_amount === '' || !is_numeric($loan_amount) || (float)$loan_amount <= 0) {
    $errors[] = 'Loan amount must be greater than 0.';
}

if ($borrow_days === '' || !ctype_digit((string)$borrow_days) || (int)$borrow_days <= 0) {
    $errors[] = 'Borrow days must be greater than 0.';
}

if ($interest_rate === '' || !is_numeric($interest_rate) || (float)$interest_rate < 0) {
    $errors[] = 'Interest rate must be 0 or greater.';
}

if (!in_array($status, ['active', 'finished'], true)) {
    $errors[] = 'Invalid status selected.';
}

if ($customer_id > 0) {
    $stmtCustomer = $pdo->prepare("
        SELECT name
        FROM customers
        WHERE id = ?
        LIMIT 1
    ");
    $stmtCustomer->execute([$customer_id]);
    $customerName = trim((string)$stmtCustomer->fetchColumn());

    if ($customerName === '') {
        $errors[] = 'Selected customer does not exist.';
    }
}

if ($loan_date !== '' && $repay_date !== '') {
    $loanDateObj = DateTime::createFromFormat('Y-m-d', $loan_date);
    $repayDateObj = DateTime::createFromFormat('Y-m-d', $repay_date);

    if ($loanDateObj && $repayDateObj && $repayDateObj < $loanDateObj) {
        $errors[] = 'Repay date cannot be earlier than loan date.';
    }
}

if ($loan_code !== '' && $status === 'active') {
    $checkCode = $pdo->prepare("
        SELECT COUNT(*)
        FROM loans
        WHERE loan_code = ?
          AND status = 'active'
          AND id <> ?
    ");
    $checkCode->execute([$loan_code, $id]);

    if ((int)$checkCode->fetchColumn() > 0) {
        $errors[] = 'This case number is already being used by another active loan.';
    }
}

$allowedExtensions = ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx'];
$maxFileSize = 10 * 1024 * 1024;

if (isset($_FILES['attachments']) && isset($_FILES['attachments']['name']) && is_array($_FILES['attachments']['name'])) {
    foreach ($_FILES['attachments']['name'] as $key => $originalName) {
        $originalName = trim((string)$originalName);
        $errorCode = $_FILES['attachments']['error'][$key] ?? UPLOAD_ERR_NO_FILE;

        if ($errorCode === UPLOAD_ERR_NO_FILE || $originalName === '') {
            continue;
        }

        if ($errorCode !== UPLOAD_ERR_OK) {
            $errors[] = 'Failed to upload file: ' . $originalName;
            continue;
        }

        $fileSize = (int)($_FILES['attachments']['size'][$key] ?? 0);
        if ($fileSize <= 0 || $fileSize > $maxFileSize) {
            $errors[] = 'File too large or invalid: ' . $originalName . ' (max 10 MB)';
            continue;
        }

        $ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));
        if (!in_array($ext, $allowedExtensions, true)) {
            $errors[] = 'Invalid file type: ' . $originalName;
        }
    }
}


function compressImage($source, $destination, $quality = 75, $maxWidth = 1200) {
    $info = getimagesize($source);

    if ($info === false) {
        return false;
    }

    list($width, $height) = $info;

    // Calculate new size
    if ($width > $maxWidth) {
        $newWidth = $maxWidth;
        $newHeight = floor($height * ($maxWidth / $width));
    } else {
        $newWidth = $width;
        $newHeight = $height;
    }

    // Create image resource
    switch ($info['mime']) {
        case 'image/jpeg':
            $image = imagecreatefromjpeg($source);
            break;
        case 'image/png':
            $image = imagecreatefrompng($source);
            break;
        default:
            return false;
    }

    $newImage = imagecreatetruecolor($newWidth, $newHeight);

    // Keep transparency for PNG
    if ($info['mime'] === 'image/png') {
        imagealphablending($newImage, false);
        imagesavealpha($newImage, true);
    }

    imagecopyresampled(
        $newImage,
        $image,
        0, 0, 0, 0,
        $newWidth,
        $newHeight,
        $width,
        $height
    );

    // Save compressed
    if ($info['mime'] === 'image/jpeg') {
        imagejpeg($newImage, $destination, $quality);
    } elseif ($info['mime'] === 'image/png') {
        imagepng($newImage, $destination, 6); // 0–9 (higher = smaller)
    }

    imagedestroy($image);
    imagedestroy($newImage);

    return true;
}

$_SESSION['form_old'] = [
    'loan_code'     => $loan_code,
    'loan_date'     => $loan_date,
    'customer_id'   => $customer_id,
    'loan_amount'   => $loan_amount,
    'borrow_days'   => $borrow_days,
    'interest_rate' => $interest_rate,
    'repay_date'    => $repay_date,
    'status'        => $status,
    'note'          => $note,
];

if (!empty($errors)) {
    redirectBackToEdit($id, $errors);
}

$loanAmountFloat   = (float)$loan_amount;
$interestRateFloat = (float)$interest_rate;
$borrowDaysInt     = (int)$borrow_days;

$interest_amount = $loanAmountFloat * $interestRateFloat / 100;
$total_expected  = $loanAmountFloat + $interest_amount;

/*
|--------------------------------------------------------------------------
| Upload path
|--------------------------------------------------------------------------
*/
$projectRoot = dirname(__DIR__);
$uploadsRoot = $projectRoot . '/uploads';
$uploadDir   = $uploadsRoot . '/loan_files';

try {
    if (!is_dir($uploadsRoot)) {
        if (!mkdir($uploadsRoot, 0775, true) && !is_dir($uploadsRoot)) {
            throw new Exception('Failed to create uploads folder: ' . $uploadsRoot);
        }
    }

    if (!is_dir($uploadDir)) {
        if (!mkdir($uploadDir, 0775, true) && !is_dir($uploadDir)) {
            throw new Exception('Failed to create upload folder: ' . $uploadDir);
        }
    }

    if (!is_writable($uploadDir)) {
        throw new Exception('Upload folder is not writable: ' . $uploadDir);
    }

    $pdo->beginTransaction();

    $stmt = $pdo->prepare("
        UPDATE loans
        SET
            loan_date = ?,
            loan_amount = ?,
            borrow_days = ?,
            interest_rate = ?,
            interest_amount = ?,
            repay_date = ?,
            total_expected = ?,
            status = ?,
            note = ?
        WHERE id = ?
        LIMIT 1
    ");

    $stmt->execute([
        $loan_date,
        $loanAmountFloat,
        $borrowDaysInt,
        $interestRateFloat,
        $interest_amount,
        $repay_date,
        $total_expected,
        $status,
        $note !== '' ? $note : null,
        $id
    ]);

    if (isset($_FILES['attachments']) && isset($_FILES['attachments']['name']) && is_array($_FILES['attachments']['name'])) {
        $insertAttachment = $pdo->prepare("
            INSERT INTO loan_attachments
            (loan_id, original_name, file_name, file_type, file_size)
            VALUES (?, ?, ?, ?, ?)
        ");

        foreach ($_FILES['attachments']['name'] as $key => $originalName) {
            $originalName = trim((string)$originalName);
            $errorCode = $_FILES['attachments']['error'][$key] ?? UPLOAD_ERR_NO_FILE;

            if ($errorCode === UPLOAD_ERR_NO_FILE || $originalName === '') {
                continue;
            }

            if ($errorCode !== UPLOAD_ERR_OK) {
                continue;
            }

            $tmpName = $_FILES['attachments']['tmp_name'][$key] ?? '';
            $fileSize = (int)($_FILES['attachments']['size'][$key] ?? 0);
            $ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));
            $safeOriginalName = basename($originalName);

            if (!in_array($ext, $allowedExtensions, true)) {
                continue;
            }

            if (!is_uploaded_file($tmpName)) {
                throw new Exception('Invalid uploaded file: ' . $safeOriginalName);
            }

            $newFileName = uniqid('loan_', true) . '.' . $ext;
            $targetPath = $uploadDir . '/' . $newFileName;
            $mimeType = getMimeTypeSafe($tmpName);

            $mimeType = getMimeTypeSafe($tmpName);

            if (strpos($mimeType, 'image/') === 0) {
                // Compress image
                if (!compressImage($tmpName, $targetPath, 75, 1200)) {
                    throw new Exception('Failed to compress image.');
                }
            } else {
                // Normal file
                if (!move_uploaded_file($tmpName, $targetPath)) {
                    throw new Exception('Failed to save uploaded file.');
                }
            }

            $insertAttachment->execute([
                $id,
                $safeOriginalName,
                $newFileName,
                $mimeType,
                $fileSize
            ]);
        }
    }

    $pdo->commit();

    unset($_SESSION['form_old'], $_SESSION['form_errors']);
    $_SESSION['success_message'] = 'Loan updated successfully.';
    header('Location: edit.php?id=' . $id);
    exit;

} catch (Exception $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }

    $_SESSION['form_errors'] = ['Failed to update loan: ' . $e->getMessage()];
    header('Location: edit.php?id=' . $id);
    exit;
}