<?php
include_once __dir__ . '/../vendor/autoload.php';
include_once __dir__ .  '/../core/AICore.php';
include_once __dir__ .  '/../core/CurriculoIACore.php';

use Smalot\PdfParser\Parser;
use Dompdf\Dompdf;

class ImportCurriculo extends Core
{
    use CurriculoIACore;

    const INSTRUCTION = array(
        "Analise o dados do currículo de candidatos para vagas de empregos e retorne as informações requisitadas nas regras abaixo:",
        "Deve ser retornado um JSON com o seguintes atributos:",
        "",
        '{	',
        '	"fullname": <nome do candidato>,',
        '   "birthdate": <data de nascimento do candidato - se houver (YYYY-MM-DD)>,',
        '	"email": <email do candidato - se houver>,',
        '   "phone": <telefone do candidato (somente números) - se houver>,',
        '	"street": <logradouro do candidato - se houver>,',
        '	"streetNumber": <número do logradouro do candidato - se houver>,',
        '   "city": <cidade do candidato - se houver>,',
        '   "state": <estado do candidato - se houver>,',
        '   "postalCode": <código postal do candidato - se houver>,',
        '	"educationHistoric": [',
        '        {',
        '            "name": <nome do curso>,',
        '            "institution": <nome da instituição de ensino>,',
        '            "startDate": <data do inicio do curso - formato YYYY-MM>,',
        '            "endDate": <data de termino do curso, se houver - formato YYYY-MM>,',
        '            "description": <uma descrição gerada com as informações do curso>',
        '        }',
        '    ],',
        '    "professionalHistoric": [',
        '        {',
        '            "name": <nome do cargo emprego>,',
        '            "company": <nome da empresa>,',
        '            "startDate": <data do inicio do emprego - formato YYYY-MM>,',
        '            "endDate": <data de termino do emprego, se houver - formato YYYY-MM>,',
        '            "description": <uma descrição gerada com as informações do cargo>',
        '        }',
        '    ]',
        '}',
        "",
        "Retorne os dados possíveis encontrado no texto informado, com correções ortográficas e melhorando a descrições dos cargos e escolaridade para gerar uma escrita formal e de qualidade para ser analisado pelos RH das empresas."
    );

