<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>GSTIN Excel Upload and Details Fetch</title>
    <style>
        :root {
            --primary-color: #4a6fa5;
            --secondary-color: #166088;
            --success-color: #28a745;
            --danger-color: #dc3545;
            --warning-color: #ffc107;
            --light-color: #f8f9fa;
            --dark-color: #343a40;
            --background-color: #f5f7fa;
            --border-color: #dee2e6;
        }

        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }

        body {
            background-color: var(--background-color);
            color: var(--dark-color);
            line-height: 1.6;
            padding: 20px;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
        }

        h1, h2 {
            color: var(--primary-color);
            margin-bottom: 20px;
        }

        h1 {
            border-bottom: 2px solid var(--border-color);
            padding-bottom: 10px;
            font-size: 2rem;
        }

        h2 {
            font-size: 1.5rem;
            margin-top: 30px;
        }

        .error-message {
            color: var(--danger-color);
            background-color: rgba(220, 53, 69, 0.1);
            padding: 12px;
            border-radius: 4px;
            margin-bottom: 20px;
            border-left: 4px solid var(--danger-color);
        }

        .upload-form {
            background-color: var(--light-color);
            padding: 20px;
            border-radius: 8px;
            margin-bottom: 30px;
            border: 1px solid var(--border-color);
        }

        .file-input-group {
            display: flex;
            flex-direction: column;
            margin-bottom: 15px;
        }

        .file-input-group label {
            margin-bottom: 8px;
            font-weight: 600;
        }

        .file-input {
            padding: 15px;
            background-color: white;
            border: 2px dashed var(--border-color);
            border-radius: 6px;
            cursor: pointer;
            transition: all 0.3s;
            text-align: center;
        }

        .file-input:hover, .file-input.dragover {
            border-color: var(--primary-color);
            background-color: rgba(74, 111, 165, 0.05);
        }

        .file-input input {
            display: none;
        }

        .file-name {
            margin-top: 10px;
            font-size: 0.9rem;
            color: var(--secondary-color);
        }

        .checkbox-group {
            margin: 15px 0;
            display: flex;
            align-items: center;
        }

        .checkbox-group input {
            margin-right: 10px;
        }

        .btn {
            padding: 10px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-weight: 600;
            transition: all 0.3s;
            font-size: 1rem;
        }

        .btn-primary {
            background-color: var(--primary-color);
            color: white;
        }

        .btn-primary:hover {
            background-color: var(--secondary-color);
        }

        .btn-success {
            background-color: var(--success-color);
            color: white;
        }

        .btn-success:hover {
            background-color: #218838;
        }

        .btn-warning {
            background-color: var(--warning-color);
            color: #212529;
        }

        .btn-warning:hover {
            background-color: #e0a800;
        }

        .data-table-container {
            overflow-x: auto;
            margin-top: 20px;
        }

        table {
            width: 100%;
            border-collapse: collapse;
            margin-bottom: 30px;
            box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1);
        }

        th, td {
            padding: 12px 15px;
            text-align: left;
            border-bottom: 1px solid var(--border-color);
        }

        th {
            background-color: var(--primary-color);
            color: white;
            font-weight: 600;
            position: sticky;
            top: 0;
        }

        tr:nth-child(even) {
            background-color: rgba(0, 0, 0, 0.02);
        }

        tr:hover {
            background-color: rgba(74, 111, 165, 0.05);
        }

        .error-row {
            background-color: rgba(220, 53, 69, 0.1) !important;
        }

        .error-row:hover {
            background-color: rgba(220, 53, 69, 0.2) !important;
        }

        .success-row {
            background-color: rgba(40, 167, 69, 0.1) !important;
        }

        .success-row:hover {
            background-color: rgba(40, 167, 69, 0.2) !important;
        }

        .action-cell {
            text-align: center;
        }

        .action-button {
            padding: 6px 12px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 0.85rem;
            transition: all 0.2s;
        }

        .refresh-button {
            background-color: var(--primary-color);
            color: white;
        }

        .refresh-button:hover {
            background-color: var(--secondary-color);
        }

        .loading {
            position: relative;
            pointer-events: none;
        }

        .loading:after {
            content: "";
            position: absolute;
            width: 16px;
            height: 16px;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            margin: auto;
            border: 3px solid transparent;
            border-top-color: #ffffff;
            border-radius: 50%;
            animation: loading-spinner 1s ease infinite;
        }

        .status-badge {
            display: inline-block;
            padding: 4px 8px;
            border-radius: 4px;
            font-size: 0.85rem;
            font-weight: 600;
        }

        .status-active {
            background-color: rgba(40, 167, 69, 0.2);
            color: #1e7e34;
        }

        .status-inactive {
            background-color: rgba(220, 53, 69, 0.2);
            color: #bd2130;
        }

        .status-pending {
            background-color: rgba(255, 193, 7, 0.2);
            color: #d39e00;
        }

        .note-section {
            background-color: rgba(74, 111, 165, 0.1);
            padding: 15px;
            border-radius: 6px;
            margin-top: 30px;
            border-left: 4px solid var(--primary-color);
        }

        .note-section p {
            margin: 0;
            font-size: 0.9rem;
        }

        .progress-container {
            margin-top: 20px;
            display: none;
        }

        .progress-bar {
            height: 10px;
            background-color: #e9ecef;
            border-radius: 5px;
            margin-bottom: 5px;
            overflow: hidden;
        }

        .progress-bar-fill {
            height: 100%;
            background-color: var(--primary-color);
            border-radius: 5px;
            transition: width 0.3s ease;
            width: 0%;
        }

        .progress-text {
            font-size: 0.85rem;
            color: var(--secondary-color);
        }

        .tabs {
            display: flex;
            margin-bottom: 20px;
            border-bottom: 1px solid var(--border-color);
        }

        .tab {
            padding: 10px 20px;
            cursor: pointer;
            border: 1px solid transparent;
            border-bottom: none;
            margin-right: 5px;
            border-radius: 4px 4px 0 0;
            transition: all 0.3s;
        }

        .tab.active {
            background-color: white;
            border-color: var(--border-color);
            border-bottom: 1px solid white;
            margin-bottom: -1px;
            color: var(--primary-color);
            font-weight: 600;
        }

        .tab:hover:not(.active) {
            background-color: rgba(0, 0, 0, 0.05);
        }

        .tab-content {
            display: none;
        }

        .tab-content.active {
            display: block;
        }

        .summary-section {
            display: flex;
            justify-content: space-between;
            flex-wrap: wrap;
            margin-bottom: 30px;
        }

        .summary-card {
            background-color: white;
            border-radius: 8px;
            padding: 20px;
            flex: 1;
            min-width: 200px;
            margin: 10px;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
            text-align: center;
        }

        .summary-card h3 {
            font-size: 1rem;
            color: var(--dark-color);
            margin-bottom: 10px;
        }

        .summary-card .count {
            font-size: 2rem;
            font-weight: 700;
            color: var(--primary-color);
        }

        .summary-card.error .count {
            color: var(--danger-color);
        }

        .summary-card.success .count {
            color: var(--success-color);
        }

        .empty-state {
            text-align: center;
            padding: 40px 20px;
            color: #6c757d;
        }

        .empty-state .icon {
            font-size: 3rem;
            margin-bottom: 20px;
        }

        @keyframes loading-spinner {
            to {
                transform: rotate(360deg);
            }
        }

        @media (max-width: 768px) {
            .container {
                padding: 15px;
            }

            .summary-section {
                flex-direction: column;
            }

            .summary-card {
                width: 100%;
                margin: 5px 0;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>GSTIN Excel Upload and Details Fetch</h1>
        <div id="error-container" class="error-message" style="display: none;"></div>

        <div class="tabs">
            <div class="tab active" data-tab="upload">Upload Excel</div>
            <div class="tab" data-tab="preview">Preview Data</div>
        </div>

        <div id="upload-tab" class="tab-content active">
            <div class="upload-form">
                <div class="file-input-group">
                    <label for="excel_file">Upload Excel file with GSTIN Numbers:</label>
                    <div class="file-input" id="dropzone">
                        <p>Drag & drop your file here or click to browse</p>
                        <input type="file" id="excel_file" accept=".xls,.xlsx">
                        <div id="file-name" class="file-name"></div>
                    </div>
                </div>

                <div class="checkbox-group">
                    <input type="checkbox" id="reprocess_errors_only" name="reprocess_errors_only" value="1">
                    <label for="reprocess_errors_only">Reprocess error rows only</label>
                </div>

                <button type="button" id="upload-btn" class="btn btn-primary">Upload and Preview</button>
            </div>

            <div id="progress-container" class="progress-container">
                <div class="progress-bar">
                    <div id="progress-bar-fill" class="progress-bar-fill"></div>
                </div>
                <div id="progress-text" class="progress-text">Processing file...</div>
            </div>

            <div class="note-section">
                <p><strong>Note:</strong> The GSTIN numbers should be in the first column (A) starting from row 2 (row 1 is header).</p>
            </div>
        </div>

        <div id="preview-tab" class="tab-content">
            <div id="summary-section" class="summary-section" style="display: none;">
                <div class="summary-card">
                    <h3>Total Records</h3>
                    <div id="total-count" class="count">0</div>
                </div>
                <div class="summary-card success">
                    <h3>Successfully Processed</h3>
                    <div id="success-count" class="count">0</div>
                </div>
                <div class="summary-card error">
                    <h3>Errors</h3>
                    <div id="error-count" class="count">0</div>
                </div>
            </div>

            <div class="data-table-container">
                <table id="preview-table" style="display: none;">
                    <thead>
                        <tr>
                            <th>Action</th>
                            <th>GST Number</th>
                            <th>Status</th>
                            <th>Legal Name</th>
                            <th>Registration Date</th>
                            <th>State</th>
                            <th>Trade Name</th>
                            <th>Address</th>
                            <th>Business Type</th>
                            <th>Nature of Business</th>
                            <th>Last Updated</th>
                        </tr>
                    </thead>
                    <tbody id="preview-table-body">
                        <!-- Data will be added here dynamically -->
                    </tbody>
                </table>

                <div id="empty-state" class="empty-state">
                    <div class="icon">📊</div>
                    <h3>No data to preview</h3>
                    <p>Please upload an Excel file with GSTIN numbers to see the preview here.</p>
                </div>
            </div>

            <div id="process-actions" style="display: none; margin-top: 20px; text-align: center;">
                <button type="button" id="process-all-btn" class="btn btn-success">Process All Pending Records</button>
                <button type="button" id="download-btn" class="btn btn-primary" style="margin-left: 10px;">Download Results</button>
            </div>
        </div>
    </div>

    <script>
        // Mock data for demonstration
        const mockGstData = {
            '27AADCB2230M1ZT': {
                gstNumber: '27AADCB2230M1ZT',
                status: 'Active',
                legalName: 'ABC Corporation Pvt Ltd',
                registrationDate: '12-09-2017',
                state: 'Maharashtra',
                tradeName: 'ABC Corp',
                address: '123, Business Park, Mumbai - 400001',
                businessType: 'Private Limited Company',
                natureOfBusiness: 'Manufacturing, Trading',
                lastUpdated: '2023-06-15'
            },
            '29AAKCS0956G1Z1': {
                status: 'Active',
                gstNumber: '29AAKCS0956G1Z1',
                legalName: 'XYZ Solutions Private Limited',
                registrationDate: '28-07-2017',
                state: 'Karnataka',
                tradeName: 'XYZ Solutions',
                address: '456, Tech Park, Bangalore - 560001',
                businessType: 'Private Limited Company',
                natureOfBusiness: 'IT Services, Consulting',
                lastUpdated: '2023-05-20'
            },
            '24AAACR5055K1Z5': {
                status: 'Cancelled',
                gstNumber: '24AAACR5055K1Z5',
                legalName: 'PQR Industries Ltd',
                registrationDate: '15-08-2017',
                state: 'Gujarat',
                tradeName: 'PQR Industries',
                address: '789, Industrial Area, Ahmedabad - 380015',
                businessType: 'Public Limited Company',
                natureOfBusiness: 'Manufacturing',
                lastUpdated: '2023-04-10'
            },
            '07BBBCE9882F1Z2': {
                error: 'Invalid GSTIN - not found in database'
            },
            '06AABCU9603R1ZV': {
                error: 'Temporary error - please try again later'
            }
        };

        // DOM elements
        const errorContainer = document.getElementById('error-container');
        const fileInput = document.getElementById('excel_file');
        const dropzone = document.getElementById('dropzone');
        const fileNameDisplay = document.getElementById('file-name');
        const uploadBtn = document.getElementById('upload-btn');
        const progressContainer = document.getElementById('progress-container');
        const progressBarFill = document.getElementById('progress-bar-fill');
        const progressText = document.getElementById('progress-text');
        const previewTable = document.getElementById('preview-table');
        const previewTableBody = document.getElementById('preview-table-body');
        const emptyState = document.getElementById('empty-state');
        const processAllBtn = document.getElementById('process-all-btn');
        const downloadBtn = document.getElementById('download-btn');
        const processActions = document.getElementById('process-actions');
        const summarySection = document.getElementById('summary-section');
        const totalCount = document.getElementById('total-count');
        const successCount = document.getElementById('success-count');
        const errorCount = document.getElementById('error-count');
        
        // Tab handling
        const tabs = document.querySelectorAll('.tab');
        const tabContents = document.querySelectorAll('.tab-content');

        tabs.forEach(tab => {
            tab.addEventListener('click', () => {
                const tabId = tab.getAttribute('data-tab');
                
                // Update active tab
                tabs.forEach(t => t.classList.remove('active'));
                tab.classList.add('active');
                
                // Show active content
                tabContents.forEach(content => {
                    content.classList.remove('active');
                    if (content.id === `${tabId}-tab`) {
                        content.classList.add('active');
                    }
                });
            });
        });

        // File upload handling
        fileInput.addEventListener('change', (e) => {
            if (e.target.files.length > 0) {
                const fileName = e.target.files[0].name;
                fileNameDisplay.textContent = fileName;
                dropzone.classList.add('has-file');
            } else {
                fileNameDisplay.textContent = '';
                dropzone.classList.remove('has-file');
            }
        });

        // Drag and drop functionality
        ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
            dropzone.addEventListener(eventName, preventDefaults, false);
        });

        function preventDefaults(e) {
            e.preventDefault();
            e.stopPropagation();
        }

        ['dragenter', 'dragover'].forEach(eventName => {
            dropzone.addEventListener(eventName, () => {
                dropzone.classList.add('dragover');
            }, false);
        });

        ['dragleave', 'drop'].forEach(eventName => {
            dropzone.addEventListener(eventName, () => {
                dropzone.classList.remove('dragover');
            }, false);
        });

        dropzone.addEventListener('drop', (e) => {
            const dt = e.dataTransfer;
            const files = dt.files;
            
            if (files.length > 0) {
                fileInput.files = files;
                const fileName = files[0].name;
                fileNameDisplay.textContent = fileName;
                dropzone.classList.add('has-file');
            }
        });

        // Click to browse
        dropzone.addEventListener('click', () => {
            fileInput.click();
        });

        // Upload and preview functionality
        uploadBtn.addEventListener('click', () => {
            if (!fileInput.files || fileInput.files.length === 0) {
                showError('Please select an Excel file to upload.');
                return;
            }

            const file = fileInput.files[0];
            const fileExtension = file.name.split('.').pop().toLowerCase();
            
            if (fileExtension !== 'xls' && fileExtension !== 'xlsx') {
                showError('Please upload a valid Excel file (.xls or .xlsx).');
                return;
            }

            // Show progress bar
            progressContainer.style.display = 'block';
            let progress = 0;
            
            const progressInterval = setInterval(() => {
                progress += 5;
                if (progress > 90) {
                    clearInterval(progressInterval);
                }
                progressBarFill.style.width = `${progress}%`;
                progressText.textContent = `Processing file... ${progress}%`;
            }, 100);

            // Simulate file processing
            setTimeout(() => {
                clearInterval(progressInterval);
                progressBarFill.style.width = '100%';
                progressText.textContent = 'Processing complete!';
                
                // Generate random GSTIN data for demonstration
                const gstNumberList = [
                    '27AADCB2230M1ZT',
                    '29AAKCS0956G1Z1',
                    '24AAACR5055K1Z5',
                    '07BBBCE9882F1Z2',
                    '06AABCU9603R1ZV',
                    // Generate some random pending records
                    ...Array(5).fill().map(() => generateRandomGSTIN())
                ];
                
                // Display data preview
                displayPreview(gstNumberList);
                
                // Switch to preview tab
                document.querySelector('[data-tab="preview"]').click();
                
                // Hide progress after a delay
                setTimeout(() => {
                    progressContainer.style.display = 'none';
                }, 1000);
            }, 1500);
        });

        // Process individual row
        function processGSTIN(gstinNumber, rowElement) {
            const actionButton = rowElement.querySelector('.action-button');
            actionButton.textContent = 'Processing...';
            actionButton.classList.add('loading');
            actionButton.disabled = true;
            
            // Simulate API call
            setTimeout(() => {
                const result = mockGstData[gstinNumber] || {
                    gstNumber: gstinNumber,
                    status: ['Active', 'Cancelled'][Math.floor(Math.random() * 2)],
                    legalName: `Company ${gstinNumber.substring(0, 5)}`,
                    registrationDate: `${Math.floor(Math.random() * 28) + 1}-${Math.floor(Math.random() * 12) + 1}-201${Math.floor(Math.random() * 9)}`,
                    state: ['Maharashtra', 'Karnataka', 'Gujarat', 'Delhi', 'Tamil Nadu'][Math.floor(Math.random() * 5)],
                    tradeName: `Trade ${gstinNumber.substring(0, 5)}`,
                    address: `${Math.floor(Math.random() * 999) + 1}, Sample Street, City - ${Math.floor(Math.random() * 900000) + 100000}`,
                    businessType: ['Private Limited', 'Public Limited', 'Partnership', 'Proprietorship'][Math.floor(Math.random() * 4)],
                    natureOfBusiness: ['Manufacturing', 'Services', 'Trading', 'Retail', 'Wholesale'][Math.floor(Math.random() * 5)],
                    lastUpdated: `202${Math.floor(Math.random() * 3) + 1}-${Math.floor(Math.random() * 12) + 1}-${Math.floor(Math.random() * 28) + 1}`
                };
                
                // Update row with fetched data
                updateTableRow(rowElement, result);
                
                // Update summary counts
                updateSummaryCounts();
                
                actionButton.classList.remove('loading');
                
                if (result.error) {
                    actionButton.textContent = 'Retry';
                    actionButton.disabled = false;
                    actionButton.classList.remove('btn-primary');
                    actionButton.classList.add('btn-warning');
                } else {
                    actionButton.textContent = 'Processed';
                    actionButton.disabled = true;
                }
            }, 1000);
        }

        // Process all pending records
        processAllBtn.addEventListener('click', () => {
            const pendingRows = document.querySelectorAll('.pending-row');
            if (pendingRows.length === 0) {
                showError('No pending records to process.');
                return;
            }
            
            processAllBtn.textContent = 'Processing...';
            processAllBtn.disabled = true;
            processAllBtn.classList.add('loading');
            
            let processed = 0;
            
            // Process each row with a slight delay between them
            pendingRows.forEach((row, index) => {
                setTimeout(() => {
                    const gstinNumber = row.querySelector('td:nth-child(2)').textContent;
                    processGSTIN(gstinNumber, row);
                    
                    processed++;
                    if (processed === pendingRows.length) {
                        processAllBtn.textContent = 'Process All Pending Records';
                        processAllBtn.disabled = false;
                        processAllBtn.classList.remove('loading');
                    }
                }, index * 300);
            });
        });

        // Download results
        downloadBtn.addEventListener('click', () => {
            // Create a CSV string from table data
            const headers = Array.from(document.querySelectorAll('#preview-table th'))
                .slice(1) // Skip action column
                .map(th => th.textContent)
                .join(',');
            
            const rows = [];
            document.querySelectorAll('#preview-table tbody tr').forEach(row => {
                const rowData = Array.from(row.querySelectorAll('td'))
                    .slice(1) // Skip action column
                    .map(td => `"${td.textContent.replace(/"/g, '""')}"`)
                    .join(',');
                rows.push(rowData);
            });
            
            const csvContent = `${headers}\n${rows.join('\n')}`;
            
            // Create download link
            const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
            const url = URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.setAttribute('href', url);
            link.setAttribute('download', 'gst_details_output.csv');
            link.style.visibility = 'hidden';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        });

        // Helper Functions
        function showError(message) {
            errorContainer.textContent = message;
            errorContainer.style.display = 'block';
            
            // Auto hide after 5 seconds
            setTimeout(() => {
                errorContainer.style.display = 'none';
            }, 5000);
        }

        function displayPreview(gstinList) {
            // Clear existing data
            previewTableBody.innerHTML = '';
            
            if (gstinList.length === 0) {
                previewTable.style.display = 'none';
                emptyState.style.display = 'block';
                processActions.style.display = 'none';
                summarySection.style.display = 'none';
                return;
            }
            
            // Add rows for each GSTIN
            gstinList.forEach(gstin => {
                const row = document.createElement('tr');
                row.className = 'pending-row';
                
                // Create cells
                const cells = [
                    `<td class="action-cell"><button class="action-button refresh-button" data-gstin="${gstin}">Process</button></td>`,
                    `<td>${gstin}</td>`,
                    `<td>Pending</td>`,
                    `<td></td>`,
                    `<td></td>`,
                    `<td></td>`,
                    `<td></td>`,
                    `<td></td>`,
                    `<td></td>`,
                    `<td></td>`,
                    `<td></td>`
                ];
                
                row.innerHTML = cells.join('');
                previewTableBody.appendChild(row);
            });
            
            // Add event listeners to process buttons
            document.querySelectorAll('.action-button').forEach(button => {
                button.addEventListener('click', (e) => {
                    const gstin = e.target.getAttribute('data-gstin');
                    const row = e   complete the code