<?php session_start();
/*  Copyright 2023 Flávio Ribeiro

    This file is part of OCOMON.

    OCOMON is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    OCOMON is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Foobar; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

if (!isset($_SESSION['s_logado']) || $_SESSION['s_logado'] == 0 || $_SESSION['s_nivel'] > 1) {
    $_SESSION['session_expired'] = 1;
    echo "<script>top.window.location = '../../index.php'</script>";
    exit;
}

require_once __DIR__ . "/" . "../../includes/include_basics_only.php";
require_once __DIR__ . "/" . "../../includes/classes/ConnectPDO.php";
require_once __DIR__ . "/" . "../../includes/components/dompdf/vendor/autoload.php";


use OcomonApi\Support\Email;
use includes\classes\ConnectPDO;
use Dompdf\Dompdf;


$conn = ConnectPDO::getInstance();

$auth = new AuthNew($_SESSION['s_logado'], $_SESSION['s_nivel'], 1);
$exception = "";
$data = [];
$data['success'] = true;
// $mailConfig = getMailConfig($conn);
// $data['sendEmailToAuthorizer'] = true;

$post = $_POST;
// var_dump($post); exit;


$invoice_id = "";
$data['csrf_session_key'] = (isset($post['csrf_session_key']) ? $post['csrf_session_key'] : "");

$data['issuance_date'] = (isset($post['issuance_date']) && !empty($post['issuance_date']) ? dateDB($post['issuance_date']) : "");
$data['due_date'] = (isset($post['due_date']) && !empty($post['due_date']) ? dateDB($post['due_date']) : "");

$data['service_descriptions'] = (isset($post['service_description']) && !empty($post['service_description']) ? array_map('noHtml', $post['service_description']) : []);
$data['amounts'] = (isset($post['amount']) && !empty($post['amount']) ? array_map('intval', $post['amount']) : []);
$data['unitary_prices'] = (isset($post['unitary_price']) && !empty($post['unitary_price']) ? array_map('priceDB', $post['unitary_price']) : []);


$data['invoice_number'] = (isset($post['invoice_number']) && !empty($post['invoice_number']) ? noHtml($post['invoice_number']) : "");
$data['tax_rate'] = (isset($post['tax_rate']) && !empty($post['tax_rate']) ? noHtml($post['tax_rate']) : null);
$data['issqn'] = (isset($post['issqn']) && !empty($post['issqn']) ? noHtml($post['issqn']) : null);
$data['discounts'] = (isset($post['discounts']) && !empty($post['discounts']) ? priceDB($post['discounts']) : null);
$data['invoice_model'] = (isset($post['invoice_model']) && !empty($post['invoice_model']) ? (int)$post['invoice_model'] : "");
$data['contractor_id'] = (isset($post['contractor_id']) && !empty($post['contractor_id']) ? (int)$post['contractor_id'] : "");
$data['contractor_organization'] = (isset($post['contractor_organization']) && !empty($post['contractor_organization']) ? (int)$post['contractor_organization'] : "");

$data['send_invoice'] = (isset($post['send_invoice']) ? ($post['send_invoice'] == "yes" ? 1 : 0) : 0);


if (empty($data['contractor_id'])) {
    $data['success'] = false; 
    $data['field_id'] = 'contractor_id';
    $data['message'] = message('warning', 'Ooops!', TRANS('SOME_ERROR_DONT_PROCEED'),'');
    echo json_encode($data);
    return false;
}


$contractor_info = getContractors($conn, $data['contractor_id']);
if (empty($contractor_info)) {
    $data['success'] = false; 
    $data['field_id'] = 'contractor_id';
    $data['message'] = message('warning', 'Ooops!', TRANS('ERROR_GETTING_CONTRACTOR_INFO'),'');
    echo json_encode($data);
    return false;
}


if (count($data['service_descriptions']) != count($data['unitary_prices'])) {
    $data['success'] = false; 
    $data['message'] = message('warning', 'Ooops!', TRANS('CHECK_FILLED_DATA'),'');

    echo json_encode($data);
    return false;
}

// if (empty($data['main_asset_id']) && empty($data['asset_units'])) {
//     $data['success'] = false; 
//     $data['message'] = message('warning', 'Ooops!', TRANS('AT_LEAST_ONE_ASSET_IS_REQUIRED'),'');
//     echo json_encode($data);
//     return false;
// }

function arrayHasDuplicates($array) {
    return count($array) !== count(array_unique($array));
}

/* Organizando os serviços descritos em um único array */
$invoice_items = [];