    function upload() {
        try {
            
            if (!isset($_FILES['curriculos'])) {
                return ['type' => 'ERROR', 'message' => 'Nenhum arquivo enviado'];
            }

            $results = [];
            $process_id = $_POST['processId'] ?? null;
            $company_id = $_POST['companyId'] ?? null;
            $totalFiles = count($_FILES['curriculos']['name']);

            for ($i = 0; $i < $totalFiles; $i++) {

                if ($_FILES['curriculos']['error'][$i] !== UPLOAD_ERR_OK) {
                    $results[] = [
                        'file' => $_FILES['curriculos']['name'][$i],
                        'fileIndex' => $i,
                        'type' => 'ERROR',
                        'message' => 'Erro no upload'
                    ];
                    continue;
                }

                $tmpFile = $_FILES['curriculos']['tmp_name'][$i];

                $parser = new Parser();
                $pdf = $parser->parseFile($tmpFile);

                $text = '';
                foreach ($pdf->getPages() as $page) {
                    $text .= $page->getText();
                }

                if (!preg_match('//u', $text)) {
                    $text = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $text);
                }

                try {
                    $payload = $this->start(ImportCurriculo::INSTRUCTION, $text);
                    $json = json_decode($payload, true);
                    file_put_contents('CURRICULOS.txt', print_r($json, true));
                    $email = $json['email'] ?? null;
                    $fullname = $json['fullname'] ?? null;

                    if(!$fullname) {
                        $results[] = [
                            'file' => $_FILES['curriculos']['name'][$i],
                            'fileIndex' => $i,
                            'type' => 'ERROR',
                            'message' => 'Nome completo não encontrado'
                        ];
                        continue;
                    }

                    if(!$email) {
                        $results[] = [
                            'file' => $_FILES['curriculos']['name'][$i],
                            'fileIndex' => $i,
                            'type' => 'ERROR',
                            'message' => 'Email não encontrado'
                        ];
                        continue;
                    }


                    $sql = "SELECT id FROM leads WHERE email = :email";
                    $stmt = parent::$conn->prepare($sql);
                    $stmt->execute([':email' => $email]);
                    $lead = $stmt->fetch(PDO::FETCH_ASSOC);
                    $password = null;

                    if ($lead) {
                        $lead_id = $lead['id'];
                    } else {
                        list($lead_id, $password) = $this->insertCandidate($json);
                    }
                    
                    $this->saveCurriculoData($json, $lead_id);

                    if(isset($process_id)) {
                        $this->saveProcessListLead($process_id, $lead_id);
                    }

                    $filepath = __DIR__ . "/../uploads/curriculos/{$lead_id}.pdf";

                    if (move_uploaded_file($tmpFile, $filepath)) {
                        $this->saveLeadsCurriculo($lead_id, $text, $json, $filepath, $company_id);
                    }

                    $results[] = [
                        'file' => $_FILES['curriculos']['name'][$i],
                        'fileIndex' => $i,
                        'type' => 'OK',
                        'lead' => [
                            'id' => $lead_id,
                            'password' => $password
                        ],
                        'message' => 'Currículo importado com sucesso'
                    ];

                } catch (\Exception $err) {                    
                    $results[] = [
                        'file' => $_FILES['curriculos']['name'][$i],
                        'fileIndex' => $i,
                        'type' => 'ERROR',
                        'message' => 'Falha ao processar o currículo'
                    ];
                }

            }

            return [
                'type' => 'OK',
                'data' => $results
            ];

        } catch (\Exception $err) {
            return ['type' => 'ERROR', 'message' => $err->getMessage()];
        }
    }

    function saveLeads() {

        $leads = $_POST['leadIds'] ?? [];
        $company_id = $_POST['companyId'] ?? null;
        
        $leads = json_decode($leads, true);

        foreach ($leads as $lead_id) {
            $this->saveLeadsCurriculo($lead_id, null, null, null, $company_id);
        }

        return ['type' => 'OK'];

    }

    private function insertCandidate($data) {        

        $password = bin2hex(random_bytes(4));        

        $parts = explode(' ', $data['fullname']);
        $firstName = $parts[0];
        $lastName = $parts[1] ?? '';
        $white_lb_id = $this->config['WHITE_LABEL_ID'];
        $sql = "INSERT INTO leads(email, firstname, lastname, phone, address1, address2, city, state, zipcode, is_published, password, white_label_id) 
            VALUES(:email, :firstname, :lastname, :phone, :address1, :address2, :city, :state, :zipcode, 1, :password, :white_label_id)
        ";
        $stmt = parent::$conn->prepare($sql);
        $stmt->execute([
            ':email' => $data['email'],
            ':firstname' => $firstName,
            ':lastname' => $lastName,
            ':phone' => $data['phone'] ?? null,
            ':address1' => $data['street'] ?? null,
            ':address2' => $data['streetNumber'] ?? null,
            ':city' => $data['city'] ?? null,
            ':state' => $data['state'] ?? null,
            ':zipcode' => $data['postalCode'] ?? null,
            ':password' => $password,
            ':white_label_id' => $white_lb_id
        ]);
        $lead_id = parent::$conn->lastInsertId();

        return [ $lead_id, $password ];
    }

    private function saveLeadsCurriculo($lead_id, $text, $json, $filepath, $company_id) {

        $sql = "INSERT IGNORE INTO leads_curriculo(lead_id, content, `json`, `path`, company_id) 
            VALUES(:lead_id, :content, :json, :path, :company_id)";
        $stmt = parent::$conn->prepare($sql);
        $stmt->execute([
            ':lead_id' => $lead_id,
            ':content' => $text,
            ':json' => $json ? json_encode($json) : null,
            ':path' => $filepath,
            ':company_id' => $company_id
        ]);

    }

    private function saveProcessListLead($process_id, $lead_id) {
        
        $sql = "INSERT IGNORE INTO process_list_lead(process_list, lead) 
            VALUES(:process_list_id, :lead_id)";
        $stmt = parent::$conn->prepare($sql);
        $stmt->execute([
            ':process_list_id' => $process_id,
            ':lead_id' => $lead_id
        ]);

        if(parent::$conn->lastInsertId()) {
            $this->addToDefaultProcessStep($lead_id, $process_id);
        }

    }

    private function addToDefaultProcessStep($lead_id, $process_id) {

        $sql = "SELECT id FROM kanban_dashboard WHERE process_id = :process_id AND `default` = 1";
        $stmt = parent::$conn->prepare($sql);
        $stmt->execute([
            ':process_id' => $process_id
        ]);

        if ($stmt->rowCount() === 0) {
            $sql = "INSERT INTO kanban_dashboard(process_id, name, `order`, `default`) 
                VALUES(:process_id, 'Candidatos selecionados', -1, 1)";
            $stmt = parent::$conn->prepare($sql);
            $stmt->execute([':process_id' => $process_id]);
            $kanban_id = parent::$conn->lastInsertId();
        } else {
            $kanban_id = $stmt->fetchColumn();
        }

        $sql = "UPDATE process_list_lead SET kanban_step_id = :step_id  WHERE lead = :lead AND process_list = :process_list";        
            
        $stmt = parent::$conn->prepare($sql);
        $stmt->execute([
            ':step_id' => $kanban_id,           
            ':lead' => $lead_id,
            ':process_list' => $process_id
        ]);

    }

    function listCurriculos() {

        $company_id = $_GET['companyId'] ?? null;
        $search_term = $_GET['searchTerm'] ?? null;
        $page_index = $_GET['page'] ?? 1;
        $page_size = $_GET['pageSize'] ?? 50;

        $where = "WHERE company_id = :company_id AND company_id IS NOT NULL";

        if($search_term) {
            $where .= " AND (L.firstname LIKE :search_term OR L.lastname LIKE :search_term OR L.email LIKE :search_term)";
        }

        $sql = "SELECT LC.*, L.* FROM leads_curriculo AS LC 
            LEFT JOIN leads AS L ON LC.lead_id = L.id
            $where LIMIT :offset, :limit";
        $stmt = parent::$conn->prepare($sql);
        $stmt->bindValue(':company_id', $company_id);
        if($search_term) {
            $stmt->bindValue(':search_term', '%' . $search_term . '%', PDO::PARAM_STR);
        }
        $stmt->bindValue(':offset', ($page_index - 1) * $page_size, PDO::PARAM_INT);
        $stmt->bindValue(':limit', $page_size, PDO::PARAM_INT);
        $stmt->execute();
        $result =  $stmt->fetchAll(PDO::FETCH_ASSOC);

        return ['type' => 'OK', 'data' => $result];

    }

    function removeCurriculo() {

        $id = $_GET['id'] ?? null;
        
        if(!$id) {
            return ['type' => 'ERROR', 'message' => 'ID não informado'];
        }

        $sql = "DELETE FROM leads_curriculo WHERE curriculo_id = :id";
        $stmt = parent::$conn->prepare($sql);
        $stmt->execute([':id' => $id]);

        return ['type' => 'OK'];

    }

}