<?php
/**
 * Generation  invoice from  array data.
 * @param array $data_raw - array of data.
 * @return array -  code and url
 *
 * Example:

  $response_arr = ingen_api_generate_invoice(
                    array(
                            "invoice_number"        => "INV-2025-001",
                            "invoice_date"          => "2025-05-17",
                            "due_date"              => "2025-06-17",
                            "bill_from_name"        => "ZAaaaaaYyyyaaaaaa",
                            "bill_from_email"       => "tania@example.com",
                            "bill_from_description" => "Your company address or info here",
                            "bill_to_name"          => "Client Company",
                            "bill_to_email"         => "client@example.com",
                            "bill_to_description"   => "Client address or info here",
                            "currency"              => "USD",
                            "items" => array(
                                            array(
                                                    "name" => "Test Automation Service",
                                                    "qty" => 3,
                                                    "price" => 150.00
                                            ),
                                            array(
                                                    "name" => "Consulting",
                                                    "qty" => 2,
                                                    "price" => 100.00
                                            )
                                    ),
                            "tax_rate" => "1",
                            "table_class" => "invoice-table",
                            "template_style" => "blue-accent"

                    )
                  );
     if ( 200 === $response_arr['code'] ) {
        echo '<a href="'.esc_url($response_arr['pdf_url']).'">PDF link</a>';
     } else {
        echo 'Error code' . intval( $response_arr['code'] ) . '. Message: ' .  esc_html( $response_arr['error']  );
     }

 */

     if ( ! defined( 'ABSPATH' ) ) exit;

 function ingen_api_generate_invoice( $data_raw ) {

     $required_fields = array(
         'invoice_number',
         'invoice_date',
         'due_date',
         'bill_from_name',
         'bill_from_email',
         'bill_to_name',
         'bill_to_email',
         'currency',
         'items',
     );

     foreach ( $required_fields as $field ) {
             if ( ! isset( $data_raw[ $field ] ) || empty( $data_raw[ $field ] ) ) {
                 return array( 'error' => "Missing field: $field", 'code' => 400 );
             }
         }

    $tax_rate = isset( $data_raw['tax_rate'] ) ? floatval( $data_raw['tax_rate'] ) : 0;

     $data = array(
         'invoice_number' => sanitize_text_field($data_raw['invoice_number']),
         'invoice_date' => sanitize_text_field($data_raw['invoice_date']),
         'due_date' => sanitize_text_field($data_raw['due_date']),
         'bill_from_name' => sanitize_text_field($data_raw['bill_from_name']),
         'bill_from_email' => sanitize_email($data_raw['bill_from_email']),
         'bill_to_name' => sanitize_text_field($data_raw['bill_to_name']),
         'bill_to_email' => sanitize_email($data_raw['bill_to_email']),
         'currency' => sanitize_text_field($data_raw['currency']),
         'tax_rate' => $tax_rate,
         'bill_from_description' => isset($data_raw['bill_from_description']) ? sanitize_textarea_field($data_raw['bill_from_description']) : '',
         'bill_to_description' => isset($data_raw['bill_to_description']) ? sanitize_textarea_field($data_raw['bill_to_description']) : '',
         'items' => array(),
         'table_class' => isset($data_raw['table_class']) ? sanitize_text_field($data_raw['table_class']) : '',
         'template_style' => isset($data_raw['template_style']) ? sanitize_text_field($data_raw['template_style']) : '',
     );

     if ( is_array( $data_raw['items'] ) ) {
            foreach ( $data_raw['items'] as $index => $item ) {

                if ( ! isset( $item['name'] ) || empty( $item['name'] ) ) {
                    return array( 'error' => "Missing or empty item name at index $index", 'code' => 400 );
                }
                if ( ! isset( $item['price'] ) || ! is_numeric( $item['price'] ) ) {
                    return array( 'error' => "Invalid or missing item price at index $index", 'code' => 400 );
                }

                if ( isset( $item['qty'] ) && ! is_numeric( $item['qty'] ) ) {
                    return array( 'error' => "Invalid item quantity at index $index", 'code' => 400 );
                }

                $qty = isset( $item['qty'] ) ? intval( $item['qty'] ) : 1;

                $data['items'][] = array(
                    'name'  => sanitize_text_field( $item['name'] ),
                    'qty'   => $qty,
                    'price' => floatval( $item['price'] ),
                );
            }
        } else {
            return array( 'error' => 'Items field must be an array', 'code' => 400 );
        }



     $pdf_path = ingen_generate_pdf_from_data($data);

     if (!$pdf_path) {
         return array('error' => esc_html__('Failed to generate PDF'), 'code' => 500);
     }

     return array(
         'pdf_url' => esc_url($pdf_path),
         'code' => 200,
     );
 }


 function ingen_generate_pdf_from_data($data) {

     $invoice_number = sanitize_text_field($data['invoice_number']);
     $invoice_date = sanitize_text_field($data['invoice_date']);
     $due_date = sanitize_text_field($data['due_date']);
     $bill_from_name = sanitize_text_field($data['bill_from_name']);
     $bill_from_email = sanitize_email($data['bill_from_email']);
     $bill_from_description = isset($data['bill_from_description']) ? sanitize_textarea_field($data['bill_from_description']) : '';
     $bill_to_name = sanitize_text_field($data['bill_to_name']);
     $bill_to_email = sanitize_email($data['bill_to_email']);
     $bill_to_description = isset($data['bill_to_description']) ? sanitize_textarea_field($data['bill_to_description']) : '';
     $currency = sanitize_text_field($data['currency']);
     $tax_rate_raw = trim($data['tax_rate']);
     $tax_rate = $tax_rate_raw === '' ? 0 : floatval($tax_rate_raw);
     $items = array();
     $table_class = isset($data['table_class']) ? sanitize_text_field($data['table_class']) : '';
     $template_style = isset($data['template_style']) ? sanitize_text_field($data['template_style']) : '';


     if (!filter_var($bill_from_email, FILTER_VALIDATE_EMAIL)) {
         return array('error' => esc_html('Invalid bill_from_email'), 'code' => 400);
     }

     if (!filter_var($bill_to_email, FILTER_VALIDATE_EMAIL)) {
         return array('error' => esc_html('Invalid bill_to_email'), 'code' => 400);
     }

     foreach (array('invoice_date' => $invoice_date, 'due_date' => $due_date) as $field => $value) {
         if (!strtotime($value)) {
             return array('error' => esc_html("Invalid date format in $field"), 'code' => 400);
         }
     }

     if (!is_array($data['items']) || empty($data['items'])) {
         return array('error' => esc_html('Items must be a non-empty array'), 'code' => 400);
     }

     foreach ($data['items'] as $i => $item) {
         if (
             empty($item['name']) ||
             !isset($item['qty']) || !is_numeric($item['qty']) ||
             !isset($item['price']) || !is_numeric($item['price'])
         ) {
             return array('error' => esc_html("Invalid item at index $i"), 'code' => 400);
         }

         $items[] = array(
             'name' => sanitize_text_field($item['name']),
             'qty' => floatval($item['qty']),
             'price' => floatval($item['price']),
         );
     }

     $allowed_currencies = array('USD', 'EUR', 'GBP', 'UAH', 'JPY', 'AUD', 'CAD', 'CHF', 'NZD', 'SEK', 'NOK', 'DKK', 'PLN', 'HUF', 'TRY', 'BRL', 'INR', 'RUB', 'CNY', 'MXN');
     if (!in_array($currency, $allowed_currencies)) {
         return array('error' => esc_html('Unsupported currency'), 'code' => 400);
     }

     if (!is_numeric($tax_rate) || $tax_rate < 0 || $tax_rate > 100) {
         return array('error' => esc_html('Invalid tax rate'), 'code' => 400);
     }

     $html = ingen_generate_invoice_html(
         $invoice_number,
         $invoice_date,
         $due_date,
         $bill_from_name,
         $bill_from_email,
         $bill_from_description,
         $bill_to_name,
         $bill_to_email,
         $bill_to_description,
         $currency,
         $tax_rate,
         $items,
         'ingen_render_items_with_calculated_totals',
          $table_class,
          $template_style
     );

        return ingen_generate_invoice_pdf($html, $invoice_number);
 }


