Thursday, September 18, 2025

Complete Guide to Enhanced Indian Invoice System

๐Ÿ‡ฎ๐Ÿ‡ณ Enhanced Indian Invoice System

Your Complete Guide to Professional Invoice Management

๐ŸŽฏ System Overview

The Enhanced Indian Invoice System is a comprehensive web-based solution designed specifically for Indian businesses. It provides all the tools you need to manage invoices, inventory, customers, and sales analytics in one powerful platform.

๐Ÿ“‹ Invoice Generation

Create professional invoices with GST compliance, multiple tax rates, discounts, and custom branding. Supports HSN/SAC codes and Indian tax regulations.

Essential

๐Ÿ“ฆ Stock Management

Track inventory levels, set up products with barcodes, manage pricing, and get low-stock alerts. Perfect for retail and wholesale businesses.

Pro

๐Ÿ‘ฅ Customer Database

Maintain detailed customer records with contact information, purchase history, and automated data filling for faster invoice creation.

Essential

๐Ÿ“Š Sales Dashboard

Get insights into your business performance with revenue tracking, top products analysis, and customer analytics.

Analytics

๐Ÿ“ฑ WhatsApp Integration

Send invoices directly via WhatsApp with custom messages and PDF attachments. Perfect for Indian market communication.

Advanced

๐Ÿ’พ Backup & Restore

Secure your data with comprehensive backup options and easy restoration features. Never lose your business data.

Security

๐Ÿš€ Getting Started

๐ŸŒŸ Quick Start Guide

Follow these simple steps to get your invoice system running in under 5 minutes!

  1. Open the Application: Save the HTML file and open it in any modern web browser (Chrome, Firefox, Safari, or Edge recommended).
  2. Set Up Company Information: Navigate to the Invoice Generator tab and enter your company details including name, address, and contact information.
  3. Add Your Logo: Upload your company logo and position it on invoices using the drag-and-drop interface.
  4. Create Your First Customer: Go to Customer Database and add your first customer with contact details.
  5. Add Products to Inventory: Switch to Stock Management and add your products with prices, GST rates, and descriptions.
  6. Generate Your First Invoice: Return to Invoice Generator, select a customer, add items, and create your professional invoice!

๐Ÿ’ก Pro Tip

The system automatically saves all your data in your browser's local database. No internet connection required after the initial load, making it perfect for offline use!

๐Ÿ“‹ Invoice Generator

๐Ÿข Company Setup

Start by configuring your company information. This data will appear on all your invoices:

  • Company Name: Enter your business name exactly as it appears on official documents.
  • Company Address: Include your complete business address with PIN code for GST compliance.
  • Contact Information: Add email, phone numbers, and website. Format example: "Email: info@company.com\nPhone: +91 9037393709"

๐Ÿ–ผ️ Logo Management

  1. Upload Image: Click "Upload Logo" and select your company logo (PNG, JPG supported).
  2. Initial Sizing: The logo will appear at 100x100 pixels by default.
  3. Positioning: Click and drag the logo to your desired position on the invoice.
  1. Drag to Move: Click and drag the logo anywhere on the invoice.
  2. Resize with Handles: Click the logo to show resize handles, then drag corners to resize.
  3. Precise Sizing: Use width/height inputs for exact pixel dimensions.
  4. Lock Aspect Ratio: Keep proportions locked to prevent distortion.

๐Ÿ“ Logo Best Practices

  • Use high-resolution images (minimum 200x200 pixels)
  • PNG format with transparent background works best
  • Keep logo size between 80-150 pixels for professional appearance
  • Position in top-left or top-center for maximum impact

๐Ÿ‘ค Customer Information

The system includes powerful autocomplete features to speed up invoice creation:

๐Ÿ” Smart Autocomplete

Start typing a customer's contact number or name, and the system will suggest matching customers from your database.

๐Ÿš€ Auto-Fill

Select a customer and watch as name, email, address, and WhatsApp number populate automatically with visual confirmation.

๐Ÿ“ฆ Adding Items

The items section is the heart of your invoice. Here's how to use it effectively:

  1. HSN/SAC Code: Enter the tax classification code. The system will suggest items from your inventory as you type.
  2. Description: Product or service description. Auto-fills when you select from inventory.
  3. Quantity & Unit: Specify quantity and unit of measurement (PCS, KG, LTR, etc.).
  4. Rate: Price per unit. Auto-populated from inventory but can be manually adjusted.
  5. Discount: Choose between percentage (%) or fixed amount (₹) discount.
  6. GST Rates: SGST and CGST percentages (typically 9% each for 18% total GST).
  7. Total Calculation: Automatically calculated as you type with real-time validation.

⚠️ Important Validations

The system prevents common errors:

  • Quantity cannot exceed available stock
  • Percentage discount cannot exceed 100%
  • Fixed discount cannot exceed item subtotal
  • All validations show visual feedback with red borders

๐ŸŽ›️ Invoice Actions

๐Ÿ“‹ Browse Items

Open a searchable dialog showing all inventory items. Click any item to add it to the invoice instantly.

๐Ÿ” Scan Barcode

Use your device's camera to scan product barcodes and automatically add items to the invoice.

๐Ÿ’พ Save Invoice

Saves the invoice to database and updates inventory quantities. Generates unique invoice numbers automatically.

๐Ÿงน Clear Screen

Reset the entire form while keeping your company settings. Perfect for starting a new invoice quickly.

๐Ÿ“ฆ Stock Management

Efficiently manage your inventory with comprehensive product information and stock tracking.

➕ Adding Products

  1. Item Code: Create unique identifiers (e.g., ITM001, MOUSE-01). Used for quick search and identification.
  2. HSN/SAC Code: Tax classification code required for GST compliance (e.g., 8471 for computer peripherals).
  3. Description: Detailed product description that will appear on invoices.
  4. Pricing & Units: Set rate per unit and select appropriate unit of measurement.
  5. GST Configuration: Set SGST and CGST rates (typically 9% each for 18% total).
  6. Discount Settings: Configure default discounts as percentage or fixed amount.
  7. Stock Quantity: Current available quantity for inventory tracking.
  8. Barcode: Optional barcode for quick scanning and identification.

๐Ÿ“Š Stock Level Monitoring

Items with quantity below 10 units appear in red text, helping you identify low-stock situations quickly. Set up a reorder system based on these alerts.

✏️ Managing Existing Stock

Edit Items

Click "Edit" to modify any product details. The form pre-fills with current data for easy updates.

Delete Items

Remove products with confirmation dialog to prevent accidental deletion of important inventory data.

Bulk Operations

Use backup and restore features for bulk inventory updates via JSON files.

๐Ÿ” Barcode Integration

The system supports barcode scanning for both adding inventory and creating invoices:

  • Scan for Stock: Click the scan button next to barcode field to use your camera for barcode input.
  • Supported Formats: EAN, UPC, Code 128, Code 39, and EAN-8 barcodes are supported.
  • Invoice Integration: Scanned items automatically populate invoice fields when adding items.

๐Ÿ‘ฅ Customer Database

Maintain comprehensive customer records to streamline invoice creation and track customer relationships.

๐Ÿ‘ค Adding Customers

  1. Contact Number: Primary identifier (include country code: +91 for India). Must be unique.
  2. Customer Name: Full legal name or business name as it should appear on invoices.
  3. Email Address: For sending digital invoices and communication.
  4. Address: Complete address including city, state, and PIN code for delivery and compliance.

๐Ÿ“Š Customer Management Features

๐Ÿ” Quick Search

Search customers by phone number or name with instant autocomplete suggestions.

✏️ Edit Records

Update customer information with inline editing. Changes reflect immediately in invoice autocomplete.

๐Ÿ“œ Purchase History

View complete transaction history for each customer with expandable invoice details.

๐Ÿ”— Integration

Customer data automatically populates invoice fields, WhatsApp numbers, and delivery information.

๐Ÿš€ Productivity Boost

A well-maintained customer database can reduce invoice creation time by up to 70%. The autocomplete feature eliminates repetitive data entry and reduces errors.

๐Ÿ“Š Sales Dashboard

Get powerful insights into your business performance with comprehensive analytics and reporting.

๐Ÿ“ˆ Key Metrics

๐Ÿ’ฐ Total Revenue

Track total income over selected time periods with trend analysis and growth indicators.

๐Ÿ“‹ Order Count

Monitor invoice volume to understand business activity and seasonal patterns.

๐Ÿ‘ฅ Active Customers

Count unique customers who made purchases in the selected period.

๐Ÿ“ฆ Products Sold

Track total quantity of items sold across all invoices and categories.

๐Ÿ’ธ Discount Analytics

Monitor total discounts given to understand pricing strategy impact.

๐ŸŽฏ Advanced Analytics

  1. Date Range Filtering: Choose from preset ranges (7, 30, 90, 365 days) or set custom date ranges for precise analysis.
  2. Top Products Analysis: Identify best-selling items by quantity to optimize inventory and marketing efforts.
  3. Recent Orders View: Quick access to latest invoices with customer details and amounts for follow-up actions.
  4. Customer Insights: Click on customer names to jump directly to their purchase history for detailed analysis.

๐Ÿ“Š Using Analytics for Growth

Regular dashboard review helps identify trends, peak sales periods, and customer preferences. Use this data to make informed decisions about inventory, pricing, and customer outreach.

๐Ÿ”ง Advanced Features

๐Ÿ“ฑ WhatsApp Integration

Send professional invoices directly through WhatsApp with customized messages:

Multiple Code Blocks

Here is the code