$subtotal_price = 0;
$i = 0;
$total_price = 0;
foreach ($data['service_descriptions'] as $key => $value) {
    $total_item = 0;

    $invoice_items[$i]['description'] = $value;
    $invoice_items[$i]['amount'] = $data['amounts'][$i];
    $invoice_items[$i]['unit_item_price'] = $data['unitary_prices'][$i];
    
    $total_item = $data['amounts'][$i] * $data['unitary_prices'][$i];
    $invoice_items[$i]['total_item'] = $total_item;
    $total_price += $data['amounts'][$i] * $data['unitary_prices'][$i];

    $i++;
}
$subtotal_price = $total_price;

if (!empty($data['discounts'])) {
    $total_price -= $data['discounts'];
}


// var_dump([
//     'contractor_info' => $contractor_info,
//     'data' => $data,
//     'invoice_items' => $invoice_items,
//     'total_price' => $total_price
// ]); exit;



if (empty($data['issuance_date'])) {
    $data['success'] = false; 
    $data['field_id'] = 'issuance_date';
    $data['message'] = message('warning', 'Ooops!', TRANS('MSG_EMPTY_DATA'),'');
    echo json_encode($data);
    return false;
} elseif (empty($data['due_date'])) {
    $data['success'] = false; 
    $data['field_id'] = 'due_date';
    $data['message'] = message('warning', 'Ooops!', TRANS('MSG_EMPTY_DATA'),'');
    echo json_encode($data);
    return false;
} elseif (empty($data['contractor_organization'])) {
    $data['success'] = false; 
    $data['field_id'] = 'contractor_organization';
    $data['message'] = message('warning', 'Ooops!', TRANS('MSG_EMPTY_DATA'),'');
    echo json_encode($data);
    return false;
} elseif (empty($data['service_descriptions'])) {
    $data['success'] = false; 
    $data['field_id'] = 'service_description';
    $data['message'] = message('warning', 'Ooops!', TRANS('MSG_EMPTY_DATA'),'');
    echo json_encode($data);
    return false;
} elseif (empty($data['amounts'])) {
    $data['success'] = false; 
    $data['field_id'] = 'amount';
    $data['message'] = message('warning', 'Ooops!', TRANS('MSG_EMPTY_DATA'),'');
    echo json_encode($data);
    return false;
} elseif (empty($data['unitary_prices'])) {
    $data['success'] = false; 
    $data['field_id'] = 'unitary_price';
    $data['message'] = message('warning', 'Ooops!', TRANS('MSG_EMPTY_DATA'),'');
    echo json_encode($data);
    return false;
} elseif (empty($data['invoice_number'])) {
    $data['success'] = false; 
    $data['field_id'] = 'invoice_number';
    $data['message'] = message('warning', 'Ooops!', TRANS('MSG_EMPTY_DATA'),'');
    echo json_encode($data);
    return false;
}

$data['invoice_number'] = str_replace(' ', '', $data['invoice_number']);



$authorInfo = getUserInfo($conn, $_SESSION['s_uid']);
if (empty($authorInfo)) {
    $data['success'] = false; 
    $data['message'] = message('warning', 'Ooops!', TRANS('SOME_ERROR_DONT_PROCEED') . $exception,'');
    echo json_encode($data);
    return false;
}



// var_dump([
//     'post' => $post,
//     'data' => $data,
//     'new_asset_ids' => $new_asset_ids,
//     'textNewAssetIds' => $textNewAssetIds
// ]); exit;


/* Checar se o número da invoice já existe */
$sql = "SELECT invoice_number FROM invoices WHERE invoice_number = '" . $data['invoice_number'] . "' ";
$res = $conn->query($sql);
if ($res->rowCount()) {
    $data['success'] = false; 
    $data['field_id'] = 'invoice_number';
    $data['message'] = message('warning', '', TRANS('MSG_INVOICE_EXISTS'), '');
    echo json_encode($data);
    return false;
}



if (!csrf_verify($post, $data['csrf_session_key'])) {
    $data['success'] = false; 
    $data['message'] = message('warning', 'Ooops!', TRANS('FORM_ALREADY_SENT'),'');

    echo json_encode($data);
    return false;
}


/**
 * Primeira parte: inserção das informações da fatura em invoices e invoice_items
 */
