<?php
    namespace Zampet\Module\Tutor\v0\Controllers;

    use Zampet\Helpers\Sanitizer;
    use Zampet\Services\JWTService;
    use AxiumPHP\Helpers\RequestHelper;
    use Zampet\Module\Tutor\v0\DTO\PetDTO;
    use Zampet\Module\Tutor\v0\DTO\PetRacaDTO;
    use Zampet\Module\Tutor\v0\Services\PetService;

    class PetController {
        /**
         * Lida com a requisição para listar todas as espécies de pets disponíveis.
         *
         * Este método atua como um **controlador** para um endpoint de API. Ele delega a busca da lista completa de espécies para o `PetService` e, em seguida, formata e envia a resposta ao cliente em JSON.
         *
         * #### Fluxo de Operação:
         * 1.  **Delegação ao Serviço:** Uma instância de `PetService` é criada, e o método `getAllEspecies` é chamado para obter a lista de espécies. O serviço é responsável pela lógica de busca no modelo.
         * 2.  **Envio da Resposta JSON:** O resultado retornado pelo serviço (`especiesPets`) é formatado para uma resposta JSON padronizada usando **`RequestHelper::sendJsonResponse`**. Os dados da resposta (código HTTP, status, mensagem e lista de espécies) são comunicados ao cliente.
         *
         * @return void Este método não retorna um valor, pois seu objetivo é enviar uma resposta JSON e encerrar a execução do script.
         */
        public function getAllEspecies(): void {
            // Lista as espécies de pets
            $especiesPets = (new PetService())->getAllEspecies();

            // Retorna a resposta em JSON
            RequestHelper::sendJsonResponse(
                response_code: $especiesPets['response_code'], 
                status: $especiesPets['status'], 
                message: $especiesPets['message'], 
                output: $especiesPets['output'] ?? []
            );
            exit;
        }

        /**
         * Lista todos os pets associados ao usuário atualmente autenticado.
         *
         * Este método atua como um **controlador** para um endpoint de API, responsável por identificar o usuário autenticado, buscar a lista de seus pets e retornar os dados em formato JSON padronizado.
         *
         * #### Fluxo de Operação:
         * 1.  **Obtenção da Identidade do Usuário:** O método primeiro extrai e decodifica o token JWT presente no cabeçalho `Authorization` usando `JWTService::getBearerToken()` e `JWTService::decode()`. O UUID do usuário (tutor) é obtido diretamente do payload decodificado.
         * 2.  **Delegação ao Serviço:** O método `listPetsByTutorUuid` do **`PetService`** é chamado, passando o UUID do usuário para buscar todos os pets associados.
         * 3.  **Envio da Resposta JSON:** O resultado retornado pelo serviço (`petsTutor`) é formatado e enviado de volta ao cliente usando **`RequestHelper::sendJsonResponse`**.
         * * O código HTTP, status e mensagem são extraídos do array de resposta do serviço, garantindo que a resposta reflita o sucesso ou falha da operação de busca.
         *
         * @return void Este método não retorna um valor, pois seu objetivo é enviar uma resposta JSON e encerrar a execução do script.
         */
        public function listMyPets(): void {
            // Recebe o token JWT do cabeçalho Authorization
            $decodedToken = JWTService::decode(token: JWTService::getBearerToken());

            // Inicia o serviço de Pet
            $petsTutor = (new PetService())->listPetsByTutorUuid(uuid: $decodedToken['user_uuid']);

            // Retorna a resposta em JSON
            RequestHelper::sendJsonResponse(
                response_code: $petsTutor['response_code'], 
                status: $petsTutor['status'], 
                message: $petsTutor['message'], 
                output: $petsTutor['output'] ?? []
            );
            exit;
        }

        /**
         * Lida com a requisição de criação de uma nova raça de pet.
         *
         * Este método atua como um **controlador** de API, responsável por receber os dados da nova raça (descrição) e o UUID da espécie, validar as entradas e orquestrar a criação do novo registro na camada de serviço.
         *
         * #### Fluxo de Operação:
         * 1.  **Validação de Presença:** Verifica se os campos obrigatórios (`especie_uuid` e `descricao`) estão presentes. Se não estiverem, retorna uma resposta JSON com o código **400 Bad Request** e encerra a execução.
         * 2.  **Busca e Validação da Espécie:** Chama `PetService::getEspecieByIdentifier` para confirmar a existência da espécie pelo UUID e obter seu ID interno. Se a espécie não for encontrada, retorna um erro `400`.
         * 3.  **Preparação do DTO:** Cria e popula um **`PetRacaDTO`** com o ID interno da espécie e a descrição sanitizada.
         * 4.  **Delegação ao Serviço:** O método `storeRaca` do **`PetService`** é chamado para executar a lógica de persistência e validação de negócio.
         * 5.  **Envio da Resposta JSON:** O resultado do serviço (`serviceResult`) é formatado e enviado de volta ao cliente, comunicando o status (`201 Created` em caso de sucesso) e a mensagem da operação.
         *
         * @return void Este método não retorna um valor, pois seu objetivo é enviar uma resposta JSON e encerrar a execução do script.
         */
        public function storeRaca(): void {
            // Receber dados do formulário de registro
            $form = RequestHelper::getFilteredInput(form_type: INPUT_POST);

            // Campos Obrigatórios
            $required_fields = [
                'especie_uuid',
                'descricao'
            ];

            // Verificar se todos os campos obrigatórios estão presentes
            foreach ($required_fields as $field) {
                if (empty($form[$field])) {
                    RequestHelper::sendJsonResponse(
                        response_code: 400, 
                        status: 'error', 
                        message: "Field '{$field}' is required"
                    );
                    exit;
                }
            }

            // Consulta informações da espécie com base no UUID fornecido
            $getEspecie = (new PetService())->getEspecieByIdentifier(
                identifier: 'uuid', 
                value: $form['especie_uuid']
            );
            if($getEspecie['status'] !== 'success') {
                RequestHelper::sendJsonResponse(
                    response_code: 400, 
                    status: 'error', 
                    message: "Espécie não encontrada",
                    output: ['data' => $form]
                );
                exit;
            }
            $especieData = $getEspecie['output']['data'];

            // Chama o serviço de criar raça
            $serviceResult = (new PetService())->storeRaca(
                petRacaDTO: new PetRacaDTO(data: [
                    'especie_id' => $especieData['id'],
                    'descricao' => Sanitizer::string(value: $form['descricao'] ?? '')
                ])
            );

            // Enviar a resposta JSON
            RequestHelper::sendJsonResponse(
                response_code: $serviceResult['response_code'], 
                status: $serviceResult['status'], 
                message: $serviceResult['message'], 
                output: $serviceResult['output'] ?? []
            );
            exit;
        }

        /**
         * Lida com a requisição de criação de um novo pet (animal de estimação).
         *
         * Este método atua como um **controlador** de API, responsável por receber os dados do formulário, realizar validações de presença e delegar a lógica de negócio (criação do pet e associação ao tutor) para o `PetService`.
         *
         * #### Fluxo de Operação:
         * 1.  **Validação de Presença:** Verifica se os campos obrigatórios (`name`, `raca_uuid`, `birthDate`, `sexo`) estão presentes no formulário. Se algum estiver faltando, retorna um erro **400 Bad Request** e encerra a execução.
         * 2.  **Busca e Validação da Raça/Espécie:** Chama `PetService::getEspecieByIdentifier` (apesar do nome, a lógica sugere que este método deve retornar a raça e a espécie) para validar o `raca_uuid` fornecido e obter os IDs internos. Se a raça não for encontrada ou a busca falhar, retorna um erro **400**.
         * 3.  **Preparação do DTO:** Cria e popula um **`PetDTO`** com os dados sanitizados e os IDs internos da raça e espécie.
         * 4.  **Delegação ao Serviço:** O método `storePet` do **`PetService`** é chamado para executar a lógica de persistência e associação do pet ao tutor autenticado.
         * 5.  **Envio da Resposta JSON:** O resultado do serviço (`serviceResult`) é formatado e enviado de volta ao cliente, comunicando o status (código **201 Created** em caso de sucesso) e a mensagem da operação.
         *
         * @return void Este método não retorna um valor, pois seu objetivo é enviar uma resposta JSON e encerrar a execução do script.
         */
        public function storePet(): void {
            // Receber dados do formulário de registro
            $form = RequestHelper::getFilteredInput(form_type: INPUT_POST);

            // Campos Obrigatórios
            $required_fields = [
                'name',
                'raca_uuid',
                'birthDate',
                'sexo',
            ];

            // Verificar se todos os campos obrigatórios estão presentes
            foreach ($required_fields as $field) {
                if (empty($form[$field])) {
                    RequestHelper::sendJsonResponse(
                        response_code: 400, 
                        status: 'error', 
                        message: "Field '{$field}' is required"
                    );
                    exit;
                }
            }

            // Consulta informações da raça com base no UUID fornecido
            $getRaca = (new PetService())->getRacaByIdentifier(
                identifier: 'uuid', 
                value: $form['raca_uuid']
            );

            if($getRaca['status'] !== 'success') {
                RequestHelper::sendJsonResponse(
                    response_code: 400, 
                    status: 'error', 
                    message: "Raça não encontrada"
                );
                exit;
            }

            // Chama o serviço de criar pet
            $serviceResult = (new PetService())->storePet(
                petDTO: new PetDTO(data: [
                    "nome" => Sanitizer::string(value: $form['name'] ?? ''),
                    "data_nascimento" => Sanitizer::string(value: $form['birthDate'] ?? ''),
                    "sexo" => Sanitizer::string(value: $form['sexo'] ?? ''),
                    "raca_id" => $getRaca['output']['data']['id'],
                    "especie_id" => $getRaca['output']['data']['especie_id'],
                    "registro_geral_animal" => Sanitizer::string(value: $form['registro_geral_animal'] ?? NULL),
                ])
            );

            // Enviar a resposta JSON
            RequestHelper::sendJsonResponse(
                response_code: $serviceResult['response_code'], 
                status: $serviceResult['status'], 
                message: $serviceResult['message'], 
                output: $serviceResult['output'] ?? []
            );
            exit;
        }

        /**
         * Lida com a requisição para obter detalhes de um pet específico por seu UUID.
         *
         * Este método atua como um **controlador** para um endpoint de API. Ele é responsável por delegar a busca dos dados do pet para o serviço e formatar a resposta para o cliente em JSON.
         *
         * #### Fluxo de Operação:
         * 1.  **Busca de Detalhes:** O método chama `PetService::getPetByIdentifier()`, usando o UUID fornecido como identificador. O serviço lida com a lógica de consulta no modelo.
         * 2.  **Envio da Resposta JSON:** O resultado retornado pelo serviço (`petDetails`) é formatado e enviado de volta ao cliente usando **`RequestHelper::sendJsonResponse`**. O código HTTP, status e mensagem são extraídos do array de resposta do serviço, comunicando o resultado da busca (sucesso ou falha).
         *
         * @param string $uuid O UUID do pet cujos detalhes devem ser buscados.
         * @return void Este método não retorna um valor, pois seu objetivo é enviar uma resposta JSON e encerrar a execução do script.
         */
        public function getPetDetails(string $uuid): void {
            // Consulta detalhes do pet com base no UUID fornecido
            $petDetails = (new PetService())->getPetByIdentifier(
                identifier: 'uuid', 
                value: $uuid
            );

            if($petDetails['status'] !== 'success') {
                RequestHelper::sendJsonResponse(
                    response_code: $petDetails['response_code'], 
                    status: $petDetails['status'], 
                    message: $petDetails['message'], 
                    output: $petDetails['output'] ?? []
                );
                exit;
            }
            $pet = $petDetails['output']['data'];
            $pet['vacinas'] = [
                [
                    "id" => 1,
                    "nome" => "Antirrábica",
                    "fabricante" => "Zoetis",
                    "lote" => "ZOE-2025-001",
                    "validade" => "2026-02-15",
                    "data_aplicacao" => "2025-02-10",
                    "data_reforco" => "2026-02-10",
                    "veterinario" => "Dr. Carlos Mendes",
                    "created_at" => "2025-02-10 14:30:00",
                    "updated_at" => null,
                    "deleted_at" => null
                ],
                [
                    "id" => 2,
                    "nome" => "V10",
                    "fabricante" => "Boehringer Ingelheim",
                    "lote" => "BIO-2025-044",
                    "validade" => "2026-06-20",
                    "data_aplicacao" => "2025-03-05",
                    "data_reforco" => "2026-03-05",
                    "veterinario" => "Dra. Fernanda Lopes",
                    "created_at" => "2025-03-05 09:10:00",
                    "updated_at" => null,
                    "deleted_at" => null
                ],
                [
                    "id" => 3,
                    "nome" => "Giárdia",
                    "fabricante" => "Ceva",
                    "lote" => "CEV-2025-321",
                    "validade" => "2026-08-01",
                    "data_aplicacao" => "2025-04-15",
                    "data_reforco" => "2025-05-15",
                    "veterinario" => "Dr. Rafael Silva",
                    "created_at" => "2025-04-15 11:45:00",
                    "updated_at" => null,
                    "deleted_at" => null
                ],
                [
                    "id" => 4,
                    "nome" => "Leptospirose",
                    "fabricante" => "MSD",
                    "lote" => "MSD-2025-112",
                    "validade" => "2026-09-30",
                    "data_aplicacao" => "2025-05-20",
                    "data_reforco" => "2026-05-20",
                    "veterinario" => "Dra. Ana Paula",
                    "created_at" => "2025-05-20 10:00:00",
                    "updated_at" => null,
                    "deleted_at" => null
                ],
                [
                    "id" => 5,
                    "nome" => "Cinomose",
                    "fabricante" => "Vanguard",
                    "lote" => "VAN-2025-210",
                    "validade" => "2026-11-12",
                    "data_aplicacao" => "2025-06-10",
                    "data_reforco" => "2026-06-10",
                    "veterinario" => "Dr. Eduardo Gomes",
                    "created_at" => "2025-06-10 15:20:00",
                    "updated_at" => null,
                    "deleted_at" => null
                ]
            ];

            // Retorna a resposta em JSON
            RequestHelper::sendJsonResponse(
                response_code: $petDetails['response_code'], 
                status: $petDetails['status'], 
                message: $petDetails['message'], 
                output: ['data' => $pet] ?? []
            );
            exit;
        }

        public function updatePet(string $uuid, array $params): void {
            
        }
    }