{{--
<!DOCTYPE html>
<html>

<head>
    <title>PDF to HTML</title>
</head>

<body>

    <h2>Upload PDF</h2>

    <form action="{{ route('convert') }}" method="POST" enctype="multipart/form-data">

        @csrf

        <input type="file" name="pdf" accept=".pdf" required>

        <button type="submit">
            Convert
        </button>

    </form>

</body>

</html> --}}




<!DOCTYPE html>
<html>

<head>

    <title>PDF.js Structured Viewer</title>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.min.js"></script>

    <style>
        body {
            font-family: Arial;
            padding: 20px;
        }

        .page {
            position: relative;
            margin-bottom: 40px;
        }

        .textLayer {
            position: absolute;
            left: 0;
            top: 0;
            right: 0;
            bottom: 0;
            overflow: hidden;
            opacity: 0.2;
            line-height: 1;
        }

        .textLayer span {
            position: absolute;
            white-space: pre;
            transform-origin: 0% 0%;
            color: red;
        }

        canvas {
            border: 1px solid #ccc;
        }

        .debug-box {
            margin-top: 30px;
            padding: 20px;
            background: #f5f5f5;
        }
    </style>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf_viewer.min.css">

    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf_viewer.min.js"></script>
</head>

<body>

    <h2>Upload PDF</h2>

    <form action="{{ route('convert') }}" method="POST" enctype="multipart/form-data">

        @csrf

        <input type="file" id="pdfUpload" name="pdf" accept=".pdf" required>

        <!-- Extracted Data -->

        <input type="hidden" name="company_name" id="company_input">

        <input type="hidden" name="transaction_date" id="date_input">

        <input type="hidden" name="remitter_name" id="name_input">

        <input type="hidden" name="amount" id="amount_input">

        <input type="hidden" name="exchange_rate" id="rate_input">

        <input type="hidden" name="yen_equivalent" id="yen_input">

        <button type="submit">
            Submit
        </button>

    </form>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.min.js"></script>

    <script>

        pdfjsLib.GlobalWorkerOptions.workerSrc =
            'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.16.105/pdf.worker.min.js';

        document.getElementById('pdfUpload')
            .addEventListener('change', async function (e) {

                const file = e.target.files[0];

                if (!file) return;

                const reader = new FileReader();

                reader.onload = async function () {

                    const typedArray =
                        new Uint8Array(this.result);

                    /*
                    |--------------------------------------------------------------------------
                    | Load PDF
                    |--------------------------------------------------------------------------
                    */

                    const loadingTask =
                        pdfjsLib.getDocument({

                            data: typedArray,

                            cMapUrl:
                                window.location.origin +
                                '/pdfjs/cmaps/',

                            cMapPacked: true
                        });

                    const pdf =
                        await loadingTask.promise;

                    let fullText = '';

                    /*
                    |--------------------------------------------------------------------------
                    | Read All Pages
                    |--------------------------------------------------------------------------
                    */

                    for (let pageNum = 1; pageNum <= pdf.numPages; pageNum++) {

                        const page =
                            await pdf.getPage(pageNum);

                        const textContent =
                            await page.getTextContent();

                        /*
                        |--------------------------------------------------------------------------
                        | Preserve PDF Row Structure
                        |--------------------------------------------------------------------------
                        */

                        let lastY = null;

                        textContent.items.forEach(item => {

                            if (!item.str) return;

                            let text =
                                item.str.trim();

                            if (!text) return;

                            /*
                            |--------------------------------------------------------------------------
                            | Ignore Visual Noise
                            |--------------------------------------------------------------------------
                            */

                            const ignoredPatterns = [

                                /^↑$/,
                                /^★$/,
                                /^-$/,
                                /^:$/,
                                /^円$/,
                                /^Page$/,
                                /^1\/1$/,
                                /^\(*\)*$/,
                                /^\d+\/\d+$/
                            ];

                            const shouldIgnore =
                                ignoredPatterns.some(pattern =>
                                    pattern.test(text)
                                );

                            if (shouldIgnore) return;

                            /*
                            |--------------------------------------------------------------------------
                            | Detect New Line Using Y Position
                            |--------------------------------------------------------------------------
                            */

                            const y =
                                item.transform[5];

                            if (
                                lastY !== null
                                &&
                                Math.abs(y - lastY) > 5
                            ) {

                                fullText += '\n';
                            }

                            fullText += text + ' ';

                            lastY = y;
                        });

                        fullText += '\n';
                    }

                    /*
                    |--------------------------------------------------------------------------
                    | Remove Japanese Characters
                    |--------------------------------------------------------------------------
                    */

                    fullText =
                        fullText.replace(

                            /[\u3040-\u30ff\u3400-\u4dbf\u4e00-\u9fff]/g,

                            ''
                        );

                    /*
                    |--------------------------------------------------------------------------
                    | Cleanup Text
                    |--------------------------------------------------------------------------
                    */

                    fullText =
                        fullText

                            .replace(/[（）]/g, '')

                            .replace(/\s+\n/g, '\n')

                            .replace(/\n\s+/g, '\n')

                            .replace(/[ \t]+/g, ' ')

                            .replace(/\n+/g, '\n')

                            .trim();

                    console.log(
                        'FULL TEXT:',
                        fullText
                    );

                    /*
                    |--------------------------------------------------------------------------
                    | Extract Company Name
                    |--------------------------------------------------------------------------
                    */

                    let companyName = '';

                    const companyMatch =
                        fullText.match(
                            /\d{4}-\d{2}-\d{2}\s+\d+\s+([A-Z0-9.,&()'\-\s]+?)\s+\d{6,}/i
                        );

                    if (companyMatch) {

                        companyName =
                            companyMatch[1]

                                .replace(/\s+/g, ' ')

                                .trim();
                    }

                    console.log(
                        'COMPANY:',
                        companyName
                    );

                    /*
                    |--------------------------------------------------------------------------
                    | Extract Date
                    |--------------------------------------------------------------------------
                    */

                    let transactionDate = '';

                    const dateMatch =
                        fullText.match(
                            /\d{4}-\d{2}-\d{2}/
                        );

                    if (dateMatch) {

                        transactionDate =
                            dateMatch[0];
                    }

                    console.log(
                        'DATE:',
                        transactionDate
                    );

                    /*
                    |--------------------------------------------------------------------------
                    | Extract Remitter Block
                    |--------------------------------------------------------------------------
                    */

                    let remitterBlock = '';

                    const remitterRegex =
                        /\/REMITTER([\s\S]*?)\/REMITTING BANK/iu;

                    const remitterMatch =
                        fullText.match(remitterRegex);

                    if (remitterMatch) {

                        remitterBlock =
                            remitterMatch[1]

                                .replace(
                                    /\/REMITTER'S\s*MESSAGE/iu,
                                    ''
                                )

                                .trim();
                    }

                    console.log(
                        'REMITTER BLOCK:',
                        remitterBlock
                    );

                    /*
                    |--------------------------------------------------------------------------
                    | Split Into Lines
                    |--------------------------------------------------------------------------
                    */

                    const remitterLines =

                        remitterBlock

                            .split('\n')

                            .map(line => line.trim())

                            .filter(line => line);

                    console.log(
                        'REMITTER LINES:',
                        remitterLines
                    );

                    /*
                    |--------------------------------------------------------------------------
                    | Cleanup Lines Dynamically
                    |--------------------------------------------------------------------------
                    */

                    const cleanedLines = [];

                    remitterLines.forEach(line => {

                        line = line.trim();

                        if (!line) return;

                        /*
                        |--------------------------------------------------------------------------
                        | Remove long numeric codes
                        |--------------------------------------------------------------------------
                        */

                        line = line

                            .replace(/\b\d{6,}\b/g, '')

                            .replace(/\b20\d{2}\b/g, '')

                            .replace(/\s+/g, ' ')

                            .trim();

                        if (!line) return;

                        cleanedLines.push(line);
                    });

                    console.log(
                        'CLEANED LINES:',
                        cleanedLines
                    );

                    /*
                    |--------------------------------------------------------------------------
                    | Extract Name
                    |--------------------------------------------------------------------------
                    |
                    | If slash exists:
                    |
                    | PAUL CHAWINGA /ROC/...
                    |
                    | take content before slash
                    |--------------------------------------------------------------------------
                    */

                    let remitterName = '';

                    if (cleanedLines.length) {

                        const firstLine =
                            cleanedLines[0];

                        /*
                        |--------------------------------------------------------------------------
                        | If message content exists
                        |--------------------------------------------------------------------------
                        */

                        if (firstLine.includes('/')) {

                            remitterName =

                                firstLine

                                    .split('/')[0]

                                    .trim();

                        } else {

                            remitterName =
                                firstLine.trim();
                        }
                    }

                    console.log(
                        'NAME:',
                        remitterName
                    );

                    /*
                    |--------------------------------------------------------------------------
                    | Extract Address
                    |--------------------------------------------------------------------------
                    */

                    let remitterAddress = '';

                    /*
                    |--------------------------------------------------------------------------
                    | Remaining lines = address
                    |--------------------------------------------------------------------------
                    */

                    const addressLines =
                        cleanedLines.slice(1);

                    remitterAddress =
                        addressLines

                            .join(' ')

                            /*
                            |--------------------------------------------------------------------------
                            | Remove generic message fragments
                            |--------------------------------------------------------------------------
                            */

                            .replace(/\/[A-Z0-9\/._-]+/gi, '')

                            /*
                            |--------------------------------------------------------------------------
                            | Cleanup spaces
                            |--------------------------------------------------------------------------
                            */

                            .replace(/\s+/g, ' ')

                            .trim();

                    console.log(
                        'ADDRESS:',
                        remitterAddress
                    );

                    /*
                    |--------------------------------------------------------------------------
                    | Extract Amount Block
                    |--------------------------------------------------------------------------
                    */

                    let amountBlock = '';

                    const amountRegex =
                        /\/REMIT\.\s*AMT\.([\s\S]*?)\/REMIT\.CHG\./iu;

                    const amountMatch =
                        fullText.match(amountRegex);

                    if (amountMatch) {

                        amountBlock =
                            amountMatch[1]
                                .trim();
                    }

                    console.log(
                        'AMOUNT BLOCK:',
                        amountBlock
                    );

                    /*
                    |--------------------------------------------------------------------------
                    | Extract Numbers
                    |--------------------------------------------------------------------------
                    */

                    const numbers =
                        amountBlock.match(
                            /[\d,]+(?:\.\d+)?/g
                        ) || [];

                    console.log(
                        'NUMBERS:',
                        numbers
                    );

                    /*
                    |--------------------------------------------------------------------------
                    | Final Values
                    |--------------------------------------------------------------------------
                    */

                    let amount = '';

                    let exchangeRate = '';

                    let yenEquivalent = '';

                    /*
                    |--------------------------------------------------------------------------
                    | Amount
                    |--------------------------------------------------------------------------
                    */

                    amount =
                        numbers[0] || '';

                    /*
                    |--------------------------------------------------------------------------
                    | Exchange Rate
                    |--------------------------------------------------------------------------
                    */

                    exchangeRate =
                        numbers.find(n => {

                            return (
                                n.includes('.')
                                &&
                                parseFloat(
                                    n.replace(/,/g, '')
                                ) < 1000
                            );

                        }) || '';

                    /*
                    |--------------------------------------------------------------------------
                    | YEN Equivalent
                    |--------------------------------------------------------------------------
                    */

                    const integerNumbers =
                        numbers.filter(n =>
                            !n.includes('.')
                        );

                    if (integerNumbers.length) {

                        yenEquivalent =
                            integerNumbers

                                .map(n => parseInt(
                                    n.replace(/,/g, '')
                                ))

                                .sort((a, b) => b - a)[0]

                                .toLocaleString();
                    }

                    /*
                    |--------------------------------------------------------------------------
                    | Fill Hidden Inputs
                    |--------------------------------------------------------------------------
                    */

                    document.getElementById('company_input')
                        .value = companyName;

                    document.getElementById('date_input')
                        .value = transactionDate;

                    document.getElementById('name_input')
                        .value = remitterName;

                    document.getElementById('amount_input')
                        .value = amount;

                    document.getElementById('rate_input')
                        .value = exchangeRate;

                    document.getElementById('yen_input')
                        .value = yenEquivalent;

                    /*
                    |--------------------------------------------------------------------------
                    | Optional Debug Output
                    |--------------------------------------------------------------------------
                    */

                    document.getElementById('output')
                        .innerText = fullText;
                };

                reader.readAsArrayBuffer(file);
            });

    </script>

</body>

</html>


<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Smalot\PdfParser\Parser;

class PdfController extends Controller
{
    public function index()
    {
        return view('upload');
    }

    public function convert(Request $request)
    {
        $request->validate([

            'pdf' => 'required|mimes:pdf|max:20480',

            'company_name' => 'nullable|string',

            'transaction_date' => 'nullable|string',

            'remitter_name' => 'nullable|string',

            'amount' => 'nullable|string',

            'exchange_rate' => 'nullable|string',

            'yen_equivalent' => 'nullable|string',
        ]);

        /*
    |--------------------------------------------------------------------------
    | Get Extracted Frontend Data
    |--------------------------------------------------------------------------
    */

        $companyName =
            $request->company_name;

        $transactionDate =
            $request->transaction_date;

        $remitterName =
            $request->remitter_name;

        $amount =
            $request->amount;

        $exchangeRate =
            $request->exchange_rate;

        $yenEquivalent =
            $request->yen_equivalent;

        /*
    |--------------------------------------------------------------------------
    | Return View
    |--------------------------------------------------------------------------
    */

        return view(

            'result',

            compact(

                'companyName',

                'transactionDate',

                'remitterName',

                'amount',

                'exchangeRate',

                'yenEquivalent'
            )
        );
    }
}