$sql = "INSERT 
        INTO
            invoices
        (
            invoice_number,
            contractor_id,
            issuance_date,
            due_date,
            tax_rate,
            issqn,
            discounts, 
            total_price,
            contractor_organization,
            author
        )
        VALUES
        (
            :invoice_number,
            :contractor_id,
            :issuance_date,
            :due_date,
            :tax_rate,
            :issqn,
            :discounts,
            :total_price,
            :contractor_organization,
            :author
        )
";
try {
    $res = $conn->prepare($sql);
    $res->bindParam(':invoice_number', $data['invoice_number'], PDO::PARAM_STR);
    $res->bindParam(':contractor_id', $contractor_info['id']);
    $res->bindParam(':issuance_date', $data['issuance_date']);
    $res->bindParam(':due_date', $data['due_date']);
    // $res->bindParam(':invoice_items', $invoice_items_id);
    $res->bindParam(':tax_rate', $data['tax_rate'], PDO::PARAM_INT);
    $res->bindParam(':issqn', $data['issqn']);
    $res->bindParam(':discounts', $data['discounts']);
    $res->bindParam(':total_price', $total_price);
    $res->bindParam(':contractor_organization', $data['contractor_organization'], PDO::PARAM_INT);
    $res->bindParam(':author', $authorInfo['id']);
    $res->execute();

    $invoice_id = $conn->lastInsertId();

    $data['invoice_id'] = $invoice_id;


} catch (\PDOException $e) {
    $data['success'] = false; 
    $exception .= "<hr />" .$e->getMessage();
    $data['message'] = message('warning', 'Ooops!', TRANS('SOME_ERROR_DONT_PROCEED') . $exception,'');
    echo json_encode($data);
    return false;
}



/**
 * Segunda parte, inserção em invoice_items
 */
foreach ($invoice_items as $item) {
    $sql = "INSERT INTO invoice_items 
            (
                invoice_id, 
                amount,
                description,
                unit_item_price
            ) 
            VALUES 
            (
                :invoice_id, 
                :amount,
                :description,
                :unit_item_price
            )";
    try {
        $res = $conn->prepare($sql);
        $res->bindParam(':invoice_id', $invoice_id);
        $res->bindParam(':amount', $item['amount']);
        $res->bindParam(':description', $item['description']);
        $res->bindParam(':unit_item_price', $item['unit_item_price']);
        $res->execute();


        
    } catch (\PDOException $e) {
        $data['success'] = false; 
        $exception .= "<hr />" .$e->getMessage();
        $data['message'] = message('warning', 'Ooops!', TRANS('SOME_ERROR_DONT_PROCEED') . $exception,'');
        echo json_encode($data);
        return false;
    }
}



/** 
 * Terceira parte: identificação e carregamento do modelo de fatura
*/

$invoice_model_info = getInvoiceModels($conn, $data['invoice_model']);

/**
 * Quarta parte: Processo para transpor as variáveis de ambiente
 * 
*/

$tableItems = '';

/**
 * Formatação para a geração do PDF
 */
$htmlTable = '';


$htmlTable .= '<table width="100%" cellpadding="5" cellspacing="0" style="border: 1px solid #000;">';
$htmlTable .= '<tr style="background-color: #f0f0f0;">';
$htmlTable .= '<th style="border: 1px solid #000; text-align: left;">' . TRANS('DESCRIPTION') . '</th>';
$htmlTable .= '<th style="border: 1px solid #000; text-align: center;">' . TRANS('COL_AMOUNT') . '</th>';
$htmlTable .= '<th style="border: 1px solid #000; text-align: center;">' . TRANS('UNITARY_PRICE') . '</th>';
$htmlTable .= '<th style="border: 1px solid #000; text-align: center;">' . TRANS('FINAL_PRICE') . '</th>';
$htmlTable .= '</tr>';



foreach ($invoice_items as $item) {
    /** Formatação para o PDF */
    $htmlTable .= '<tr>';
    $htmlTable .= '<td style="border: 1px solid #000;">' . $item['description'] . '</td>';
    $htmlTable .= '<td style="border: 1px solid #000; text-align: center;">' . $item['amount'] . '</td>';
    $htmlTable .= '<td style="border: 1px solid #000; text-align: right;">' . priceScreen($item['unit_item_price']) . '</td>';
    $htmlTable .= '<td style="border: 1px solid #000; text-align: right;">' . priceScreen($item['total_item']) . '</td>';
    $htmlTable .= '</tr>';
}
$htmlTable .= '</table>';