Click or Tap to Copy

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Complete Invoice System</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.5.23/jspdf.plugin.autotable.min.js"></script>
  <script src="https://unpkg.com/dexie@latest/dist/dexie.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/quagga/1.0.0/quagga.min.js"></script>
  <style>
    * { box-sizing: border-box; }
    body { 
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 
      margin: 0; 
      padding: 20px; 
      background: #f5f5f5; 
      touch-action: manipulation; 
    }

    .container { max-width: 1400px; margin: auto; }

    /* Navigation Menu Styles */
    .nav-menu {
      background: linear-gradient(135deg, #007bff, #0056b3);
      padding: 15px 20px;
      margin-bottom: 20px;
      border-radius: 8px;
      box-shadow: 0 4px 6px rgba(0,0,0,0.1);
    }
    .nav-menu h2 {
      color: white;
      margin: 0 0 15px 0;
      text-align: center;
    }
    .nav-buttons {
      display: flex;
      gap: 15px;
      justify-content: center;
      flex-wrap: wrap;
    }
    .nav-btn {
      background: rgba(255,255,255,0.2);
      color: white;
      border: 2px solid rgba(255,255,255,0.3);
      padding: 12px 24px;
      border-radius: 6px;
      cursor: pointer;
      font-weight: bold;
      transition: all 0.3s;
      backdrop-filter: blur(10px);
    }
    .nav-btn:hover {
      background: rgba(255,255,255,0.3);
      transform: translateY(-2px);
    }
    .nav-btn.active {
      background: white;
      color: #007bff;
      border-color: white;
    }

    .section { display: none; }
    .section.active { display: block; }
    .input-section { 
      background: white; 
      padding: 20px; 
      margin-bottom: 20px; 
      border-radius: 8px; 
      box-shadow: 0 2px 5px rgba(0,0,0,0.1);
    }
    .invoice-preview { 
      background: white; 
      padding: 0; 
      border-radius: 8px; 
      box-shadow: 0 2px 5px rgba(0,0,0,0.1); 
    }

    h3 { margin-top: 0; color: #333; border-bottom: 2px solid #007bff; padding-bottom: 10px; }

    .form-row { display: flex; gap: 15px; margin-bottom: 15px; flex-wrap: wrap; }
    .form-group { flex: 1; min-width: 200px; position: relative; }
    .form-group label { display: block; margin-bottom: 5px; font-weight: bold; color: #555; }
    .form-group input, .form-group textarea, .form-group select { 
      width: 100%; 
      padding: 10px; 
      border: 1px solid #ddd; 
      border-radius: 4px; 
      font-size: 14px;
    }
    .form-group textarea { resize: vertical; height: 80px; }

    .auto-populated {
      background-color: #e8f5e8 !important;
      border-color: #28a745 !important;
      transition: background-color 0.5s ease;
    }

    .dropdown {
      position: absolute;
      top: 100%;
      left: 0;
      right: 0;
      background: white;
      border: 1px solid #ddd;
      border-top: none;
      max-height: 200px;
      overflow-y: auto;
      z-index: 1000;
      display: none;
      box-shadow: 0 4px 6px rgba(0,0,0,0.1);
    }
    .dropdown-item {
      padding: 10px;
      cursor: pointer;
      border-bottom: 1px solid #eee;
    }
    .dropdown-item:hover {
      background: #f5f5f5;
    }

    .items-section { margin-top: 20px; }
    .items-table { 
      width: 100%; 
      border-collapse: collapse; 
      background: #f8f9fa; 
      border-radius: 5px; 
      overflow: hidden;
    }
    .items-table th, .items-table td { 
      padding: 10px; 
      border: 1px solid #ddd; 
      text-align: left; 
      font-size: 14px;
    }
    .items-table th { 
      background: #e9ecef; 
      font-weight: bold; 
      color: #333;
    }
    .items-table input, .items-table select { 
      width: 100%; 
      padding: 8px; 
      border: 1px solid #ccc; 
      border-radius: 4px; 
      font-size: 14px;
    }
    .items-table .code-input { min-width: 100px; }
    .items-table .desc-input { min-width: 200px; }
    .items-table .qty-input, .items-table .rate-input, .items-table .sgst-input, .items-table .cgst-input, .items-table .total-input { min-width: 80px; }
    .items-table .disc-type-select { min-width: 60px; }
    .items-table .disc-input { min-width: 80px; }
    .items-table .unit-select { min-width: 80px; }
    .items-table .total-input {
      background: #f0f0f0;
      text-align: right;
      pointer-events: none;
    }
    .items-table .remove-btn { 
      background: #dc3545; 
      color: white; 
      border: none; 
      padding: 8px 12px; 
      border-radius: 4px; 
      cursor: pointer; 
      width: 100%;
    }
    .items-table .remove-btn:hover { background: #c82333; }

    .add-item-btn, .generate-btn, .browse-items-btn, .add-stock-btn, .add-customer-btn, 
    .backup-btn, .restore-btn, .save-btn, .export-csv-btn, .search-customer-btn { 
      background: #28a745; 
      color: white; 
      border: none; 
      padding: 12px 20px; 
      border-radius: 5px; 
      cursor: pointer; 
      margin-right: 10px; 
      margin-top: 10px;
      font-weight: bold;
      transition: all 0.3s;
    }
    .add-item-btn:hover, .add-stock-btn:hover, .add-customer-btn:hover, 
    .backup-btn:hover, .restore-btn:hover, .save-btn:hover, .export-csv-btn:hover, .search-customer-btn:hover { 
      background: #218838; 
      transform: translateY(-2px);
    }
    .browse-items-btn { background: #17a2b8; }
    .browse-items-btn:hover { background: #138496; }
    .generate-btn { background: #007bff; }
    .generate-btn:hover { background: #0056b3; }
    .save-btn { background: #ffc107; color: #333; }
    .save-btn:hover { background: #e0a800; }
    .export-csv-btn { background: #17a2b8; }
    .export-csv-btn:hover { background: #138496; }

    .stock-table, .customer-table, .customer-history-table {
      width: 100%;
      border-collapse: collapse;
      margin-top: 20px;
    }
    .stock-table th, .stock-table td, .customer-table th, .customer-table td, .customer-history-table th, .customer-history-table td {
      border: 1px solid #ddd;
      padding: 12px;
      text-align: left;
    }
    .stock-table th, .customer-table th, .customer-history-table th {
      background: #f8f9fa;
      font-weight: bold;
    }
    .stock-table tr:hover, .customer-table tr:hover, .customer-history-table tr:hover {
      background: #f5f5f5;
    }
    .customer-history-table .items-details {
      display: none;
      background: #f8f9fa;
    }
    .customer-history-table .items-details.active {
      display: table-row;
    }

    .edit-btn, .delete-btn, .toggle-items-btn {
      padding: 6px 12px;
      margin: 2px;
      border: none;
      border-radius: 3px;
      cursor: pointer;
      font-size: 12px;
    }
    .edit-btn { background: #ffc107; color: #333; }
    .edit-btn:hover { background: #e0a800; }
    .delete-btn { background: #dc3545; color: white; }
    .delete-btn:hover { background: #c82333; }
    .toggle-items-btn { background: #17a2b8; color: white; }
    .toggle-items-btn:hover { background: #138496; }

    .low-stock {
      color: #dc3545;
      font-weight: bold;
    }

    .quantity-error, .disc-error {
      border: 2px solid #dc3545 !important;
      background-color: #fff3f3 !important;
    }

    /* Invoice Styles */
    .invoice-box {
      max-width: 700px; 
      margin: auto; 
      padding: 20px;
      border: 1px solid #ddd; 
      border-radius: 8px; 
      background: white;
      position: relative;
    }
    .company-header {
      text-align: center; 
      margin-bottom: 20px;
    }
    .company-header h2 { margin: 0; color: #333; }
    .company-header p { margin: 2px 0; font-size: 13px; color: #666; }
    .header { display: flex; justify-content: space-between; margin-bottom: 20px; }
    .bill-to { font-size: 14px; }
    .invoice-details { text-align: right; font-size: 14px; }
    .invoice-table { 
      width: 100%; 
      border-collapse: collapse; 
      margin-top: 20px; 
    }
    .invoice-table, .invoice-table th, .invoice-table td { border: 1px solid #ccc; }
    .invoice-table th, .invoice-table td { padding: 8px; text-align: left; }
    .invoice-table th { background: #f8f9fa; }
    .total { text-align: right; font-weight: bold; margin-top: 10px; font-size: 16px; }
    .print-btn { 
      margin-top: 20px; 
      padding: 10px 20px; 
      background: #007bff; 
      color: #fff; 
      border: none; 
      cursor: pointer; 
      border-radius: 5px; 
      font-weight: bold;
    }
    .print-btn:hover { background: #0056b3; }

    /* Logo Styles */
    .invoice-logo {
      position: absolute;
      top: 20px;
      left: 20px;
      z-index: 10;
      cursor: move;
      user-select: none;
      -webkit-user-select: none;
      touch-action: none;
    }
    .invoice-logo img {
      width: 100%;
      height: 100%;
      object-fit: contain;
    }
    .invoice-logo.active {
      border: 2px dashed #007bff;
    }
    .resize-handle {
      position: absolute;
      width: 12px;
      height: 12px;
      background: #007bff;
      border-radius: 50%;
      display: none;
    }
    .invoice-logo.active .resize-handle {
      display: block;
    }
    .resize-handle.top-left {
      top: -6px;
      left: -6px;
      cursor: nwse-resize;
    }
    .resize-handle.top-right {
      top: -6px;
      right: -6px;
      cursor: nesw-resize;
    }
    .resize-handle.bottom-left {
      bottom: -6px;
      left: -6px;
      cursor: nesw-resize;
    }
    .resize-handle.bottom-right {
      bottom: -6px;
      right: -6px;
      cursor: nwse-resize;
    }
    .logo-controls {
      margin-top: 20px;
      display: flex;
      flex-wrap: wrap;
      gap: 10px;
      align-items: center;
    }
    .logo-controls input[type="number"] {
      width: 80px;
      padding: 6px;
      border: 1px solid #ddd;
      border-radius: 4px;
    }
    .logo-controls button {
      padding: 8px 16px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 14px;
    }
    .reset-logo-btn {
      background: #6c757d;
      color: white;
    }
    .reset-logo-btn:hover {
      background: #5a6268;
    }
    .remove-logo-btn {
      background: #dc3545;
      color: white;
    }
    .remove-logo-btn:hover {
      background: #c82333;
    }

    /* Floating Dialog Styles */
    .dialog-overlay {
      position: fixed; 
      top: 0; 
      left: 0; 
      width: 100%; 
      height: 100%;
      background: rgba(0, 0, 0, 0.5); 
      z-index: 1000; 
      display: none;
      align-items: center;
      justify-content: center;
    }
    .dialog {
      background: white; 
      border-radius: 12px; 
      padding: 0; 
      width: 90%;
      max-width: 600px; 
      min-width: 300px; 
      max-height: 80vh; 
      min-height: 200px;
      overflow: hidden; 
      box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
      position: relative;
    }
    .dialog-header {
      display: flex; 
      justify-content: space-between; 
      align-items: center;
      padding: 15px 20px 10px 20px; 
      border-bottom: 2px solid #e9ecef;
      background: #f8f9fa; 
      -webkit-user-select: none; 
      user-select: none;
      touch-action: none;
    }
    .dialog-controls { 
      display: flex; 
      align-items: center; 
      gap: 10px; 
      flex-wrap: wrap; 
    }
    .size-inputs { 
      display: flex; 
      gap: 5px; 
      align-items: center; 
      margin-right: 10px; 
    }
    .size-input { 
      width: 60px; 
      padding: 2px 5px; 
      border: 1px solid #ddd; 
      border-radius: 3px; 
      font-size: 0.8rem; 
      text-align: center; 
    }
    .resize-btn, .apply-btn { 
      border: none; 
      padding: 4px 8px; 
      border-radius: 4px; 
      cursor: pointer; 
      font-size: 0.8rem; 
    }
    .resize-btn { 
      background: #6c757d; 
      color: white; 
      font-weight: 600; 
    }
    .resize-btn:hover { background: #5a6268; }
    .apply-btn { background: #007bff; color: white; }
    .apply-btn:hover { background: #0056b3; }
    .dialog-header h3 { color: #495057; margin: 0; border: none; }
    .close-btn {
      background: none; 
      border: none; 
      font-size: 1.5rem; 
      cursor: pointer;
      color: #6c757d; 
      padding: 5px; 
      border-radius: 50%; 
      width: 35px; 
      height: 35px;
      display: flex; 
      align-items: center; 
      justify-content: center;
    }
    .close-btn:hover { background: #f8f9fa; color: #495057; }
    .search-section { margin-bottom: 20px; padding: 0 20px; }
    .search-input {
      width: 100%; 
      padding: 12px; 
      border: 2px solid #dee2e6; 
      border-radius: 8px; 
      font-size: 1rem;
    }
    .search-input:focus { 
      outline: none; 
      border-color: #4facfe; 
      box-shadow: 0 0 0 3px rgba(79, 172, 254, 0.1); 
    }
    .items-container {
      max-height: calc(100% - 150px); 
      overflow-y: auto; 
      border: 1px solid #dee2e6;
      border-radius: 8px; 
      margin: 0 20px 20px 20px;
    }
    .item-table { width: 100%; border-collapse: collapse; }
    .item-table th, .item-table td { 
      padding: 10px; 
      text-align: left; 
      border-bottom: 1px solid #dee2e6; 
    }
    .item-table th { 
      background: #f8f9fa; 
      position: sticky; 
      top: 0; 
      font-weight: 600; 
      color: #495057; 
    }
    .item-table tbody tr { 
      cursor: pointer; 
      transition: background-color 0.2s ease; 
    }
    .item-table tbody tr:hover { background-color: #e3f2fd; }
    .status-message {
      padding: 10px; 
      margin: 10px 20px; 
      border-radius: 6px; 
      font-size: 0.9rem; 
      display: none;
    }
    .status-success { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
    .status-error { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }

    @media print {
      body { background: white; }
      .input-section, .nav-menu { display: none; }
      .invoice-preview { box-shadow: none; }
      .dialog-overlay { display: none !important; }
      .invoice-logo.active { border: none !important; }
      .resize-handle { display: none !important; }
    }
    @media (max-width: 768px) {
      .form-row { flex-direction: column; }
      .items-section, .stock-table, .customer-table, .customer-history-table { 
        overflow-x: auto; 
        display: block;
      }
      .items-table th, .items-table td { min-width: 60px; }
      .items-table .desc-input { min-width: 120px; }
      .items-table .remove-btn { min-width: 80px; }
      .dialog { width: 90%; min-width: 250px; max-width: 95vw; }
      .dialog-header { padding: 10px 15px; }
      .size-input { width: 50px; font-size: 0.7rem; }
      .resize-btn, .apply-btn { padding: 3px 6px; font-size: 0.7rem; }
      .nav-buttons { flex-direction: column; align-items: center; }
      .nav-btn { width: 200px; }
      .logo-controls input[type="number"] { width: 60px; }
    }
    @media (max-width: 480px) {
      .dialog { min-height: 150px; }
      .items-container { max-height: calc(100% - 120px); }
      .items-table th, .items-table td, .stock-table th, .stock-table td, .customer-table th, .customer-table td, .customer-history-table th, .customer-history-table td { 
        font-size: 12px; 
        padding: 6px; 
      }
      .items-table input, .items-table select { font-size: 12px; padding: 4px; }
      .item-table th, .item-table td { font-size: 12px; padding: 6px; }
      .resize-handle { width: 10px; height: 10px; }
    }
    .hidden { display: none; }
    .whatsapp-section {
      background: #e8f5e8;
      padding: 15px;
      border-radius: 5px;
      margin-top: 20px;
      border-left: 4px solid #25d366;
    }
    .whatsapp-section h3 {
      color: #333;
      border-bottom: 2px solid #25d366;
    }
    .btn-whatsapp {
      background: #25d366;
      color: white;
      padding: 10px 20px;
      border: none;
      border-radius: 5px;
      cursor: pointer;
      font-weight: bold;
      transition: all 0.3s;
    }
    .btn-whatsapp:hover {
      background: #20c360;
      transform: translateY(-2px);
    }
    .whatsapp-preview {
      max-height: 200px;
      overflow-y: auto;
      border: 1px solid #ddd;
      margin-top: 15px;
      padding: 10px;
      background: #f8f9fa;
      border-radius: 4px;
      white-space: pre-wrap;
      font-family: monospace;
      display: none;
    }
    .pdf-btn {
      background: #007bff;
      color: white;
      padding: 10px 20px;
      border: none;
      border-radius: 5px;
      cursor: pointer;
      margin-right: 10px;
      margin-top: 10px;
    }
    .pdf-btn:hover {
      background: #0056b3;
    }
    .pdf-btn.share {
      background: linear-gradient(135deg, #17a2b8, #20c997);
    }
    /* Dashboard Styles */
    .stats-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      gap: 20px;
      margin-bottom: 20px;
    }
    .dashboard-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
      gap: 20px;
    }
    .dashboard-card {
      background: white;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 2px 5px rgba(0,0,0,0.1);
      transition: transform 0.3s, box-shadow 0.3s;
    }
    .dashboard-card:hover {
      transform: translateY(-5px);
      box-shadow: 0 4px 10px rgba(0,0,0,0.2);
    }
    .dashboard-card h4 {
      margin: 0 0 10px;
      color: #333;
      font-size: 1.1rem;
    }
    .dashboard-card p {
      margin: 0;
      font-size: 1.5rem;
      font-weight: bold;
      color: white;
    }
    .top-products-list, .recent-orders-list {
      max-height: 200px;
      overflow-y: auto;
      margin-top: 10px;
    }
    .top-products-list div, .recent-orders-list div {
      padding: 10px;
      border-bottom: 1px solid #eee;
      display: flex;
      justify-content: space-between;
      align-items: center;
      cursor: pointer;
      transition: background 0.2s;
    }
    .top-products-list div:hover, .recent-orders-list div:hover {
      background: #f5f5f5;
    }
    .refresh-btn {
      background: #007bff;
      color: white;
      border: none;
      padding: 10px 20px;
      border-radius: 5px;
      cursor: pointer;
      margin-top: 10px;
    }
    .refresh-btn:hover {
      background: #0056b3;
    }
    @media (max-width: 768px) {
      .stats-grid, .dashboard-grid {
        grid-template-columns: 1fr;
      }
    }
    .scan-btn {
      background: #ffc107;
      color: #333;
      border: none;
      padding: 12px 20px;
      border-radius: 5px;
      cursor: pointer;
      margin-right: 10px;
      margin-top: 10px;
      font-weight: bold;
      transition: all 0.3s;
    }
    .scan-btn:hover {
      background: #e0a800;
      transform: translateY(-2px);
    }
  </style>
</head>
<body>
<div class="container">
  <!-- Navigation Menu -->
  <div class="nav-menu">
    <h2>๐Ÿ‡ฎ๐Ÿ‡ณ Enhanced Indian Invoice System</h2>
    <div class="nav-buttons">
      <button class="nav-btn active" data-section="invoice">๐Ÿ“‹ Invoice Generator</button>
      <button class="nav-btn" data-section="dashboard">๐Ÿ“Š Sales Dashboard</button>
      <button class="nav-btn" data-section="stock">๐Ÿ“ฆ Stock Management</button>
      <button class="nav-btn" data-section="customers">๐Ÿ‘ฅ Customer Database</button>
      <button class="nav-btn" data-section="customer-history">๐Ÿ“œ Customer History</button>
      <button class="nav-btn" data-section="backup-restore">๐Ÿ’พ Backup & Restore</button>
    </div>
  </div>

  <!-- Sales Dashboard Section -->
  <div class="section" id="dashboard">
    <div class="input-section">
      <h3>๐Ÿ“Š Sales Dashboard</h3>
      <div class="form-row">
        <div class="form-group">
          <label>Date Range</label>
          <select id="dateRangeFilter" onchange="toggleCustomDateRange()">
            <option value="7">Last 7 days</option>
            <option value="30">Last 30 days</option>
            <option value="90">Last 90 days</option>
            <option value="365">Last 365 days</option>
            <option value="custom">Custom Range</option>
          </select>
        </div>
        <div class="form-group hidden" id="customDateRange">
          <label>From</label>
          <input type="date" id="fromDate">
          <label>To</label>
          <input type="date" id="toDate">
        </div>
        <div class="form-group">
          <button class="refresh-btn" onclick="updateDashboard()">Refresh</button>
          <button class="refresh-btn" onclick="clearInvoices()">Clear Invoices</button>
        </div>
      </div>
      <div class="stats-grid">
        <div class="dashboard-card" style="background: linear-gradient(135deg, #28a745, #218838);">
          <h4>Total Revenue</h4>
          <p id="totalRevenue">₹0.00</p>
        </div>
        <div class="dashboard-card" style="background: linear-gradient(135deg, #007bff, #0056b3);">
          <h4>Total Orders</h4>
          <p id="totalOrders">0</p>
        </div>
        <div class="dashboard-card" style="background: linear-gradient(135deg, #ff4d4f, #cf1322);">
          <h4>Active Customers</h4>
          <p id="totalCustomers">0</p>
        </div>
        <div class="dashboard-card" style="background: linear-gradient(135deg, #17a2b8, #117a8b);">
          <h4>Products Sold</h4>
          <p id="totalProducts">0</p>
        </div>
        <div class="dashboard-card" style="background: linear-gradient(135deg, #ffc107, #e0a800);">
          <h4>Total Discounts</h4>
          <p id="totalDiscount">₹0.00</p>
        </div>
      </div>
      <div class="dashboard-grid">
        <div class="dashboard-card">
          <h4>Top Selling Products</h4>
          <div class="top-products-list" id="topProductsList"></div>
        </div>
        <div class="dashboard-card">
          <h4>Recent Orders</h4>
          <div class="recent-orders-list" id="recentOrdersList"></div>
        </div>
      </div>
    </div>
  </div>

  <!-- Invoice Generator Section -->
  <div class="section active" id="invoice">
    <div class="input-section">
      <h3>๐Ÿ“ Invoice Generator</h3>
      <!-- Company Info -->
      <div class="form-row">
        <div class="form-group">
          <label>Company Name</label>
          <input type="text" id="companyName" value="Your Company Name">
        </div>
      </div>
      <div class="form-row">
        <div class="form-group">
          <label>Company Address</label>
          <textarea id="companyAddress">123 Business Street, City, State - ZIP</textarea>
        </div>
        <div class="form-group">
          <label>Contact Info</label>
          <textarea id="companyContact">Email: info@company.com
Phone: +91 9037393709</textarea>
        </div>
      </div>
      <!-- Logo Upload -->
      <h3>๐Ÿ–ผ️ Logo</h3>
      <div class="form-row">
        <div class="form-group">
          <label>Upload Logo</label>
          <input type="file" id="logoUpload" accept="image/*">
        </div>
        <div class="form-group logo-controls">
          <label>Width (px)</label>
          <input type="number" id="logoWidth" min="20" max="300" placeholder="Width">
          <label>Height (px)</label>
          <input type="number" id="logoHeight" min="20" max="300" placeholder="Height">
          <label><input type="checkbox" id="lockAspectRatio" checked> Lock Aspect Ratio</label>
          <button class="reset-logo-btn" onclick="resetLogoPosition()">Reset Position</button>
          <button class="remove-logo-btn" onclick="removeLogo()">Remove Logo</button>
        </div>
      </div>
      <p style="font-size: 12px; color: #666;">Tip: Tap logo to show handles, drag to move, or tap handles to resize. Double-tap logo to hide handles.</p>
      <!-- Bill To -->
      <h3>๐Ÿ‘ค Bill To</h3>
      <div class="form-row">
        <div class="form-group">
          <label>Client Contact Number</label>
          <input type="text" id="clientContact" placeholder="Enter contact number">
          <div class="dropdown" id="contactDropdown"></div>
        </div>
        <div class="form-group">
          <label>Client Name</label>
          <input type="text" id="clientName" placeholder="Name will auto-populate">
        </div>
      </div>
      <div class="form-row">
        <div class="form-group">
          <label>Client Email</label>
          <input type="email" id="clientEmail" placeholder="Email will auto-populate">
        </div>
        <div class="form-group">
          <label>Client Address</label>
          <textarea id="clientAddress" placeholder="Address will auto-populate"></textarea>
        </div>
      </div>
      <!-- Invoice Details -->
      <h3>๐Ÿ“‹ Invoice Details</h3>
      <div class="form-row">
        <div class="form-group">
          <label>Invoice Number</label>
          <input type="text" id="invoiceNumber" value="INV-001">
        </div>
        <div class="form-group">
          <label>Invoice Date</label>
          <input type="date" id="invoiceDate">
        </div>
        <div class="form-group">
          <label>Due Date</label>
          <input type="date" id="dueDate">
        </div>
      </div>
      <!-- Items Section -->
     <!-- Items Section -->
<h3>๐Ÿ“ฆ Items</h3>
<div class="items-section">
  <table class="items-table" id="itemsList">
    <thead>
      <tr>
        <th>HSN/SAC Code</th>
        <th>Description</th>
        <th>Unit</th>
        <th>Qty</th>
        <th>Rate (₹)</th>
        <th>Disc Type</th>
        <th>Discount</th>
        <th>SGST %</th>
        <th>CGST %</th>
        <th>Total (₹)</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody>
      <tr class="item-row">
        <td><input type="text" class="item-code code-input" placeholder="Enter HSN/SAC code..."><div class="dropdown item-dropdown"></div></td>
        <td><input type="text" class="item-desc desc-input" placeholder="Service or product description"></td>
        <td><select class="item-unit unit-select"><option value="PCS">PCS</option><option value="KG">KG</option><option value="LTR">LTR</option><option value="MTR">MTR</option><option value="BOX">BOX</option><option value="SET">SET</option></select></td>
        <td><input type="number" class="item-qty qty-input" value="1" min="1"></td>
        <td><input type="number" class="item-rate rate-input" value="0" step="0.01" min="0"></td>
        <td>
          <select class="disc-type-select">
            <option value="percent">%</option>
            <option value="amount">₹</option>
          </select>
        </td>
        <td><input type="number" class="item-disc disc-input" value="0" step="0.01" min="0"></td>
        <td><input type="number" class="item-sgst sgst-input" value="0" step="0.01" min="0"></td>
        <td><input type="number" class="item-cgst cgst-input" value="0" step="0.01" min="0"></td>
        <td><input type="text" class="item-total total-input" value="0.00" readonly></td>
        <td><button class="remove-btn" onclick="removeItem(this)">Remove</button></td>
      </tr>
    </tbody>
  </table>
  <button class="add-item-btn" onclick="addItem()">+ Add Item</button>
  <button class="browse-items-btn" onclick="openItemDialog()">๐Ÿ“‹ Browse Items</button>
  <button class="scan-btn" onclick="scanForInvoice()">๐Ÿ” Scan Barcode</button>
  <button class="generate-btn" onclick="updateItemTotals()">Generate Invoice</button>
  <button class="save-btn" onclick="saveInvoice()">Save Invoice</button>
  <button class="add-item-btn" onclick="clearScreen()">Clear Screen</button> <!-- Added Clear Screen button -->
</div>
      <!-- WhatsApp Section -->
      <div class="whatsapp-section">
        <h3>Send Invoice via WhatsApp</h3>
        <div class="form-row">
          <div class="form-group">
            <label>WhatsApp Number</label>
            <input type="text" id="whatsappNumber" placeholder="Enter phone number (e.g., +919037393709)">
          </div>
          <div class="form-group">
            <label>Max Description Length</label>
            <input type="number" id="whatsappDescLength" value="20" min="10" max="50">
          </div>
          <div class="form-group">
            <label><input type="checkbox" id="gstEnabled" checked> Include GST in Message</label>
          </div>
        </div>
        <button class="btn-whatsapp" onclick="generateWhatsAppMessage()">Preview WhatsApp Message</button>
        <div class="whatsapp-preview" id="whatsappPreview" style="display: none;"></div>
        <button class="btn-whatsapp" style="margin-top: 10px;" onclick="sendWhatsApp()">Send via WhatsApp</button>
      </div>
      <div class="pdf-buttons">
        <button class="pdf-btn download" onclick="generatePDF()">Download PDF</button>
        <button class="pdf-btn share" onclick="sharePDF()">Share PDF via WhatsApp</button>
        <button class="pdf-btn print" onclick="printInvoice()">Print Invoice</button>
      </div>
    </div>
    <!-- Invoice Preview -->
    <div class="invoice-preview" id="invoicePreview">
      <div class="invoice-box">
        <div class="company-header">
          <h2 id="previewCompanyName">Your Company Name</h2>
          <p id="previewCompanyAddress">123 Business Street, City, State - ZIP</p>
          <p id="previewCompanyContact">Email: info@company.com | Phone: +91 9037393709</p>
        </div>
        <div class="header">
          <div class="bill-to">
            <b>Bill To</b><br>
            <span id="previewClientName">Customer Name</span><br>
            <span id="previewClientAddress">Customer Address</span><br>
            Contact: <span id="previewClientContact">Customer Contact</span><br>
            Email: <span id="previewClientEmail">Customer Email</span>
          </div>
          <div class="invoice-details">
            <b style="color:red;">INVOICE</b><br>
            Invoice #: <span id="previewInvoiceNumber">INV-001</span><br>
            Invoice Date: <span id="previewInvoiceDate">27 August 2025</span><br>
            Due Date: <span id="previewDueDate">26 September 2025</span>
          </div>
        </div>
        <table class="invoice-table">
          <thead>
            <tr>
              <th>Code</th>
              <th>Description</th>
              <th>Unit</th>
              <th>Qty</th>
              <th>Rate</th>
              <th>Discount</th>
              <th>SGST %</th>
              <th>CGST %</th>
              <th>Total</th>
            </tr>
          </thead>
          <tbody id="previewItems">
            <tr>
              <td></td>
              <td>Sample Item</td>
              <td>PCS</td>
              <td>1</td>
              <td>₹0.00</td>
              <td>0%</td>
              <td>0</td>
              <td>0</td>
              <td>₹0.00</td>
            </tr>
          </tbody>
        </table>
        <p class="total">Grand Total: <span id="previewTotal">₹0.00</span></p>
        <button class="print-btn" onclick="window.print()">Print / Save as PDF</button>
      </div>
    </div>
  </div>
  <!-- Stock Management Section -->
  <div class="section" id="stock">
    <div class="input-section">
      <h3>๐Ÿ“ฆ Stock Management</h3>
      <div class="form-row">
        <div class="form-group">
          <label>Item Code</label>
          <input type="text" id="stockCode" placeholder="e.g., ITM001">
        </div>
        <div class="form-group">
          <label>HSN/SAC Code</label>
          <input type="text" id="stockHSN" placeholder="e.g., 8471">
        </div>
        <div class="form-group">
          <label>Description</label>
          <input type="text" id="stockDescription" placeholder="e.g., Ergonomic wireless mouse">
        </div>
      </div>
      <div class="form-row">
        <div class="form-group">
          <label>Rate (₹)</label>
          <input type="number" id="stockPrice" placeholder="e.g., 25.99" step="0.01" min="0">
        </div>
        <div class="form-group">
          <label>Unit of Measurement</label>
          <select id="stockUnit">
            <option value="PCS">PCS - Pieces</option>
            <option value="KG">KG - Kilogram</option>
            <option value="LTR">LTR - Liter</option>
            <option value="MTR">MTR - Meter</option>
            <option value="BOX">BOX - Box</option>
            <option value="SET">SET - Set</option>
          </select>
        </div>
        <div class="form-group">
          <label>Quantity</label>
          <input type="number" id="stockQuantity" min="0" placeholder="Enter quantity">
        </div>
      </div>
      <div class="form-row">
        <div class="form-group">
          <label>SGST Rate (%)</label>
          <input type="number" id="stockSGST" value="9" step="0.01" min="0">
        </div>
        <div class="form-group">
          <label>CGST Rate (%)</label>
          <input type="number" id="stockCGST" value="9" step="0.01" min="0">
        </div>
      </div>
      <div class="form-row">
        <div class="form-group">
          <label>Discount Type</label>
          <select id="stockDiscountType">
            <option value="percent">%</option>
            <option value="amount">₹</option>
          </select>
        </div>
        <div class="form-group">
          <label>Discount</label>
          <input type="number" id="stockDiscount" value="0" step="0.01" min="0">
        </div>
      </div>
      <div class="form-row">
        <div class="form-group">
          <label>Barcode</label>
          <input type="text" id="stockBarcode" placeholder="e.g., 123456789012">
          <button class="scan-btn" onclick="scanForStock()">๐Ÿ” Scan</button>
        </div>
      </div>
      <button class="add-stock-btn" onclick="addStockItem()">Add to Inventory</button>
      <table class="stock-table" id="stockTable">
        <thead>
          <tr>
            <th>Item Code</th>
            <th>HSN/SAC</th>
            <th>Description</th>
            <th>Rate (₹)</th>
            <th>Unit</th>
            <th>SGST %</th>
            <th>CGST %</th>
            <th>Discount</th>
            <th>Quantity</th>
            <th>Barcode</th>
            <th>Actions</th>
          </tr>
        </thead>
        <tbody id="stockTableBody">
        </tbody>
      </table>
    </div>
  </div>
  <!-- Customer Database Section -->
  <div class="section" id="customers">
    <div class="input-section">
      <h3>๐Ÿ‘ฅ Customer Database</h3>
      <div class="form-row">
        <div class="form-group">
          <label>Contact Number</label>
          <input type="text" id="newCustomerContact" placeholder="Enter contact number">
        </div>
        <div class="form-group">
          <label>Customer Name</label>
          <input type="text" id="newCustomerName" placeholder="Enter customer name">
        </div>
        <div class="form-group">
          <label>Email</label>
          <input type="email" id="newCustomerEmail" placeholder="Enter email">
        </div>
      </div>
      <div class="form-row">
        <div class="form-group">
          <label>Address</label>
          <textarea id="newCustomerAddress" placeholder="Enter address"></textarea>
        </div>
      </div>
      <button class="add-customer-btn" onclick="addCustomer()">+ Add Customer</button>
      <table class="customer-table" id="customerTable">
        <thead>
          <tr>
            <th>Contact</th>
            <th>Name</th>
            <th>Email</th>
            <th>Address</th>
            <th>Actions</th>
          </tr>
        </thead>
        <tbody id="customerTableBody">
        </tbody>
      </table>
    </div>
  </div>
  <!-- Customer History Section -->
  <div class="section" id="customer-history">
    <div class="input-section">
      <h3>๐Ÿ“œ Customer History</h3>
      <div class="form-row">
        <div class="form-group">
          <label>Customer Contact Number</label>
          <input type="text" id="historyContact" placeholder="Enter contact number (e.g., +919037393709)">
          <div class="dropdown" id="historyContactDropdown"></div>
        </div>
        <div class="form-group">
          <button class="search-customer-btn" onclick="loadCustomerHistory()">Search History</button>
        </div>
      </div>
      <table class="customer-history-table" id="customerHistoryTable">
        <thead>
          <tr>
            <th>Invoice Number</th>
            <th>Invoice Date</th>
            <th>Customer Name</th>
            <th>Total (₹)</th>
            <th>Actions</th>
          </tr>
        </thead>
        <tbody id="customerHistoryTableBody">
        </tbody>
      </table>
      <div class="status-message" id="historyStatusMessage"></div>
    </div>
  </div>
  <!-- Backup & Restore Section -->
  <div class="section" id="backup-restore">
    <div class="input-section">
      <h3>๐Ÿ’พ Backup & Restore</h3>
      <div class="form-row">
        <div class="form-group">
          <label>Backup All Data</label>
          <button class="backup-btn" onclick="backupData()">Backup Data to JSON</button>
        </div>
        <div class="form-group">
          <label>Restore All Data</label>
          <input type="file" id="restoreFileInput" accept=".json">
          <button class="restore-btn" onclick="restoreData()">Restore Data</button>
        </div>
      </div>
      <div class="form-row">
        <div class="form-group">
          <label>Backup Stock Data Only</label>
          <button class="backup-btn" onclick="backupStockData()">Backup Stock to JSON</button>
        </div>
        <div class="form-group">
          <label>Restore Stock Data Only</label>
          <input type="file" id="restoreStockFileInput" accept=".json">
          <button class="restore-btn" onclick="restoreStockData()">Restore Stock Data</button>
        </div>
      </div>
      <div class="form-row">
        <div class="form-group">
          <label>Backup Customer Data Only</label>
          <button class="backup-btn" onclick="backupCustomerData()">Backup Customers to JSON</button>
        </div>
        <div class="form-group">
          <label>Restore Customer Data Only</label>
          <input type="file" id="restoreCustomerFileInput" accept=".json">
          <button class="restore-btn" onclick="restoreCustomerData()">Restore Customer Data</button>
        </div>
      </div>
      <div class="form-row">
        <div class="form-group">
          <label>Export Invoices</label>
          <button class="export-csv-btn" onclick="exportInvoicesToCSV()">Export Invoices to CSV</button>
        </div>
      </div>
      <div class="status-message" id="backupStatusMessage"></div>
    </div>
  </div>
</div>

<!-- Item Selection Dialog -->
<div class="dialog-overlay" id="dialogOverlay" onclick="closeDialog(event, 'dialogOverlay')">
  <div class="dialog" id="itemDialog" onclick="event.stopPropagation()">
    <div class="dialog-header">
      <h3>Select Items</h3>
      <div class="dialog-controls">
        <div class="size-inputs">
          <span style="font-size: 0.8rem;">W:</span>
          <input type="number" class="size-input" id="itemWidthInput" value="600" min="300" max="1200">
          <span style="font-size: 0.8rem;">H:</span>
          <input type="number" class="size-input" id="itemHeightInput" value="450" min="200" max="800">
          <button class="apply-btn" onclick="applyCustomSize('itemDialog', 'itemWidthInput', 'itemHeightInput')">Apply</button>
        </div>
        <div class="resize-controls">
          <button class="resize-btn" onclick="quickResize(400, 250, 'itemDialog', 'itemWidthInput', 'itemHeightInput')" title="Compact">XS</button>
          <button class="resize-btn" onclick="quickResize(500, 350, 'itemDialog', 'itemWidthInput', 'itemHeightInput')" title="Small">S</button>
          <button class="resize-btn" onclick="quickResize(700, 500, 'itemDialog', 'itemWidthInput', 'itemHeightInput')" title="Large">L</button>
        </div>
        <button class="close-btn" onclick="closeDialog(null, 'dialogOverlay')">&times;</button>
      </div>
    </div>
    <div class="search-section">
      <input type="text" class="search-input" id="searchInput" placeholder="Search items by code, name, or description..." oninput="searchItems()">
    </div>
    <div class="status-message" id="statusMessage"></div>
    <div class="items-container">
      <table class="item-table">
        <thead>
          <tr>
            <th>Code</th>
            <th>Name</th>
            <th>Description</th>
            <th>Price</th>
            <th>SGST %</th>
            <th>CGST %</th>
            <th>Discount</th>
          </tr>
        </thead>
        <tbody id="itemsList2">
        </tbody>
      </table>
    </div>
  </div>
</div>

<!-- Edit Customer Dialog -->
<div class="dialog-overlay" id="editCustomerDialogOverlay" onclick="closeDialog(event, 'editCustomerDialogOverlay')">
  <div class="dialog" id="editCustomerDialog" onclick="event.stopPropagation()">
    <div class="dialog-header">
      <h3>Edit Customer</h3>
      <button class="close-btn" onclick="closeDialog(null, 'editCustomerDialogOverlay')">&times;</button>
    </div>
    <div class="form-row" style="padding: 20px;">
      <div class="form-group">
        <label>Contact Number</label>
        <input type="text" id="editCustomerContact" placeholder="Enter contact number">
      </div>
      <div class="form-group">
        <label>Customer Name</label>
        <input type="text" id="editCustomerName" placeholder="Enter customer name">
      </div>
      <div class="form-group">
        <label>Email</label>
        <input type="email" id="editCustomerEmail" placeholder="Enter email">
      </div>
      <div class="form-group">
        <label>Address</label>
        <textarea id="editCustomerAddress" placeholder="Enter address"></textarea>
      </div>
    </div>
    <div style="padding: 0 20px 20px;">
      <button class="add-customer-btn" onclick="saveEditedCustomer()">Save Changes</button>
    </div>
  </div>
</div>

<!-- Barcode Scanner Dialog -->
<div class="dialog-overlay" id="scanDialogOverlay" onclick="closeDialog(event, 'scanDialogOverlay')">
  <div class="dialog" id="scanDialog" onclick="event.stopPropagation()">
    <div class="dialog-header">
      <h3>Scan Barcode</h3>
      <button class="close-btn" onclick="closeDialog(null, 'scanDialogOverlay'); if (typeof Quagga !== 'undefined') Quagga.stop();">&times;</button>
    </div>
    <div style="padding: 20px;">
      <div id="barcodeScanner" style="width: 100%; height: 300px; background: black;"></div>
    </div>
  </div>
</div>

<script>
// Initialize IndexedDB with Dexie.js
const db = new Dexie('InvoiceDB');
db.version(1).stores({
  invoices: 'invoiceNumber,clientContact,timestamp',
  inventory: 'code,hsn,description',
  customers: 'contact,name'
});

// Initialize data arrays
let inventory = [];
let customerDatabase = [];
let filteredInventory = [];
let invoices = [];
let editingCustomerContact = null;

// Default inventory data
const defaultInventory = [
  { code: 'ITM001', hsn: '8471', name: 'Wireless Mouse', description: 'Ergonomic wireless mouse with USB receiver', price: 25.99, unit: 'PCS', quantity: 50, sgst: 9, cgst: 9, discountType: 'percent', discount: 5, barcode: '' },
  { code: 'ITM002', hsn: '8471', name: 'Keyboard', description: 'Mechanical gaming keyboard with RGB lighting', price: 89.99, unit: 'PCS', quantity: 30, sgst: 9, cgst: 9, discountType: 'amount', discount: 10, barcode: '' },
  { code: 'ITM003', hsn: '9403', name: 'Monitor Stand', description: 'Adjustable aluminum monitor stand', price: 45.00, unit: 'PCS', quantity: 20, sgst: 9, cgst: 9, discountType: 'percent', discount: 0, barcode: '' },
  { code: 'ITM004', hsn: '8544', name: 'USB Cable', description: '6ft USB-C to USB-A cable', price: 12.50, unit: 'PCS', quantity: 100, sgst: 9, cgst: 9, discountType: 'amount', discount: 2.50, barcode: '' },
  { code: 'ITM005', hsn: '8525', name: 'Webcam', description: '1080p HD webcam with built-in microphone', price: 67.99, unit: 'PCS', quantity: 15, sgst: 9, cgst: 9, discountType: 'percent', discount: 10, barcode: '' }
];

// Default customer data
const defaultCustomers = [
  { contact: "+919037393709", name: "John Doe", email: "john@example.com", address: "123 Main St, City" },
  { contact: "+919876543210", name: "Jane Smith", email: "jane@example.com", address: "456 Park Ave, City" }
];

// Migrate data from localStorage to IndexedDB
async function migrateLocalStorageToIndexedDB() {
  try {
    const invoiceCount = await db.invoices.count();
    if (invoiceCount > 0) return; // Skip migration if IndexedDB already has data

    const localInventory = JSON.parse(localStorage.getItem('inventory'));
    const localCustomers = JSON.parse(localStorage.getItem('customerDatabase'));
    const localInvoices = JSON.parse(localStorage.getItem('invoices'));

    if (localInventory && localInventory.length > 0) {
      await db.inventory.bulkPut(localInventory);
    } else {
      await db.inventory.bulkPut(defaultInventory);
    }

    if (localCustomers && localCustomers.length > 0) {
      await db.customers.bulkPut(localCustomers);
    } else {
      await db.customers.bulkPut(defaultCustomers);
    }

    if (localInvoices && localInvoices.length > 0) {
      await db.invoices.bulkPut(localInvoices);
    }

    // Clear localStorage after migration
    localStorage.removeItem('inventory');
    localStorage.removeItem('customerDatabase');
    localStorage.removeItem('invoices');
  } catch (error) {
    showStatus('Error during data migration: ' + error.message, 'error');
  }
}

// Load data from IndexedDB
async function loadDataFromIndexedDB() {
  try {
    inventory = await db.inventory.toArray();
    customerDatabase = await db.customers.toArray();
    invoices = await db.invoices.toArray();
    filteredInventory = [...inventory];
  } catch (error) {
    showStatus('Error loading data from IndexedDB: ' + error.message, 'error');
  }
}

// Input sanitization function
function sanitizeInput(input) {
  return input.replace(/[<>"'&]/g, '');
}

// Debounce function for autocomplete
function debounce(func, wait) {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
}

// Generate unique invoice number
async function generateInvoiceNumber() {
  try {
    const invoices = await db.invoices.toArray();
    const existingNumbers = invoices.map(inv => parseInt(inv.invoiceNumber.replace('INV-', '')));
    const nextNumber = existingNumbers.length ? Math.max(...existingNumbers) + 1 : 1;
    return `INV-${String(nextNumber).padStart(3, '0')}`;
  } catch (error) {
    showStatus('Error generating invoice number: ' + error.message, 'error');
    return 'INV-001';
  }
}

// Navigation functionality
function setupNavigation() {
  const navButtons = document.querySelectorAll('.nav-btn');
  navButtons.forEach(button => {
    button.addEventListener('click', function() {
      navButtons.forEach(btn => btn.classList.remove('active'));
      this.classList.add('active');
      document.querySelectorAll('.section').forEach(section => section.classList.remove('active'));
      document.getElementById(this.getAttribute('data-section')).classList.add('active');
    });
  });
}

// Show status message
function showStatus(message, type, elementId = 'statusMessage') {
  const statusMessage = document.getElementById(elementId);
  statusMessage.textContent = message;
  statusMessage.className = `status-message status-${type}`;
  statusMessage.style.display = 'block';
  setTimeout(() => {
    statusMessage.style.display = 'none';
  }, 3000);
}

// Add new item row
function addItem() {
  const itemsList = document.getElementById('itemsList').querySelector('tbody');
  const newRow = document.createElement('tr');
  newRow.className = 'item-row';
  newRow.innerHTML = `
    <td><input type="text" class="item-code code-input" placeholder="Enter HSN/SAC code..."><div class="dropdown item-dropdown"></div></td>
    <td><input type="text" class="item-desc desc-input" placeholder="Service or product description"></td>
    <td><select class="item-unit unit-select"><option value="PCS">PCS</option><option value="KG">KG</option><option value="LTR">LTR</option><option value="MTR">MTR</option><option value="BOX">BOX</option><option value="SET">SET</option></select></td>
    <td><input type="number" class="item-qty qty-input" value="1" min="1"></td>
    <td><input type="number" class="item-rate rate-input" value="0" step="0.01" min="0"></td>
    <td>
      <select class="disc-type-select">
        <option value="percent">%</option>
        <option value="amount">₹</option>
      </select>
    </td>
    <td><input type="number" class="item-disc disc-input" value="0" step="0.01" min="0"></td>
    <td><input type="number" class="item-sgst sgst-input" value="0" step="0.01" min="0"></td>
    <td><input type="number" class="item-cgst cgst-input" value="0" step="0.01" min="0"></td>
    <td><input type="text" class="item-total total-input" value="0.00" readonly></td>
    <td><button class="remove-btn" onclick="removeItem(this)">Remove</button></td>
  `;
  itemsList.appendChild(newRow);
  attachInputListeners(newRow);
  setupItemAutocomplete(newRow);
  updateItemTotals();
  return newRow;
}

// Remove item row
function removeItem(button) {
  const itemsList = document.getElementById('itemsList').querySelector('tbody');
  if (itemsList.children.length > 1) {
    button.closest('tr').remove();
    updateItemTotals();
  } else {
    showStatus('At least one item is required.', 'error');
  }
}

// Attach input listeners for real-time calculations
function attachInputListeners(row) {
  row.querySelectorAll('.item-qty, .item-rate, .item-disc, .item-sgst, .item-cgst, .disc-type-select').forEach(input => {
    input.addEventListener('input', () => {
      const code = row.querySelector('.item-code').value;
      const qty = parseInt(row.querySelector('.item-qty').value) || 0;
      const disc = parseFloat(row.querySelector('.item-disc').value) || 0;
      const discType = row.querySelector('.disc-type-select').value;
      const rate = parseFloat(row.querySelector('.item-rate').value) || 0;

      // Validate quantity
      if (input.classList.contains('item-qty') && code) {
        const item = inventory.find(i => i.code === code);
        if (item && qty > item.quantity) {
          input.classList.add('quantity-error');
          showStatus(`Insufficient stock for ${item.description}. Available: ${item.quantity} units.`, 'error');
          input.value = item.quantity;
        } else {
          input.classList.remove('quantity-error');
        }
      }

      // Validate discount
      if (input.classList.contains('item-disc') || input.classList.contains('disc-type-select')) {
        if (discType === 'percent' && disc > 100) {
          input.classList.add('disc-error');
          showStatus('Discount percentage cannot exceed 100%.', 'error');
          input.value = 100;
        } else if (discType === 'amount' && disc > qty * rate) {
          input.classList.add('disc-error');
          showStatus('Discount amount cannot exceed subtotal.', 'error');
          input.value = qty * rate;
        } else {
          input.classList.remove('disc-error');
        }
      }

      updateItemTotal(row);
      updateItemTotals();
    });
  });
}

// Update individual item total
function updateItemTotal(row) {
  const qty = parseFloat(row.querySelector('.item-qty').value) || 0;
  const rate = parseFloat(row.querySelector('.item-rate').value) || 0;
  const discType = row.querySelector('.disc-type-select').value;
  const disc = parseFloat(row.querySelector('.item-disc').value) || 0;
  const sgst = parseFloat(row.querySelector('.item-sgst').value) || 0;
  const cgst = parseFloat(row.querySelector('.item-cgst').value) || 0;

  const subtotal = qty * rate;
  let discAmount = discType === 'percent' ? subtotal * (disc / 100) : disc;
  const afterDisc = subtotal - discAmount;
  const sgstAmount = afterDisc * (sgst / 100);
  const cgstAmount = afterDisc * (cgst / 100);
  const lineTotal = afterDisc + sgstAmount + cgstAmount;

  row.querySelector('.item-total').value = lineTotal.toFixed(2);
}

// Update all item totals and invoice preview
function updateItemTotals() {
  const rows = document.querySelectorAll('.item-row');
  let subtotal = 0, totalDiscount = 0, totalSGST = 0, totalCGST = 0, grandTotal = 0;
  let canGenerate = true;

  rows.forEach(row => {
    const code = row.querySelector('.item-code').value;
    const qty = parseInt(row.querySelector('.item-qty').value) || 0;
    const disc = parseFloat(row.querySelector('.item-disc').value) || 0;
    const discType = row.querySelector('.disc-type-select').value;
    const rate = parseFloat(row.querySelector('.item-rate').value) || 0;
    const item = inventory.find(i => i.code === code);

    if (item && qty > item.quantity) {
      canGenerate = false;
      row.querySelector('.item-qty').classList.add('quantity-error');
      showStatus(`Insufficient stock for ${item.description}. Available: ${item.quantity} units.`, 'error');
    } else {
      row.querySelector('.item-qty').classList.remove('quantity-error');
    }

    if (discType === 'percent' && disc > 100) {
      canGenerate = false;
      row.querySelector('.item-disc').classList.add('disc-error');
      showStatus('Discount percentage cannot exceed 100%.', 'error');
    } else if (discType === 'amount' && disc > qty * rate) {
      canGenerate = false;
      row.querySelector('.item-disc').classList.add('disc-error');
      showStatus('Discount amount cannot exceed subtotal.', 'error');
    } else {
      row.querySelector('.item-disc').classList.remove('disc-error');
    }
  });

  if (!canGenerate) return;

  rows.forEach(row => {
    const qty = parseFloat(row.querySelector('.item-qty').value) || 0;
    const rate = parseFloat(row.querySelector('.item-rate').value) || 0;
    const discType = row.querySelector('.disc-type-select').value;
    const disc = parseFloat(row.querySelector('.item-disc').value) || 0;
    const sgst = parseFloat(row.querySelector('.item-sgst').value) || 0;
    const cgst = parseFloat(row.querySelector('.item-cgst').value) || 0;

    const subtotalAmount = qty * rate;
    let discAmount = discType === 'percent' ? subtotalAmount * (disc / 100) : disc;
    const afterDisc = subtotalAmount - discAmount;
    const sgstAmount = afterDisc * (sgst / 100);
    const cgstAmount = afterDisc * (cgst / 100);
    const lineTotal = afterDisc + sgstAmount + cgstAmount;

    row.querySelector('.item-total').value = lineTotal.toFixed(2);
    subtotal += subtotalAmount;
    totalDiscount += discAmount;
    totalSGST += sgstAmount;
    totalCGST += cgstAmount;
    grandTotal += lineTotal;
  });

  const totalsRow = `
    <tr>
      <td colspan="4"></td>
      <td colspan="3">Subtotal</td>
      <td>₹${subtotal.toFixed(2)}</td>
    </tr>
    <tr>
      <td colspan="4"></td>
      <td colspan="3">Total Discount</td>
      <td>₹${totalDiscount.toFixed(2)}</td>
    </tr>
    <tr>
      <td colspan="4"></td>
      <td colspan="3">Total SGST</td>
      <td>₹${totalSGST.toFixed(2)}</td>
    </tr>
    <tr>
      <td colspan="4"></td>
      <td colspan="3">Total CGST</td>
      <td>₹${totalCGST.toFixed(2)}</td>
    </tr>
    <tr>
      <td colspan="4"></td>
      <td colspan="3"><strong>Grand Total</strong></td>
      <td><strong>₹${grandTotal.toFixed(2)}</strong></td>
    </tr>
  `;
  generateInvoice(totalsRow);
}

// Save invoice and update inventory
async function saveInvoice() {
  try {
    const invoice = {
      invoiceNumber: document.getElementById('invoiceNumber').value || await generateInvoiceNumber(),
      invoiceDate: document.getElementById('invoiceDate').value,
      dueDate: document.getElementById('dueDate').value,
      clientContact: sanitizeInput(document.getElementById('clientContact').value),
      clientName: sanitizeInput(document.getElementById('clientName').value),
      clientEmail: sanitizeInput(document.getElementById('clientEmail').value),
      clientAddress: sanitizeInput(document.getElementById('clientAddress').value),
      items: [],
      subtotal: 0,
      totalDiscount: 0,
      totalSGST: 0,
      totalCGST: 0,
      grandTotal: 0,
      timestamp: new Date().toISOString()
    };

    const rows = document.querySelectorAll('.item-row');
    let canSave = true;

    // Validate all rows
    rows.forEach(row => {
      const code = row.querySelector('.item-code').value;
      const qty = parseInt(row.querySelector('.item-qty').value) || 0;
      const disc = parseFloat(row.querySelector('.item-disc').value) || 0;
      const discType = row.querySelector('.disc-type-select').value;
      const rate = parseFloat(row.querySelector('.item-rate').value) || 0;
      const item = inventory.find(i => i.code === code);

      if (item && qty > item.quantity) {
        canSave = false;
        row.querySelector('.item-qty').classList.add('quantity-error');
        showStatus(`Insufficient stock for ${item.description}. Available: ${item.quantity} units.`, 'error');
      }
      if (discType === 'percent' && disc > 100) {
        canSave = false;
        row.querySelector('.item-disc').classList.add('disc-error');
        showStatus('Discount percentage cannot exceed 100%.', 'error');
      } else if (discType === 'amount' && disc > qty * rate) {
        canSave = false;
        row.querySelector('.item-disc').classList.add('disc-error');
        showStatus('Discount amount cannot exceed subtotal.', 'error');
      }
    });

    if (!canSave) return;

    // Build invoice items and update totals
    rows.forEach(row => {
      const code = row.querySelector('.item-code').value;
      const qty = parseFloat(row.querySelector('.item-qty').value) || 0;
      const unit = row.querySelector('.item-unit').value || 'PCS';
      const rate = parseFloat(row.querySelector('.item-rate').value) || 0;
      const discType = row.querySelector('.disc-type-select').value;
      const disc = parseFloat(row.querySelector('.item-disc').value) || 0;
      const sgst = parseFloat(row.querySelector('.item-sgst').value) || 0;
      const cgst = parseFloat(row.querySelector('.item-cgst').value) || 0;

      const subtotalAmount = qty * rate;
      let discAmount = discType === 'percent' ? subtotalAmount * (disc / 100) : disc;
      const afterDisc = subtotalAmount - discAmount;
      const sgstAmount = afterDisc * (sgst / 100);
      const cgstAmount = afterDisc * (cgst / 100);
      const lineTotal = afterDisc + sgstAmount + cgstAmount;

      invoice.items.push({
        code: sanitizeInput(code),
        description: sanitizeInput(row.querySelector('.item-desc').value),
        quantity: qty,
        unit: unit,
        rate: rate,
        discountType: discType,
        discount: disc,
        sgst: sgst,
        cgst: cgst,
        total: lineTotal
      });

      invoice.subtotal += subtotalAmount;
      invoice.totalDiscount += discAmount;
      invoice.totalSGST += sgstAmount;
      invoice.totalCGST += cgstAmount;
      invoice.grandTotal += lineTotal;

      const item = inventory.find(i => i.code === code);
      if (item) item.quantity -= qty;
    });

    if (!invoice.clientContact || !invoice.clientName || invoice.items.length === 0) {
      showStatus('Please fill in client details and add at least one item.', 'error');
      return;
    }

    // Save invoice and update inventory
    await db.invoices.put(invoice);
    await db.inventory.bulkPut(inventory);
    invoices = await db.invoices.toArray();
    loadStockTable();
    showStatus('Invoice saved successfully!', 'success');
    updateDashboard();

    // Reset form
    document.getElementById('invoiceNumber').value = await generateInvoiceNumber();
    document.getElementById('clientContact').value = '';
    document.getElementById('clientName').value = '';
    document.getElementById('clientEmail').value = '';
    document.getElementById('clientAddress').value = '';
    document.getElementById('whatsappNumber').value = '';
    const itemsList = document.getElementById('itemsList').querySelector('tbody');
    itemsList.innerHTML = '';
    addItem();
  } catch (error) {
    showStatus('Error saving invoice: ' + error.message, 'error');
  }
}

// Generate invoice preview
function generateInvoice(totalsRow) {
  const companyName = document.getElementById('companyName').value;
  const companyAddress = document.getElementById('companyAddress').value;
  const companyContact = document.getElementById('companyContact').value;
  const clientName = document.getElementById('clientName').value;
  const clientAddress = document.getElementById('clientAddress').value;
  const clientContact = document.getElementById('clientContact').value;
  const clientEmail = document.getElementById('clientEmail').value;
  const invoiceNumber = document.getElementById('invoiceNumber').value;
  const invoiceDate = document.getElementById('invoiceDate').value;
  const dueDate = document.getElementById('dueDate').value;

  document.getElementById('previewCompanyName').textContent = companyName || 'Your Company Name';
  document.getElementById('previewCompanyAddress').textContent = companyAddress || '123 Business Street, City, State - ZIP';
  document.getElementById('previewCompanyContact').textContent = companyContact || 'Email: info@company.com | Phone: +91 9037393709';
  document.getElementById('previewClientName').textContent = clientName || 'Customer Name';
  document.getElementById('previewClientAddress').textContent = clientAddress || 'Customer Address';
  document.getElementById('previewClientContact').textContent = clientContact || 'Customer Contact';
  document.getElementById('previewClientEmail').textContent = clientEmail || 'Customer Email';
  document.getElementById('previewInvoiceNumber').textContent = invoiceNumber || 'INV-001';
  document.getElementById('previewInvoiceDate').textContent = invoiceDate || new Date().toLocaleDateString();
  document.getElementById('previewDueDate').textContent = dueDate || new Date().toLocaleDateString();

  let itemsHtml = '';
  document.querySelectorAll('.item-row').forEach(row => {
    const code = row.querySelector('.item-code').value || '';
    const desc = row.querySelector('.item-desc').value || 'Sample Item';
    const unit = row.querySelector('.item-unit').value || 'PCS';
    const qty = row.querySelector('.item-qty').value || 1;
    const rate = parseFloat(row.querySelector('.item-rate').value) || 0;
    const discType = row.querySelector('.disc-type-select').value;
    const disc = parseFloat(row.querySelector('.item-disc').value) || 0;
    const sgst = parseFloat(row.querySelector('.item-sgst').value) || 0;
    const cgst = parseFloat(row.querySelector('.item-cgst').value) || 0;
    const total = parseFloat(row.querySelector('.item-total').value) || 0;
    const item = inventory.find(i => i.code === code);
const hsnCode = item ? item.hsn : code;

    const discDisplay = discType === 'percent' ? `${disc}%` : `₹${disc.toFixed(2)}`;
    itemsHtml += `
      <tr>
        <td>${sanitizeInput(hsnCode)}</td>
        <td>${sanitizeInput(desc)}</td>
        <td>${unit}</td>
        <td>${qty}</td>
        <td>₹${rate.toFixed(2)}</td>
        <td>${discDisplay}</td>
        <td>${sgst}%</td>
        <td>${cgst}%</td>
        <td>₹${total.toFixed(2)}</td>
      </tr>
    `;
  });
  itemsHtml += totalsRow;
  document.getElementById('previewItems').innerHTML = itemsHtml;
  document.getElementById('previewTotal').textContent = `₹${parseFloat(totalsRow.match(/₹([\d.]+)/)[1]).toFixed(2)}`;
}

// Generate PDF
async function generatePDF() {
  try {
    const { jsPDF } = window.jspdf;
    const doc = new jsPDF();
    const invoiceBox = document.querySelector('.invoice-box');
    const companyName = document.getElementById('previewCompanyName').textContent;
    const invoiceNumber = document.getElementById('previewInvoiceNumber').textContent;

    // Add logo if present
    const logo = document.querySelector('.invoice-logo img');
    if (logo) {
      const logoStyle = window.getComputedStyle(document.querySelector('.invoice-logo'));
      const left = parseFloat(logoStyle.left) / 3.78; // Convert px to mm
      const top = parseFloat(logoStyle.top) / 3.78;
      const width = parseFloat(logoStyle.width) / 3.78;
      const height = parseFloat(logoStyle.height) / 3.78;
      const imgData = await getImageData(logo);
      doc.addImage(imgData, 'PNG', left, top, width, height);
    }

    // Capture invoice content
    const canvas = await html2canvas(invoiceBox, { scale: 2 });
    const imgData = canvas.toDataURL('image/png');
    doc.addImage(imgData, 'PNG', 10, 30, 190, 0);
    doc.save(`${companyName}_Invoice_${invoiceNumber}.pdf`);
  } catch (error) {
    showStatus('Error generating PDF: ' + error.message, 'error');
  }
}

// Share PDF via WhatsApp
// Replace your existing sharePDF() function with this improved version
async function sharePDF() {
  try {
    const { jsPDF } = window.jspdf;
    const doc = new jsPDF();
    const invoiceBox = document.querySelector('.invoice-box');
    const companyName = document.getElementById('previewCompanyName').textContent;
    const invoiceNumber = document.getElementById('previewInvoiceNumber').textContent;
    const whatsappNumber = document.getElementById('whatsappNumber').value;

    if (!whatsappNumber) {
      showStatus('Please enter a WhatsApp number.', 'error');
      return;
    }

    // Add logo if present
    const logo = document.querySelector('.invoice-logo img');
    if (logo) {
      const logoStyle = window.getComputedStyle(document.querySelector('.invoice-logo'));
      const left = parseFloat(logoStyle.left) / 3.78;
      const top = parseFloat(logoStyle.top) / 3.78;
      const width = parseFloat(logoStyle.width) / 3.78;
      const height = parseFloat(logoStyle.height) / 3.78;
      const imgData = await getImageData(logo);
      doc.addImage(imgData, 'PNG', left, top, width, height);
    }

    // Capture the invoice with higher resolution
    const canvas = await html2canvas(invoiceBox, { 
      scale: 2,
      useCORS: true,
      allowTaint: true,
      height: invoiceBox.scrollHeight,
      width: invoiceBox.scrollWidth
    });
    
    const imgData = canvas.toDataURL('image/png');
    const imgWidth = 190; // PDF width in mm
    const pageHeight = 277; // A4 page height in mm
    const imgHeight = (canvas.height * imgWidth) / canvas.width;
    let heightLeft = imgHeight;
    let position = 30; // Start position

    // Add first page
    doc.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight);
    heightLeft -= (pageHeight - position);

    // Add additional pages if needed
    while (heightLeft >= 0) {
      position = heightLeft - imgHeight + 30;
      doc.addPage();
      doc.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight);
      heightLeft -= pageHeight;
    }

    const pdfBlob = doc.output('blob');
    const file = new File([pdfBlob], `${companyName}_Invoice_${invoiceNumber}.pdf`, { type: 'application/pdf' });

    if (navigator.canShare && navigator.canShare({ files: [file] })) {
      await navigator.share({
        files: [file],
        title: `Invoice ${invoiceNumber}`,
        text: `Invoice ${invoiceNumber} from ${companyName}`,
        url: whatsappNumber ? `https://wa.me/${whatsappNumber.replace('+', '')}?text=Invoice%20${invoiceNumber}%20from%20${encodeURIComponent(companyName)}` : ''
      });
    } else {
      // Fallback: Download the file and open WhatsApp
      const url = URL.createObjectURL(pdfBlob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `${companyName}_Invoice_${invoiceNumber}.pdf`;
      a.click();
      URL.revokeObjectURL(url);
      
      // Open WhatsApp with message
      const whatsappUrl = `https://wa.me/${whatsappNumber.replace('+', '')}?text=Please%20find%20the%20invoice%20PDF%20attached.%20Invoice%20${invoiceNumber}%20from%20${encodeURIComponent(companyName)}`;
      window.open(whatsappUrl, '_blank');
      
      showStatus('PDF downloaded. Please manually attach it to WhatsApp.', 'success');
    }
  } catch (error) {
    showStatus('Error sharing PDF: ' + error.message, 'error');
  }
}

// Print invoice
function printInvoice() {
  window.print();
}

// Get image data for PDF
function getImageData(img) {
  return new Promise((resolve) => {
    const canvas = document.createElement('canvas');
    canvas.width = img.naturalWidth;
    canvas.height = img.naturalHeight;
    const ctx = canvas.getContext('2d');
    ctx.drawImage(img, 0, 0);
    resolve(canvas.toDataURL('image/png'));
  });
}

// Setup item autocomplete
function setupItemAutocomplete(row) {
  const codeInput = row.querySelector('.item-code');
  const dropdown = row.querySelector('.item-dropdown');
  codeInput.addEventListener('input', debounce(async () => {
    const query = codeInput.value.toLowerCase();
    dropdown.innerHTML = '';
    if (query.length < 1) {
      dropdown.style.display = 'none';
      return;
    }
    const filtered = inventory.filter(item =>
      item.code.toLowerCase().includes(query) ||
      item.description.toLowerCase().includes(query) ||
      (item.barcode && item.barcode.toLowerCase().includes(query))
    );
    filtered.forEach(item => {
      const div = document.createElement('div');
      div.className = 'dropdown-item';
      div.textContent = `${item.code} - ${item.description}`;
      div.addEventListener('click', () => {
        codeInput.value = item.code;
        row.querySelector('.item-desc').value = item.description;
        row.querySelector('.item-rate').value = item.price.toFixed(2);
        row.querySelector('.item-unit').value = item.unit;
        row.querySelector('.item-sgst').value = item.sgst;
        row.querySelector('.item-cgst').value = item.cgst;
        row.querySelector('.item-disc').value = item.discount;
        row.querySelector('.disc-type-select').value = item.discountType;
        [row.querySelector('.item-desc'), row.querySelector('.item-rate'), row.querySelector('.item-unit'),
         row.querySelector('.item-sgst'), row.querySelector('.item-cgst'), row.querySelector('.item-disc'),
         row.querySelector('.disc-type-select')].forEach(el => el.classList.add('auto-populated'));
        updateItemTotal(row);
        updateItemTotals();
        dropdown.style.display = 'none';
      });
      dropdown.appendChild(div);
    });
    dropdown.style.display = filtered.length ? 'block' : 'none';
  }, 300));
}

// Client contact autocomplete
function setupClientAutocomplete() {
  const contactInput = document.getElementById('clientContact');
  const dropdown = document.getElementById('contactDropdown');
  contactInput.addEventListener('input', debounce(async () => {
    const query = contactInput.value.toLowerCase();
    dropdown.innerHTML = '';
    if (query.length < 1) {
      dropdown.style.display = 'none';
      return;
    }
    const filtered = customerDatabase.filter(customer =>
      customer.contact.toLowerCase().includes(query) ||
      customer.name.toLowerCase().includes(query)
    );
    filtered.forEach(customer => {
      const div = document.createElement('div');
      div.className = 'dropdown-item';
      div.textContent = `${customer.contact} - ${customer.name}`;
      div.addEventListener('click', () => {
        contactInput.value = customer.contact;
        document.getElementById('clientName').value = customer.name;
        document.getElementById('clientEmail').value = customer.email;
        document.getElementById('clientAddress').value = customer.address;
        document.getElementById('whatsappNumber').value = customer.contact;
        [document.getElementById('clientName'), document.getElementById('clientEmail'),
         document.getElementById('clientAddress'), document.getElementById('whatsappNumber')]
          .forEach(el => el.classList.add('auto-populated'));
        dropdown.style.display = 'none';
      });
      dropdown.appendChild(div);
    });
    dropdown.style.display = filtered.length ? 'block' : 'none';
  }, 300));
}

// Load stock table
async function loadStockTable() {
  try {
    const stockTableBody = document.getElementById('stockTableBody');
    stockTableBody.innerHTML = '';
    inventory = await db.inventory.toArray();
    inventory.forEach((item, index) => {
      const row = document.createElement('tr');
      const discDisplay = item.discountType === 'percent' ? `${item.discount}%` : `₹${item.discount.toFixed(2)}`;
      row.innerHTML = `
        <td>${sanitizeInput(item.code)}</td>
        <td>${sanitizeInput(item.hsn)}</td>
        <td>${sanitizeInput(item.description)}</td>
        <td>₹${item.price.toFixed(2)}</td>
        <td>${item.unit}</td>
        <td>${item.sgst}%</td>
        <td>${item.cgst}%</td>
        <td>${discDisplay}</td>
        <td class="${item.quantity < 10 ? 'low-stock' : ''}">${item.quantity}</td>
        <td>${sanitizeInput(item.barcode || '')}</td>
        <td>
          <button class="edit-btn" onclick="editStockItem(${index})">Edit</button>
          <button class="delete-btn" onclick="deleteStockItem('${item.code}')">Delete</button>
        </td>
      `;
      stockTableBody.appendChild(row);
    });
  } catch (error) {
    showStatus('Error loading stock table: ' + error.message, 'error');
  }
}

// Add stock item
async function addStockItem() {
  try {
    const item = {
      code: sanitizeInput(document.getElementById('stockCode').value),
      hsn: sanitizeInput(document.getElementById('stockHSN').value),
      description: sanitizeInput(document.getElementById('stockDescription').value),
      price: parseFloat(document.getElementById('stockPrice').value) || 0,
      unit: document.getElementById('stockUnit').value,
      quantity: parseInt(document.getElementById('stockQuantity').value) || 0,
      sgst: parseFloat(document.getElementById('stockSGST').value) || 0,
      cgst: parseFloat(document.getElementById('stockCGST').value) || 0,
      discountType: document.getElementById('stockDiscountType').value,
      discount: parseFloat(document.getElementById('stockDiscount').value) || 0,
      barcode: sanitizeInput(document.getElementById('stockBarcode').value)
    };

    if (!item.code || !item.description || !item.hsn) {
      showStatus('Please fill in all required fields (Code, HSN/SAC, Description).', 'error');
      return;
    }

    if (inventory.some(i => i.code === item.code)) {
      showStatus('Item code already exists.', 'error');
      return;
    }

    await db.inventory.put(item);
    inventory = await db.inventory.toArray();
    loadStockTable();
    document.getElementById('stockCode').value = '';
    document.getElementById('stockHSN').value = '';
    document.getElementById('stockDescription').value = '';
    document.getElementById('stockPrice').value = '';
    document.getElementById('stockUnit').value = 'PCS';
    document.getElementById('stockQuantity').value = '';
    document.getElementById('stockSGST').value = '9';
    document.getElementById('stockCGST').value = '9';
    document.getElementById('stockDiscountType').value = 'percent';
    document.getElementById('stockDiscount').value = '0';
    document.getElementById('stockBarcode').value = '';
    showStatus('Item added successfully!', 'success');
  } catch (error) {
    showStatus('Error adding stock item: ' + error.message, 'error');
  }
}

// Edit stock item
function editStockItem(index) {
  const item = inventory[index];
  document.getElementById('stockCode').value = item.code;
  document.getElementById('stockHSN').value = item.hsn;
  document.getElementById('stockDescription').value = item.description;
  document.getElementById('stockPrice').value = item.price;
  document.getElementById('stockUnit').value = item.unit;
  document.getElementById('stockQuantity').value = item.quantity;
  document.getElementById('stockSGST').value = item.sgst;
  document.getElementById('stockCGST').value = item.cgst;
  document.getElementById('stockDiscountType').value = item.discountType;
  document.getElementById('stockDiscount').value = item.discount;
  document.getElementById('stockBarcode').value = item.barcode || '';

  document.getElementById('add-stock-btn').textContent = 'Update Item';
  document.getElementById('add-stock-btn').onclick = async () => {
    try {
      const updatedItem = {
        code: sanitizeInput(document.getElementById('stockCode').value),
        hsn: sanitizeInput(document.getElementById('stockHSN').value),
        description: sanitizeInput(document.getElementById('stockDescription').value),
        price: parseFloat(document.getElementById('stockPrice').value) || 0,
        unit: document.getElementById('stockUnit').value,
        quantity: parseInt(document.getElementById('stockQuantity').value) || 0,
        sgst: parseFloat(document.getElementById('stockSGST').value) || 0,
        cgst: parseFloat(document.getElementById('stockCGST').value) || 0,
        discountType: document.getElementById('stockDiscountType').value,
        discount: parseFloat(document.getElementById('stockDiscount').value) || 0,
        barcode: sanitizeInput(document.getElementById('stockBarcode').value)
      };

      if (!updatedItem.code || !updatedItem.description || !updatedItem.hsn) {
        showStatus('Please fill in all required fields (Code, HSN/SAC, Description).', 'error');
        return;
      }

      await db.inventory.put(updatedItem);
      inventory = await db.inventory.toArray();
      loadStockTable();
      document.getElementById('add-stock-btn').textContent = 'Add to Inventory';
      document.getElementById('add-stock-btn').onclick = addStockItem;
      document.getElementById('stockCode').value = '';
      document.getElementById('stockHSN').value = '';
      document.getElementById('stockDescription').value = '';
      document.getElementById('stockPrice').value = '';
      document.getElementById('stockUnit').value = 'PCS';
      document.getElementById('stockQuantity').value = '';
      document.getElementById('stockSGST').value = '9';
      document.getElementById('stockCGST').value = '9';
      document.getElementById('stockDiscountType').value = 'percent';
      document.getElementById('stockDiscount').value = '0';
      document.getElementById('stockBarcode').value = '';
      showStatus('Item updated successfully!', 'success');
    } catch (error) {
      showStatus('Error updating stock item: ' + error.message, 'error');
    }
  };
}

// Delete stock item
async function deleteStockItem(code) {
  if (confirm('Are you sure you want to delete this item?')) {
    try {
      await db.inventory.delete(code);
      inventory = await db.inventory.toArray();
      loadStockTable();
      showStatus('Item deleted successfully!', 'success');
    } catch (error) {
      showStatus('Error deleting stock item: ' + error.message, 'error');
    }
  }
}

// Add customer
async function addCustomer() {
  try {
    const customer = {
      contact: sanitizeInput(document.getElementById('newCustomerContact').value),
      name: sanitizeInput(document.getElementById('newCustomerName').value),
      email: sanitizeInput(document.getElementById('newCustomerEmail').value),
      address: sanitizeInput(document.getElementById('newCustomerAddress').value)
    };

    if (!customer.contact || !customer.name) {
      showStatus('Please fill in contact number and name.', 'error');
      return;
    }

    if (customerDatabase.some(c => c.contact === customer.contact)) {
      showStatus('Customer with this contact number already exists.', 'error');
      return;
    }

    await db.customers.put(customer);
    customerDatabase = await db.customers.toArray();
    loadCustomerTable();
    document.getElementById('newCustomerContact').value = '';
    document.getElementById('newCustomerName').value = '';
    document.getElementById('newCustomerEmail').value = '';
    document.getElementById('newCustomerAddress').value = '';
    showStatus('Customer added successfully!', 'success');
    updateDashboard();
  } catch (error) {
    showStatus('Error adding customer: ' + error.message, 'error');
  }
}

// Load customer table
async function loadCustomerTable() {
  try {
    const customerTableBody = document.getElementById('customerTableBody');
    customerTableBody.innerHTML = '';
    customerDatabase = await db.customers.toArray();
    customerDatabase.forEach((customer, index) => {
      const row = document.createElement('tr');
      row.innerHTML = `
        <td>${sanitizeInput(customer.contact)}</td>
        <td>${sanitizeInput(customer.name)}</td>
        <td>${sanitizeInput(customer.email)}</td>
        <td>${sanitizeInput(customer.address)}</td>
        <td>
          <button class="edit-btn" onclick="editCustomer('${customer.contact}')">Edit</button>
          <button class="delete-btn" onclick="deleteCustomer('${customer.contact}')">Delete</button>
        </td>
      `;
      customerTableBody.appendChild(row);
    });
  } catch (error) {
    showStatus('Error loading customer table: ' + error.message, 'error');
  }
}

// Edit customer
function editCustomer(contact) {
  const customer = customerDatabase.find(c => c.contact === contact);
  if (!customer) return;

  editingCustomerContact = contact;
  document.getElementById('editCustomerContact').value = customer.contact;
  document.getElementById('editCustomerName').value = customer.name;
  document.getElementById('editCustomerEmail').value = customer.email;
  document.getElementById('editCustomerAddress').value = customer.address;
  document.getElementById('editCustomerDialogOverlay').style.display = 'flex';
}

// Save edited customer
async function saveEditedCustomer() {
  try {
    const updatedCustomer = {
      contact: sanitizeInput(document.getElementById('editCustomerContact').value),
      name: sanitizeInput(document.getElementById('editCustomerName').value),
      email: sanitizeInput(document.getElementById('editCustomerEmail').value),
      address: sanitizeInput(document.getElementById('editCustomerAddress').value)
    };

    if (!updatedCustomer.contact || !updatedCustomer.name) {
      showStatus('Please fill in contact number and name.', 'error');
      return;
    }

    if (updatedCustomer.contact !== editingCustomerContact && customerDatabase.some(c => c.contact === updatedCustomer.contact)) {
      showStatus('Customer with this contact number already exists.', 'error');
      return;
    }

    await db.customers.delete(editingCustomerContact);
    await db.customers.put(updatedCustomer);
    customerDatabase = await db.customers.toArray();
    loadCustomerTable();
    document.getElementById('editCustomerDialogOverlay').style.display = 'none';
    showStatus('Customer updated successfully!', 'success');
    editingCustomerContact = null;
  } catch (error) {
    showStatus('Error updating customer: ' + error.message, 'error');
  }
}

// Delete customer
async function deleteCustomer(contact) {
  if (confirm('Are you sure you want to delete this customer?')) {
    try {
      await db.customers.delete(contact);
      customerDatabase = await db.customers.toArray();
      loadCustomerTable();
      showStatus('Customer deleted successfully!', 'success');
    } catch (error) {
      showStatus('Error deleting customer: ' + error.message, 'error');
    }
  }
}

// Load customer history
async function loadCustomerHistory() {
  try {
    const contact = document.getElementById('historyContact').value;
    const historyTableBody = document.getElementById('customerHistoryTableBody');
    historyTableBody.innerHTML = '';
    const filteredInvoices = invoices.filter(inv => inv.clientContact === contact);

    if (filteredInvoices.length === 0) {
      showStatus('No invoices found for this customer.', 'error', 'historyStatusMessage');
      return;
    }

    filteredInvoices.forEach(invoice => {
      const row = document.createElement('tr');
      row.innerHTML = `
        <td>${sanitizeInput(invoice.invoiceNumber)}</td>
        <td>${invoice.invoiceDate}</td>
        <td>${sanitizeInput(invoice.clientName)}</td>
        <td>₹${invoice.grandTotal.toFixed(2)}</td>
        <td>
          <button class="toggle-items-btn" onclick="toggleInvoiceItems(this, '${invoice.invoiceNumber}')">Show Items</button>
        </td>
      `;
      const itemsRow = document.createElement('tr');
      itemsRow.className = 'items-details';
      itemsRow.innerHTML = `
        <td colspan="5">
          <table class="item-table">
            <thead>
              <tr>
                <th>Code</th>
                <th>Description</th>
                <th>Unit</th>
                <th>Qty</th>
                <th>Rate</th>
                <th>Discount</th>
                <th>SGST %</th>
                <th>CGST %</th>
                <th>Total</th>
              </tr>
            </thead>
            <tbody>
              ${invoice.items.map(item => `
                <tr>
                  <td>${sanitizeInput(item.code)}</td>
                  <td>${sanitizeInput(item.description)}</td>
                  <td>${item.unit}</td>
                  <td>${item.quantity}</td>
                  <td>₹${item.rate.toFixed(2)}</td>
                  <td>${item.discountType === 'percent' ? `${item.discount}%` : `₹${item.discount.toFixed(2)}`}</td>
                  <td>${item.sgst}%</td>
                  <td>${item.cgst}%</td>
                  <td>₹${item.total.toFixed(2)}</td>
                </tr>
              `).join('')}
            </tbody>
          </table>
        </td>
      `;
      historyTableBody.appendChild(row);
      historyTableBody.appendChild(itemsRow);
    });
    showStatus('Customer history loaded successfully!', 'success', 'historyStatusMessage');
  } catch (error) {
    showStatus('Error loading customer history: ' + error.message, 'error', 'historyStatusMessage');
  }
}

// Toggle invoice items in customer history
function toggleInvoiceItems(button, invoiceNumber) {
  const row = button.closest('tr');
  const itemsRow = row.nextElementSibling;
  if (itemsRow.classList.contains('active')) {
    itemsRow.classList.remove('active');
    button.textContent = 'Show Items';
  } else {
    itemsRow.classList.add('active');
    button.textContent = 'Hide Items';
  }
}

// Customer history contact autocomplete
function setupHistoryContactAutocomplete() {
  const contactInput = document.getElementById('historyContact');
  const dropdown = document.getElementById('historyContactDropdown');
  contactInput.addEventListener('input', debounce(async () => {
    const query = contactInput.value.toLowerCase();
    dropdown.innerHTML = '';
    if (query.length < 1) {
      dropdown.style.display = 'none';
      return;
    }
    const filtered = customerDatabase.filter(customer =>
      customer.contact.toLowerCase().includes(query) ||
      customer.name.toLowerCase().includes(query)
    );
    filtered.forEach(customer => {
      const div = document.createElement('div');
      div.className = 'dropdown-item';
      div.textContent = `${customer.contact} - ${customer.name}`;
      div.addEventListener('click', () => {
        contactInput.value = customer.contact;
        dropdown.style.display = 'none';
        loadCustomerHistory();
      });
      dropdown.appendChild(div);
    });
    dropdown.style.display = filtered.length ? 'block' : 'none';
  }, 300));
}

// Open item dialog
async function openItemDialog() {
  try {
    const itemsList = document.getElementById('itemsList2');
    itemsList.innerHTML = '';
    filteredInventory = await db.inventory.toArray();
    filteredInventory.forEach(item => {
      const discDisplay = item.discountType === 'percent' ? `${item.discount}%` : `₹${item.discount.toFixed(2)}`;
      const row = document.createElement('tr');
      row.innerHTML = `
        <td>${sanitizeInput(item.code)}</td>
        <td>${sanitizeInput(item.name)}</td>
        <td>${sanitizeInput(item.description)}</td>
        <td>₹${item.price.toFixed(2)}</td>
        <td>${item.sgst}%</td>
        <td>${item.cgst}%</td>
        <td>${discDisplay}</td>
      `;
      row.addEventListener('click', () => {
        const newRow = addItem();
        newRow.querySelector('.item-code').value = item.code;
        newRow.querySelector('.item-desc').value = item.description;
        newRow.querySelector('.item-rate').value = item.price.toFixed(2);
        newRow.querySelector('.item-unit').value = item.unit;
        newRow.querySelector('.item-sgst').value = item.sgst;
        newRow.querySelector('.item-cgst').value = item.cgst;
        newRow.querySelector('.item-disc').value = item.discount;
        newRow.querySelector('.disc-type-select').value = item.discountType;
        [newRow.querySelector('.item-desc'), newRow.querySelector('.item-rate'), newRow.querySelector('.item-unit'),
         newRow.querySelector('.item-sgst'), newRow.querySelector('.item-cgst'), newRow.querySelector('.item-disc'),
         newRow.querySelector('.disc-type-select')].forEach(el => el.classList.add('auto-populated'));
        updateItemTotal(newRow);
        updateItemTotals();
        
      });
      itemsList.appendChild(row);
    });
    document.getElementById('dialogOverlay').style.display = 'flex';
  } catch (error) {
    showStatus('Error opening item dialog: ' + error.message, 'error');
  }
}

// Search items in dialog
async function searchItems() {
  try {
    const query = document.getElementById('searchInput').value.toLowerCase();
    const itemsList = document.getElementById('itemsList2');
    itemsList.innerHTML = '';
    filteredInventory = inventory.filter(item =>
      item.code.toLowerCase().includes(query) ||
      item.description.toLowerCase().includes(query) ||
      (item.barcode && item.barcode.toLowerCase().includes(query))
    );
    filteredInventory.forEach(item => {
      const discDisplay = item.discountType === 'percent' ? `${item.discount}%` : `₹${item.discount.toFixed(2)}`;
      const row = document.createElement('tr');
      row.innerHTML = `
        <td>${sanitizeInput(item.code)}</td>
        <td>${sanitizeInput(item.name)}</td>
        <td>${sanitizeInput(item.description)}</td>
        <td>₹${item.price.toFixed(2)}</td>
        <td>${item.sgst}%</td>
        <td>${item.cgst}%</td>
        <td>${discDisplay}</td>
      `;
      row.addEventListener('click', () => {
        const newRow = addItem();
        newRow.querySelector('.item-code').value = item.code;
        newRow.querySelector('.item-desc').value = item.description;
        newRow.querySelector('.item-rate').value = item.price.toFixed(2);
        newRow.querySelector('.item-unit').value = item.unit;
        newRow.querySelector('.item-sgst').value = item.sgst;
        newRow.querySelector('.item-cgst').value = item.cgst;
        newRow.querySelector('.item-disc').value = item.discount;
        newRow.querySelector('.disc-type-select').value = item.discountType;
        [newRow.querySelector('.item-desc'), newRow.querySelector('.item-rate'), newRow.querySelector('.item-unit'),
         newRow.querySelector('.item-sgst'), newRow.querySelector('.item-cgst'), newRow.querySelector('.item-disc'),
         newRow.querySelector('.disc-type-select')].forEach(el => el.classList.add('auto-populated'));
        updateItemTotal(newRow);
        updateItemTotals();
        document.getElementById('dialogOverlay').style.display = 'none';
      });
      itemsList.appendChild(row);
    });
  } catch (error) {
    showStatus('Error searching items: ' + error.message, 'error');
  }
}

// Close dialog
function closeDialog(event, overlayId) {
  if (event && event.target.id !== overlayId) return;
  document.getElementById(overlayId).style.display = 'none';
}

// Apply custom dialog size
function applyCustomSize(dialogId, widthInputId, heightInputId) {
  const dialog = document.getElementById(dialogId);
  const width = parseInt(document.getElementById(widthInputId).value);
  const height = parseInt(document.getElementById(heightInputId).value);
  if (width >= 300 && width <= 1200 && height >= 200 && height <= 800) {
    dialog.style.width = `${width}px`;
    dialog.style.height = `${height}px`;
  } else {
    showStatus('Width must be between 300-1200px and height between 200-800px.', 'error');
  }
}

// Quick resize dialog
function quickResize(width, height, dialogId, widthInputId, heightInputId) {
  document.getElementById(dialogId).style.width = `${width}px`;
  document.getElementById(dialogId).style.height = `${height}px`;
  document.getElementById(widthInputId).value = width;
  document.getElementById(heightInputId).value = height;
}

// Backup all data
async function backupData() {
  try {
    const data = {
      inventory: await db.inventory.toArray(),
      customers: await db.customers.toArray(),
      invoices: await db.invoices.toArray()
    };
    const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `invoice_backup_${new Date().toISOString().split('T')[0]}.json`;
    a.click();
    URL.revokeObjectURL(url);
    showStatus('Backup created successfully!', 'success', 'backupStatusMessage');
  } catch (error) {
    showStatus('Error creating backup: ' + error.message, 'error', 'backupStatusMessage');
  }
}

// Restore all data
async function restoreData() {
  try {
    const fileInput = document.getElementById('restoreFileInput');
    const file = fileInput.files[0];
    if (!file) {
      showStatus('Please select a backup file.', 'error', 'backupStatusMessage');
      return;
    }
    const text = await file.text();
    const data = JSON.parse(text);

    await db.inventory.clear();
    await db.customers.clear();
    await db.invoices.clear();
    if (data.inventory) await db.inventory.bulkPut(data.inventory);
    if (data.customers) await db.customers.bulkPut(data.customers);
    if (data.invoices) await db.invoices.bulkPut(data.invoices);

    await loadDataFromIndexedDB();
    loadStockTable();
    loadCustomerTable();
    updateDashboard();
    showStatus('Data restored successfully!', 'success', 'backupStatusMessage');
    fileInput.value = '';
  } catch (error) {
    showStatus('Error restoring data: ' + error.message, 'error', 'backupStatusMessage');
  }
}

// Backup stock data
async function backupStockData() {
  try {
    const data = await db.inventory.toArray();
    const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `stock_backup_${new Date().toISOString().split('T')[0]}.json`;
    a.click();
    URL.revokeObjectURL(url);
    showStatus('Stock backup created successfully!', 'success', 'backupStatusMessage');
  } catch (error) {
    showStatus('Error creating stock backup: ' + error.message, 'error', 'backupStatusMessage');
  }
}

// Restore stock data
async function restoreStockData() {
  try {
    const fileInput = document.getElementById('restoreStockFileInput');
    const file = fileInput.files[0];
    if (!file) {
      showStatus('Please select a stock backup file.', 'error', 'backupStatusMessage');
      return;
    }
    const text = await file.text();
    const data = JSON.parse(text);

    await db.inventory.clear();
    await db.inventory.bulkPut(data);
    inventory = await db.inventory.toArray();
    loadStockTable();
    showStatus('Stock data restored successfully!', 'success', 'backupStatusMessage');
    fileInput.value = '';
  } catch (error) {
    showStatus('Error restoring stock data: ' + error.message, 'error', 'backupStatusMessage');
  }
}

// Backup customer data
async function backupCustomerData() {
  try {
    const data = await db.customers.toArray();
    const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `customer_backup_${new Date().toISOString().split('T')[0]}.json`;
    a.click();
    URL.revokeObjectURL(url);
    showStatus('Customer backup created successfully!', 'success', 'backupStatusMessage');
  } catch (error) {
    showStatus('Error creating customer backup: ' + error.message, 'error', 'backupStatusMessage');
  }
}

// Restore customer data
async function restoreCustomerData() {
  try {
    const fileInput = document.getElementById('restoreCustomerFileInput');
    const file = fileInput.files[0];
    if (!file) {
      showStatus('Please select a customer backup file.', 'error', 'backupStatusMessage');
      return;
    }
    const text = await file.text();
    const data = JSON.parse(text);

    await db.customers.clear();
    await db.customers.bulkPut(data);
    customerDatabase = await db.customers.toArray();
    loadCustomerTable();
    showStatus('Customer data restored successfully!', 'success', 'backupStatusMessage');
    fileInput.value = '';
  } catch (error) {
    showStatus('Error restoring customer data: ' + error.message, 'error', 'backupStatusMessage');
  }
}

// Export invoices to CSV
function exportInvoicesToCSV() {
  if (invoices.length === 0) {
    showStatus('No invoices to export.', 'error');
    return;
  }

  let csv = 'Invoice Number,Invoice Date,Due Date,Client Name,Client Contact,Client Email,Client Address,Item Code,Item Description,Item Unit,Item Quantity,Item Rate,Item Discount Type,Item Discount,Item SGST,Item CGST,Item Total,Invoice Subtotal,Invoice Total Discount,Invoice Total SGST,Invoice Total CGST,Invoice Grand Total\n';
  
  invoices.forEach(invoice => {
    invoice.items.forEach(item => {
      csv += `"${invoice.invoiceNumber}","${invoice.invoiceDate}","${invoice.dueDate}","${invoice.clientName.replace(/"/g, '""')}","${invoice.clientContact.replace(/"/g, '""')}","${invoice.clientEmail.replace(/"/g, '""')}","${invoice.clientAddress.replace(/"/g, '""')}","${item.code.replace(/"/g, '""')}","${item.description.replace(/"/g, '""')}","${item.unit}","${item.quantity}","${item.rate.toFixed(2)}","${item.discountType}","${item.discount.toFixed(2)}","${item.sgst.toFixed(2)}","${item.cgst.toFixed(2)}","${item.total.toFixed(2)}","${invoice.subtotal.toFixed(2)}","${invoice.totalDiscount.toFixed(2)}","${invoice.totalSGST.toFixed(2)}","${invoice.totalCGST.toFixed(2)}","${invoice.grandTotal.toFixed(2)}"\n`;
    });
  });

  const blob = new Blob([csv], { type: 'text/csv' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `invoices_${new Date().toISOString().slice(0, 10)}.csv`;
  a.click();
  URL.revokeObjectURL(url);
  showStatus('Invoices exported to CSV successfully!', 'success');
}
// Generate WhatsApp message
function generateWhatsAppMessage() {
  const whatsappNumber = document.getElementById('whatsappNumber').value;
  const maxDescLength = parseInt(document.getElementById('whatsappDescLength').value) || 20;
  const gstEnabled = document.getElementById('gstEnabled').checked;
  const companyName = document.getElementById('companyName').value || 'Your Company Name';
  const invoiceNumber = document.getElementById('invoiceNumber').value;
  const clientName = document.getElementById('clientName').value;
  const invoiceDate = document.getElementById('invoiceDate').value;
  let message = `Invoice from *${companyName}*\n`;
  message += `Invoice #: ${invoiceNumber}\n`;
  message += `Date: ${invoiceDate}\n`;
  message += `To: ${clientName}\n\n`;
  message += `Items:\n`;

  let grandTotal = 0;
  let totalDiscount = 0;

  document.querySelectorAll('.item-row').forEach(row => {
    const desc = row.querySelector('.item-desc').value;
    const qty = parseFloat(row.querySelector('.item-qty').value) || 0;
    const rate = parseFloat(row.querySelector('.item-rate').value) || 0;
    const discType = row.querySelector('.disc-type-select').value;
    const disc = parseFloat(row.querySelector('.item-disc').value) || 0;
    const sgst = parseFloat(row.querySelector('.item-sgst').value) || 0;
    const cgst = parseFloat(row.querySelector('.item-cgst').value) || 0;

    const subtotalAmount = qty * rate;
    const discAmount = discType === 'percent' ? subtotalAmount * (disc / 100) : disc;
    const afterDisc = subtotalAmount - discAmount;
    const sgstAmount = afterDisc * (sgst / 100);
    const cgstAmount = afterDisc * (cgst / 100);
    const lineTotal = afterDisc + sgstAmount + cgstAmount;

    totalDiscount += discAmount;

    const shortDesc = desc.length > maxDescLength ? desc.substring(0, maxDescLength) + '...' : desc;
    message += `- ${shortDesc} (Qty: ${qty}, Rate: ₹${rate.toFixed(2)})`;
    message += `, Discount: ${discType === 'percent' ? `${disc}%` : `₹${disc.toFixed(2)}`}`; // Add discount
    if (gstEnabled) {
      message += `, SGST: ${sgst}%, CGST: ${cgst}%`;
    }
    message += ` = ₹${lineTotal.toFixed(2)}\n`;
    grandTotal += lineTotal;
  });

  message += `\nTotal Discount: ₹${totalDiscount.toFixed(2)}\n`; // Add total discount
  message += `Grand Total: ₹${grandTotal.toFixed(2)}\n`;
  message += `Thank you for your business!`;

  const preview = document.getElementById('whatsappPreview');
  preview.textContent = message;
  preview.style.display = 'block';
}
// Send WhatsApp message
function sendWhatsApp() {
  const whatsappNumber = document.getElementById('whatsappNumber').value;
  const preview = document.getElementById('whatsappPreview').textContent;
  if (!whatsappNumber) {
    showStatus('Please enter a WhatsApp number.', 'error');
    return;
  }
  const encodedMessage = encodeURIComponent(preview);
  const url = `https://wa.me/${whatsappNumber.replace('+', '')}?text=${encodedMessage}`;
  window.open(url, '_blank');
}

// Logo handling
let isDragging = false, isResizing = false, currentHandle = null;
let startX, startY, startWidth, startHeight, startLeft, startTop;

function setupLogoHandling() {
  const logoUpload = document.getElementById('logoUpload');
  const logoWidthInput = document.getElementById('logoWidth');
  const logoHeightInput = document.getElementById('logoHeight');
  const lockAspectRatio = document.getElementById('lockAspectRatio');

  logoUpload.addEventListener('change', (e) => {
    const file = e.target.files[0];
    if (file) {
      const reader = new FileReader();
      reader.onload = (event) => {
        const img = new Image();
        img.src = event.target.result;
        img.onload = () => {
          const logoContainer = document.createElement('div');
          logoContainer.className = 'invoice-logo';
          logoContainer.style.width = '100px';
          logoContainer.style.height = '100px';
          logoContainer.style.left = '20px';
          logoContainer.style.top = '20px';
          logoContainer.innerHTML = `
            <img src="${img.src}" alt="Logo">
            <div class="resize-handle top-left"></div>
            <div class="resize-handle top-right"></div>
            <div class="resize-handle bottom-left"></div>
            <div class="resize-handle bottom-right"></div>
          `;
          document.querySelector('.invoice-box').prepend(logoContainer);
          logoWidthInput.value = 100;
          logoHeightInput.value = 100;
          setupLogoInteractions(logoContainer, img);
        };
      };
      reader.readAsDataURL(file);
    }
  });

  logoWidthInput.addEventListener('input', () => {
    const logo = document.querySelector('.invoice-logo');
    if (logo) {
      let width = parseInt(logoWidthInput.value) || 100;
      if (lockAspectRatio.checked) {
        const img = logo.querySelector('img');
        const aspectRatio = img.naturalWidth / img.naturalHeight;
        logoHeightInput.value = Math.round(width / aspectRatio);
        logo.style.height = `${logoHeightInput.value}px`;
      }
      logo.style.width = `${width}px`;
    }
  });

  logoHeightInput.addEventListener('input', () => {
    const logo = document.querySelector('.invoice-logo');
    if (logo) {
      let height = parseInt(logoHeightInput.value) || 100;
      if (lockAspectRatio.checked) {
        const img = logo.querySelector('img');
        const aspectRatio = img.naturalWidth / img.naturalHeight;
        logoWidthInput.value = Math.round(height * aspectRatio);
        logo.style.width = `${logoWidthInput.value}px`;
      }
      logo.style.height = `${height}px`;
    }
  });
}

function setupLogoInteractions(logoContainer, img) {
  const logoWidthInput = document.getElementById('logoWidth');
  const logoHeightInput = document.getElementById('logoHeight');
  const lockAspectRatio = document.getElementById('lockAspectRatio');

  logoContainer.addEventListener('mousedown', (e) => {
    if (e.target.classList.contains('resize-handle')) {
      isResizing = true;
      currentHandle = e.target.className.split(' ')[1];
      startX = e.clientX;
      startY = e.clientY;
      startWidth = parseFloat(logoContainer.style.width);
      startHeight = parseFloat(logoContainer.style.height);
      startLeft = parseFloat(logoContainer.style.left);
      startTop = parseFloat(logoContainer.style.top);
    } else {
      isDragging = true;
      startX = e.clientX - parseFloat(logoContainer.style.left);
      startY = e.clientY - parseFloat(logoContainer.style.top);
      logoContainer.classList.add('active');
    }
    e.preventDefault();
  });

  document.addEventListener('mousemove', (e) => {
    if (isDragging) {
      logoContainer.style.left = `${e.clientX - startX}px`;
      logoContainer.style.top = `${e.clientY - startY}px`;
    } else if (isResizing) {
      let newWidth, newHeight, newLeft = startLeft, newTop = startTop;
      const deltaX = e.clientX - startX;
      const deltaY = e.clientY - startY;
      const aspectRatio = img.naturalWidth / img.naturalHeight;

      if (currentHandle.includes('top-left')) {
        newWidth = startWidth - deltaX;
        newHeight = lockAspectRatio.checked ? newWidth / aspectRatio : startHeight - deltaY;
        newLeft = startLeft + deltaX;
        newTop = lockAspectRatio.checked ? startTop + deltaX / aspectRatio : startTop + deltaY;
      } else if (currentHandle.includes('top-right')) {
        newWidth = startWidth + deltaX;
        newHeight = lockAspectRatio.checked ? newWidth / aspectRatio : startHeight - deltaY;
        newTop = lockAspectRatio.checked ? startTop + deltaX / aspectRatio : startTop + deltaY;
      } else if (currentHandle.includes('bottom-left')) {
        newWidth = startWidth - deltaX;
        newHeight = lockAspectRatio.checked ? newWidth / aspectRatio : startHeight + deltaY;
        newLeft = startLeft + deltaX;
      } else if (currentHandle.includes('bottom-right')) {
        newWidth = startWidth + deltaX;
        newHeight = lockAspectRatio.checked ? newWidth / aspectRatio : startHeight + deltaY;
      }

      if (newWidth >= 20 && newWidth <= 300 && newHeight >= 20 && newHeight <= 300) {
        logoContainer.style.width = `${newWidth}px`;
        logoContainer.style.height = `${newHeight}px`;
        logoContainer.style.left = `${newLeft}px`;
        logoContainer.style.top = `${newTop}px`;
        logoWidthInput.value = Math.round(newWidth);
        logoHeightInput.value = Math.round(newHeight);
      }
    }
  });

  document.addEventListener('mouseup', () => {
    isDragging = false;
    isResizing = false;
    currentHandle = null;
  });

  logoContainer.addEventListener('dblclick', () => {
    logoContainer.classList.toggle('active');
  });

  logoContainer.addEventListener('touchstart', (e) => {
    const touch = e.touches[0];
    if (e.target.classList.contains('resize-handle')) {
      isResizing = true;
      currentHandle = e.target.className.split(' ')[1];
      startX = touch.clientX;
      startY = touch.clientY;
      startWidth = parseFloat(logoContainer.style.width);
      startHeight = parseFloat(logoContainer.style.height);
      startLeft = parseFloat(logoContainer.style.left);
      startTop = parseFloat(logoContainer.style.top);
    } else {
      isDragging = true;
      startX = touch.clientX - parseFloat(logoContainer.style.left);
      startY = touch.clientY - parseFloat(logoContainer.style.top);
      logoContainer.classList.add('active');
    }
    e.preventDefault();
  });

  document.addEventListener('touchmove', (e) => {
    const touch = e.touches[0];
    if (isDragging) {
      logoContainer.style.left = `${touch.clientX - startX}px`;
      logoContainer.style.top = `${touch.clientY - startY}px`;
    } else if (isResizing) {
      let newWidth, newHeight, newLeft = startLeft, newTop = startTop;
      const deltaX = touch.clientX - startX;
      const deltaY = touch.clientY - startY;
      const aspectRatio = img.naturalWidth / img.naturalHeight;

      if (currentHandle.includes('top-left')) {
        newWidth = startWidth - deltaX;
        newHeight = lockAspectRatio.checked ? newWidth / aspectRatio : startHeight - deltaY;
        newLeft = startLeft + deltaX;
        newTop = lockAspectRatio.checked ? startTop + deltaX / aspectRatio : startTop + deltaY;
      } else if (currentHandle.includes('top-right')) {
        newWidth = startWidth + deltaX;
        newHeight = lockAspectRatio.checked ? newWidth / aspectRatio : startHeight - deltaY;
        newTop = lockAspectRatio.checked ? startTop + deltaX / aspectRatio : startTop + deltaY;
      } else if (currentHandle.includes('bottom-left')) {
        newWidth = startWidth - deltaX;
        newHeight = lockAspectRatio.checked ? newWidth / aspectRatio : startHeight + deltaY;
        newLeft = startLeft + deltaX;
      } else if (currentHandle.includes('bottom-right')) {
        newWidth = startWidth + deltaX;
        newHeight = lockAspectRatio.checked ? newWidth / aspectRatio : startHeight + deltaY;
      }

      if (newWidth >= 20 && newWidth <= 300 && newHeight >= 20 && newHeight <= 300) {
        logoContainer.style.width = `${newWidth}px`;
        logoContainer.style.height = `${newHeight}px`;
        logoContainer.style.left = `${newLeft}px`;
        logoContainer.style.top = `${newTop}px`;
        logoWidthInput.value = Math.round(newWidth);
        logoHeightInput.value = Math.round(newHeight);
      }
    }
  });

  document.addEventListener('touchend', () => {
    isDragging = false;
    isResizing = false;
    currentHandle = null;
  });
}

function resetLogoPosition() {
  const logo = document.querySelector('.invoice-logo');
  if (logo) {
    logo.style.left = '20px';
    logo.style.top = '20px';
    logo.style.width = '100px';
    logo.style.height = '100px';
    document.getElementById('logoWidth').value = 100;
    document.getElementById('logoHeight').value = 100;
  }
}

function removeLogo() {
  const logo = document.querySelector('.invoice-logo');
  if (logo) logo.remove();
  document.getElementById('logoUpload').value = '';
  document.getElementById('logoWidth').value = '';
  document.getElementById('logoHeight').value = '';
}

// Update dashboard
async function updateDashboard() {
  try {
    const dateRange = document.getElementById('dateRangeFilter').value;
    let fromDate, toDate = new Date();

    if (dateRange === 'custom') {
      fromDate = new Date(document.getElementById('fromDate').value);
      toDate = new Date(document.getElementById('toDate').value);
    } else {
      fromDate = new Date();
      fromDate.setDate(toDate.getDate() - parseInt(dateRange));
    }

    const filteredInvoices = invoices.filter(inv => {
      const invDate = new Date(inv.timestamp);
      return invDate >= fromDate && invDate <= toDate;
    });

    let totalRevenue = 0, totalOrders = filteredInvoices.length, totalProducts = 0, totalDiscount = 0;
    const productSales = {};

    filteredInvoices.forEach(invoice => {
      totalRevenue += invoice.grandTotal;
      totalDiscount += invoice.totalDiscount;
      invoice.items.forEach(item => {
        totalProducts += item.quantity;
        productSales[item.code] = (productSales[item.code] || 0) + item.quantity;
      });
    });

    const uniqueCustomers = new Set(filteredInvoices.map(inv => inv.clientContact)).size;

    document.getElementById('totalRevenue').textContent = `₹${totalRevenue.toFixed(2)}`;
    document.getElementById('totalOrders').textContent = totalOrders;
    document.getElementById('totalCustomers').textContent = uniqueCustomers;
    document.getElementById('totalProducts').textContent = totalProducts;
    document.getElementById('totalDiscount').textContent = `₹${totalDiscount.toFixed(2)}`;

    const topProductsList = document.getElementById('topProductsList');
    topProductsList.innerHTML = '';
    const sortedProducts = Object.entries(productSales)
      .sort((a, b) => b[1] - a[1])
      .slice(0, 5);
    sortedProducts.forEach(([code, qty]) => {
      const item = inventory.find(i => i.code === code);
      const div = document.createElement('div');
      div.textContent = `${item ? item.description : code}: ${qty} units`;
      div.addEventListener('click', () => {
        document.getElementById('stockCode').value = code;
        document.getElementById('nav-btn-stock').click();
      });
      topProductsList.appendChild(div);
    });

    const recentOrdersList = document.getElementById('recentOrdersList');
    recentOrdersList.innerHTML = '';
    filteredInvoices.slice(-5).reverse().forEach(invoice => {
      const div = document.createElement('div');
      div.textContent = `${invoice.invoiceNumber} - ${invoice.clientName}: ₹${invoice.grandTotal.toFixed(2)}`;
      div.addEventListener('click', () => {
        document.getElementById('historyContact').value = invoice.clientContact;
        document.getElementById('nav-btn-customer-history').click();
        loadCustomerHistory();
      });
      recentOrdersList.appendChild(div);
    });
  } catch (error) {
    showStatus('Error updating dashboard: ' + error.message, 'error');
  }
}

// Toggle custom date range
function toggleCustomDateRange() {
  const dateRange = document.getElementById('dateRangeFilter').value;
  const customDateRange = document.getElementById('customDateRange');
  customDateRange.classList.toggle('hidden', dateRange !== 'custom');
  updateDashboard();
}

// Clear invoices
async function clearInvoices() {
  if (confirm('Are you sure you want to clear all invoices? This action cannot be undone.')) {
    try {
      await db.invoices.clear();
      invoices = [];
      updateDashboard();
      showStatus('All invoices cleared successfully!', 'success');
    } catch (error) {
      showStatus('Error clearing invoices: ' + error.message, 'error');
    }
  }
}
// Clear screen (reset Invoice Generator form)
async function clearScreen() {
  try {
    // Reset company info
    document.getElementById('companyName').value = 'Your Company Name';
    document.getElementById('companyAddress').value = '123 Business Street, City, State - ZIP';
    document.getElementById('companyContact').value = 'Email: info@company.com\nPhone: +91 9037393709';

    // Reset client info
    document.getElementById('clientContact').value = '';
    document.getElementById('clientName').value = '';
    document.getElementById('clientEmail').value = '';
    document.getElementById('clientAddress').value = '';
    document.getElementById('whatsappNumber').value = '';

    // Reset invoice details
    document.getElementById('invoiceNumber').value = await generateInvoiceNumber();
    document.getElementById('invoiceDate').value = new Date().toISOString().split('T')[0];
    const dueDate = new Date();
    dueDate.setDate(dueDate.getDate() + 30);
    document.getElementById('dueDate').value = dueDate.toISOString().split('T')[0];

    // Reset items table to a single empty row
    const itemsList = document.getElementById('itemsList').querySelector('tbody');
    itemsList.innerHTML = '';
    addItem();

    // Remove logo
    removeLogo();

    // Update preview
    updateItemTotals();
    showStatus('Screen cleared successfully!', 'success');
  } catch (error) {
    showStatus('Error clearing screen: ' + error.message, 'error');
  }
}

// Barcode scanning function
function scanBarcode(callback) {
  document.getElementById('scanDialogOverlay').style.display = 'flex';
  Quagga.init({
    inputStream: {
      type: "LiveStream",
      target: document.querySelector('#barcodeScanner'),
      constraints: {
        facingMode: "environment"
      }
    },
    decoder: {
      readers: ["ean_reader", "upc_reader", "code_128_reader", "code_39_reader", "ean_8_reader"]
    }
  }, function(err) {
    if (err) {
      console.error(err);
      showStatus('Error initializing scanner: ' + err.message, 'error');
      closeDialog(null, 'scanDialogOverlay');
      return;
    }
    Quagga.start();
  });

  Quagga.onDetected(function(result) {
    const code = result.codeResult.code;
    Quagga.stop();
    closeDialog(null, 'scanDialogOverlay');
    callback(code);
  });
}

// Scan for invoice item addition
function scanForInvoice() {
  scanBarcode(function(code) {
    const item = inventory.find(i => i.barcode === code);
    if (item) {
      const newRow = addItem();
      newRow.querySelector('.item-code').value = item.code;
      newRow.querySelector('.item-desc').value = item.description;
      newRow.querySelector('.item-rate').value = item.price.toFixed(2);
      newRow.querySelector('.item-unit').value = item.unit;
      newRow.querySelector('.item-sgst').value = item.sgst;
      newRow.querySelector('.item-cgst').value = item.cgst;
      newRow.querySelector('.item-disc').value = item.discount;
      newRow.querySelector('.disc-type-select').value = item.discountType;
      [newRow.querySelector('.item-desc'), newRow.querySelector('.item-rate'), newRow.querySelector('.item-unit'),
       newRow.querySelector('.item-sgst'), newRow.querySelector('.item-cgst'), newRow.querySelector('.item-disc'),
       newRow.querySelector('.disc-type-select')].forEach(el => el.classList.add('auto-populated'));
      updateItemTotal(newRow);
      updateItemTotals();
    } else {
      showStatus('Item not found with barcode ' + code, 'error');
    }
  });
}

// Scan for stock barcode input
function scanForStock() {
  scanBarcode(function(code) {
    document.getElementById('stockBarcode').value = code;
  });
}

// Initialize application
async function init() {
  try {
    await migrateLocalStorageToIndexedDB();
    await loadDataFromIndexedDB();
    setupNavigation();
    setupClientAutocomplete();
    setupHistoryContactAutocomplete();
    setupLogoHandling();
    document.querySelectorAll('.item-row').forEach(row => {
      attachInputListeners(row);
      setupItemAutocomplete(row);
    });
    document.getElementById('invoiceDate').value = new Date().toISOString().split('T')[0];
    const dueDate = new Date();
    dueDate.setDate(dueDate.getDate() + 30);
    document.getElementById('dueDate').value = dueDate.toISOString().split('T')[0];
    document.getElementById('invoiceNumber').value = await generateInvoiceNumber();
    loadStockTable();
    loadCustomerTable();
    updateDashboard();
    updateItemTotals();
  } catch (error) {
    showStatus('Error initializing application: ' + error.message, 'error');
  }
}

document.addEventListener('DOMContentLoaded', init);
</script>
</body>
</html>

No comments:

Post a Comment