<?php

namespace App\Modules\Customer\Controllers;

use App\Core\View;
use App\Core\Security;
use App\Modules\Customer\Models\CustomerModel;

class CustomerController
{


    public function index()
    {
        $stats = (new CustomerModel())->getDashboardStats();

        View::render('Customer/Views/index', [
            'title' => 'Dashboard de Clientes',
            'stats' => $stats
        ]);
    }

    /**
     * Exibe o formulário de criação ou edição de cliente.
     * Se um ID é passado, busca os dados do cliente para preencher o formulário.
     */
    public function form($id = null)
    {
        $customerData = null;
        if ($id) {
            // Busca os dados do cliente existente para edição
            $customerData = (new CustomerModel())->pk($id)->consultar();
            if (!$customerData) {
                // Opcional: tratar cliente não encontrado, redirecionar ou mostrar erro.
                // Por enquanto, apenas exibirá um formulário vazio se não encontrar.
                // Uma melhoria seria mostrar uma mensagem de erro.
            }
        }

        View::render('Customer/Views/form', [
            'title' => $id ? 'Editar Cliente' : 'Novo Cliente',
            'csrf_token' => Security::generateCSRF(),
            'customer' => $customerData
        ]);
    }

    public function list()
    {

        header('Content-Type: application/json');
        try {
            $page = $_GET['page'] ?? 1;
            $page = filter_var($page, FILTER_VALIDATE_INT, ['options' => ['default' => 1, 'min_range' => 1]]);

            $paginationData = (new CustomerModel())
                ->logMetrics(true)
                ->paginacao($page, 10); // 10 itens por página

            echo json_encode(['success' => true, 'pagination' => $paginationData]);
        } catch (\Exception $e) {
            http_response_code(500);

            $messages = explode('||', $e->getMessage(), 2);
            $userMessage = $messages[0];
            $devMessage = $messages[1] ?? 'No developer message available.';

            echo json_encode([
                'success' => false,
                'message' => $userMessage,
                'messageDev' => $devMessage
            ]);
        }
    }

    public function get($id = null)
    {
        header('Content-Type: application/json');
        if (!is_numeric($id)) {
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => 'ID inválido.']);
            return;
        }
        try {
            $customer = (new CustomerModel())->pk($id)->consultar();
            if ($customer) {
                echo json_encode(['success' => true, 'data' => $customer]);
            } else {
                http_response_code(404);
                echo json_encode(['success' => false, 'message' => 'Cliente não encontrado.']);
            }
        } catch (\Exception $e) {
            http_response_code(500);

            $messages = explode('||', $e->getMessage(), 2);
            $userMessage = $messages[0];
            $devMessage = $messages[1] ?? 'No developer message available.';

            echo json_encode([
                'success' => false,
                'message' => $userMessage,
                'messageDev' => $devMessage
            ]);
        }
    }

    public function create()
    {
        Security::checkCSRFJson();
        header('Content-Type: application/json');
        $data = json_decode(file_get_contents('php://input'), true);

        if ($this->validateData($data) !== true) {
            return;
        }

        try {
            $customer = new CustomerModel();
            $mappedData = $this->mapToDbColumns($data);

            if ($customer->cadastrar($mappedData)) {
                $newCustomer = $customer->pk($customer->last_id)->consultar();
                http_response_code(201);
                echo json_encode(['success' => true, 'message' => 'Cliente cadastrado com sucesso!', 'data' => $newCustomer ?: null]);
            } else {
                throw new \Exception("Falha ao criar cliente no banco de dados.");
            }
        } catch (\Exception $e) {
            http_response_code(500);

            $messages = explode('||', $e->getMessage(), 2);
            $userMessage = $messages[0];
            $devMessage = $messages[1] ?? 'No developer message available.';

            echo json_encode([
                'success' => false,
                'message' => $userMessage,
                'messageDev' => $devMessage
            ]);
        }
    }

    public function update($id = null)
    {
        Security::checkCSRFJson();
        header('Content-Type: application/json');

        if (!is_numeric($id)) {
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => 'ID inválido.']);
            return;
        }

        $data = json_decode(file_get_contents('php://input'), true);

        if ($this->validateData($data, false) !== true) {
            return;
        }

        try {
            $customer = new CustomerModel();
            $mappedData = $this->mapToDbColumns($data);
            $mappedData['cliente_id'] = $id;

            if ($customer->alterar($mappedData)) {
                $updatedCustomer = (new CustomerModel())->pk($id)->consultar();
                echo json_encode(['success' => true, 'message' => 'Cliente atualizado com sucesso!', 'data' => $updatedCustomer ?: null]);
            } else {
                throw new \Exception("Nenhuma alteração foi feita. Os dados podem ser idênticos aos existentes ou o registro não foi encontrado.");
            }
        } catch (\Exception $e) {
            http_response_code(500);

            $messages = explode('||', $e->getMessage(), 2);
            $userMessage = $messages[0];
            $devMessage = $messages[1] ?? 'No developer message available.';

            echo json_encode([
                'success' => false,
                'message' => $userMessage,
                'messageDev' => $devMessage
            ]);
        }
    }

    public function delete($id = null)
    {
        Security::checkCSRFJson();
        header('Content-Type: application/json');

        if (!is_numeric($id)) {
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => 'ID inválido.']);
            return;
        }

        try {
            if ((new CustomerModel())->deletar($id)) {
                echo json_encode(['success' => true, 'message' => 'Cliente excluído com sucesso!']);
            } else {
                http_response_code(404);
                echo json_encode(['success' => false, 'message' => 'Cliente não encontrado ou já excluído.']);
            }
        } catch (\Exception $e) {
            http_response_code(500);

            $messages = explode('||', $e->getMessage(), 2);
            $userMessage = $messages[0];
            $devMessage = $messages[1] ?? 'No developer message available.';

            echo json_encode([
                'success' => false,
                'message' => $userMessage,
                'messageDev' => $devMessage
            ]);
        }
    }

    private function mapToDbColumns($data)
    {
        $map = [
            'name' => 'cliente_nome',
            'cpf' => 'cliente_cpf',
            'phone' => 'cliente_telefone',
            'address' => 'cliente_endereco',
            'credit_limit' => 'cliente_limiteCredito'
        ];
        $mappedData = [];
        foreach ($map as $apiKey => $dbColumn) {
            if (isset($data[$apiKey])) {
                $mappedData[$dbColumn] = $data[$apiKey];
            }
        }
        return $mappedData;
    }

    private function validateData($data, $isCreate = true)
    {
        if (empty($data['name'])) {
            http_response_code(400);
            echo json_encode(['success' => false, 'message' => 'O campo nome é obrigatório.']);
            return false;
        }

        if ($isCreate) {
            if (empty($data['cpf'])) {
                http_response_code(400);
                echo json_encode(['success' => false, 'message' => 'O campo CPF é obrigatório.']);
                return false;
            }

            if (!preg_match('/^\d{3}\.\d{3}\.\d{3}-\d{2}$/', $data['cpf'])) {
                http_response_code(400);
                echo json_encode(['success' => false, 'message' => 'Formato de CPF inválido. Use XXX.XXX.XXX-XX.']);
                return false;
            }

            if (CustomerModel::query()->and('cliente_cpf', $data['cpf'])->consultar()) {
                http_response_code(409); // Conflict
                echo json_encode(['success' => false, 'message' => 'CPF já cadastrado.']);
                return false;
            }
        }
        return true;
    }

}