$availableVars = [];
$availableVars['%data_emissao%'] = $post['issuance_date'];
$availableVars['%data_vencimento%'] = $post['due_date'];
$availableVars['%prestador_contrato%'] = $contractor_info['contract_number'];
$availableVars['%prestador_razao_social%'] = mb_strtoupper($contractor_info['company_name']);
$availableVars['%prestador_nome%'] = $contractor_info['contact_name'];
$availableVars['%prestador_tipo_doc%'] = mb_strtoupper($contractor_info['document_type']);
$availableVars['%prestador_doc_numero%'] = $contractor_info['document_value'];
$availableVars['%prestador_insc_estado%'] = $contractor_info['state_registration'];
$availableVars['%prestador_insc_cidade%'] = $contractor_info['city_registration'];
$availableVars['%prestador_end_rua%'] = $contractor_info['addr_street'];
$availableVars['%prestador_end_numero%'] = $contractor_info['addr_number'];
$availableVars['%prestador_end_bairro%'] = $contractor_info['addr_neighborhood'];
$availableVars['%prestador_end_cidade%'] = $contractor_info['addr_city'];
$availableVars['%prestador_end_estado%'] = $contractor_info['addr_uf'];
$availableVars['%prestador_end_cep%'] = $contractor_info['addr_cep'];
$availableVars['%prestador_fone%'] = $contractor_info['contact_phone'];
$availableVars['%prestador_email%'] = $contractor_info['contact_email'];
$availableVars['%fatura_numero%'] = $data['invoice_number'];


$addressKeys = ['addr_street', 'addr_number', 'addr_complement', 'addr_neighborhood', 'addr_cep', 'addr_city', 'addr_uf'];
$locationArray = [];
foreach ($addressKeys as $key) {
    $locationArray[] = $contractor_info[$key];
}
$address = implode(" - ", array_filter($locationArray));

$availableVars['%prestador_endereco_completo%'] = $address;




$availableVars['%fatura_subtotal%'] = priceScreen($subtotal_price);
$availableVars['%fatura_tributacao%'] = $data['tax_rate'];
$availableVars['%fatura_issqn%'] = $data['issqn'];
$availableVars['%fatura_descontos%'] = priceScreen($data['discounts']);
$availableVars['%fatura_total%'] = priceScreen($total_price);


$availableVars['%fatura_itens%'] = $htmlTable;

$invoice_model_info['html_content'] = transvars($invoice_model_info['html_content'], $availableVars);



/**
 * Quinta parte: geração do arquivo pdf com base no modelo de fatura
 */

$dompdf = new Dompdf();
$dompdf->loadHtml($invoice_model_info['html_content']);
$dompdf->setPaper('A4', 'portrait');
// Render the HTML as PDF
$dompdf->render();
$output = $dompdf->output();

$dateString = date("ymdHis");
// $db_filename = generate_slug(TRANS('INVOICE')) . '_' . $dateString . '.pdf';
$db_filename = generate_slug(TRANS('INVOICE')) . '_' . $data['invoice_number'] . '.pdf';
$tmp_file_prefix = 'oc_';
$tmp_dir = sys_get_temp_dir();
$tmp_path_and_name = tempnam($tmp_dir, $tmp_file_prefix);

file_put_contents($tmp_path_and_name, $output);
$file_size = filesize($tmp_path_and_name);
$mime_type = "application/pdf";
/* Removendo o arquivo temporário */
unlink($tmp_path_and_name);


/**
 * Sexta parte: Gravar o arquivo no banco de dados
*/

$sql = "INSERT
        INTO
        invoice_files
        (
            invoice_id,
            file,
            filename,
            mime_type,
            file_size
        )
        VALUES
        (
            :invoice_id,
            :file,
            :file_name,
            :mime_type,
            :file_size
        )
";

try {
    $res = $conn->prepare($sql);
    $res->bindParam(':invoice_id', $invoice_id);
    $res->bindParam(':file', $output);
    $res->bindParam(':file_name', $db_filename);
    $res->bindParam(':mime_type', $mime_type);
    $res->bindParam(':file_size', $file_size);
    $res->execute();
} catch (\PDOException $e) {
    $data['success'] = false; 
    $exception .= "<hr />" .$e->getMessage();
    $data['message'] = message('warning', 'Ooops!', TRANS('SOME_ERROR_DONT_PROCEED') . $exception,'');
    echo json_encode($data);
    return false;
}


$data['success'] = true; 
$data['message'] = TRANS('MSG_SUCCESSFULLY_GENERATED_INVOICE');
$_SESSION['flash'] = message('success', '', $data['message'] . $exception, '');

echo json_encode($data);
// dump($return);
return true;