function ingen_render_items_with_calculated_totals($items, $currency, $tax_rate) {
    $subtotal = 0;

    foreach ($items as $item) {
        $name = esc_html($item['name']);
        $qty = intval($item['qty']);
        $price = floatval($item['price']);
        $total = round($qty * $price, 2);
        $subtotal += $total;

        echo "<tr><td class='invoice_header_item'>{$name}</td><td>{$qty}</td><td>{$currency}" . number_format($price, 2) . "</td><td>{$currency}" . number_format($total, 2) . "</td></tr>";
    }

    $tax_amount = round($subtotal * ($tax_rate / 100), 2);
    ?> </tbody>
</table>
<div class="totals">
    <div class="line"></div>
    <p><strong><?php esc_html_e('SUBTOTAL', 'invoice-generator'); ?>:</strong> <?php echo esc_html($currency) . number_format($subtotal, 2); ?></p>
    <p><strong><?php esc_html_e('TAX', 'invoice-generator'); ?> (<?php echo floatval($tax_rate); ?>%):</strong> <?php echo esc_html($currency) . number_format($tax_amount, 2); ?></p>
    <p><strong class="total-amount"><?php esc_html_e('TOTAL', 'invoice-generator'); ?>:</strong> <span class="total-value"><?php echo esc_html($currency) . number_format($subtotal + $tax_amount, 2); ?></span></p>
</div> <?php
}

function ingen_generate_invoice_pdf($html, $invoice_number = null) {
    require_once INGEN_DIR_PATH . '/vendor/autoload.php';

    $options = new Dompdf\Options();
    $options->set('isRemoteEnabled', true);

    $upload_dir = wp_upload_dir();
    $temp_dir = $upload_dir['basedir'] . '/dompdf-temp';

    if (!file_exists($temp_dir)) {
       mkdir($temp_dir, 0755, true);
    }

    $options->set('chroot', realpath($upload_dir['basedir']));
    $options->set('tempDir', $temp_dir);

    $dompdf = new Dompdf\Dompdf($options);

    $dompdf->loadHtml($html);
    $dompdf->setPaper('A4', 'portrait');
    $dompdf->render();

    $upload_dir = wp_upload_dir();
    $invoices_dir = $upload_dir['basedir'] . '/invoices';

    if (!file_exists($invoices_dir)) {
        wp_mkdir_p($invoices_dir);
    }

    $filename = 'invoice_' . wp_date('Y-m-d-H-i-s');
    if ($invoice_number) {
        $filename .= '_' . sanitize_file_name($invoice_number);
    }
    $filename .= '.pdf';

    $filepath = $invoices_dir . '/' . $filename;
    $fileurl = $upload_dir['baseurl'] . '/invoices/' . $filename;

    file_put_contents($filepath, $dompdf->output());

    delete_temp_directory($temp_dir);

    return $fileurl;
}

function delete_temp_directory($dir) {
    if (!file_exists($dir)) return;

    $files = array_diff(scandir($dir), array('.', '..'));
    foreach ($files as $file) {
        $file_path = "$dir/$file";
        if (is_dir($file_path)) {
            delete_temp_directory($file_path);
        } else {
            unlink($file_path);
        }
    }
    rmdir($dir);
}
