<?php

namespace App\Interfaces\Http\Controllers;

use App\Application\UseCases\Clientes\CreateClienteUseCase;
use App\Domains\Clientes\Dtos\CriarClienteDto;
use App\Interfaces\Http\Requests\ClienteRequest;
use Illuminate\Http\JsonResponse;
use App\Dominios\Clientes\DTO\ClienteListagemDTO;
use App\Dominios\Clientes\DTO\AtualizarClienteDTO;
use App\Dominios\Clientes\Repositories\ClienteRepository;
use App\Dominios\Clientes\Services\ClienteService;
use App\Dominios\Clientes\Models\Cliente;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;

class ClienteController extends Controller
{
    public function __construct(
        private CreateClienteUseCase $createClienteUseCase,
        private readonly ClienteRepository $repository,
        private readonly ClienteService $service
    ) {}

    public function index(Request $request): JsonResponse
    {
        $perPage = $request->input('per_page', 15);
        $search = $request->input('search');
        
        $query = $this->repository->paginados($perPage);
        
        if ($search) {
            $query->where(function ($q) use ($search) {
                $q->where('nome', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%")
                  ->orWhere('cpf', 'like', "%{$search}%");
            });
        }
        
        $clientes = $query->paginate($perPage);
        
        $clientes->getCollection()->transform(function (Cliente $cliente) {
            return ClienteListagemDTO::fromModel($cliente);
        });

        return response()->json($clientes);
    }

    public function excluidos(Request $request): JsonResponse
    {
        $perPage = $request->input('per_page', 15);
        $search = $request->input('search');
        
        $query = $this->repository->apenasExcluidos();
        
        if ($search) {
            $query->where(function ($q) use ($search) {
                $q->where('nome', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%")
                  ->orWhere('cpf', 'like', "%{$search}%");
            });
        }
        
        $clientes = $query->paginate($perPage);
        
        $clientes->getCollection()->transform(function (Cliente $cliente) {
            return ClienteListagemDTO::fromModel($cliente);
        });

        return response()->json($clientes);
    }

    public function todos(Request $request): JsonResponse
    {
        $perPage = $request->input('per_page', 15);
        $search = $request->input('search');
        
        $query = $this->repository->todosComExcluidos();
        
        if ($search) {
            $query->where(function ($q) use ($search) {
                $q->where('nome', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%")
                  ->orWhere('cpf', 'like', "%{$search}%");
            });
        }
        
        $clientes = $query->paginate($perPage);
        
        $clientes->getCollection()->transform(function (Cliente $cliente) {
            return ClienteListagemDTO::fromModel($cliente);
        });

        return response()->json($clientes);
    }

    public function store(ClienteRequest $request): JsonResponse
    {
        try {
            $dto = CriarClienteDto::fromArray($request->validated());
            $cliente = $this->createClienteUseCase->execute($dto);

            return response()->json([
                'data' => [
                    'id' => $cliente->id,
                    'nome' => $cliente->nome,
                    'email' => $cliente->email,
                    'telefone' => $cliente->telefone,
                    'cpf' => $cliente->cpf,
                    'empresa_id' => $cliente->empresa_id,
                    'created_at' => $cliente->created_at,
                    'updated_at' => $cliente->updated_at
                ],
                'message' => 'Cliente criado com sucesso'
            ], 201);
        } catch (ValidationException $e) {
            return response()->json([
                'message' => 'Dados inválidos',
                'errors' => $e->errors()
            ], 422);
        } catch (\Exception $e) {
            return response()->json([
                'message' => 'Erro ao criar cliente',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function update(int $id, Request $request): JsonResponse
    {
        try {
            $dto = AtualizarClienteDTO::fromArray($request->all());
            $cliente = $this->repository->atualizar($id, $dto);

            return response()->json([
                'id' => $cliente->id,
                'nome' => $cliente->nome,
                'email' => $cliente->email,
                'cpf' => $cliente->cpf,
                'telefone' => $cliente->telefone
            ]);
        } catch (ValidationException $e) {
            return response()->json([
                'message' => 'Dados inválidos',
                'errors' => $e->errors()
            ], 422);
        } catch (ModelNotFoundException $e) {
            return response()->json([
                'message' => 'Cliente não encontrado'
            ], 404);
        }
    }

    public function destroy(int $id): JsonResponse
    {
        try {
            $this->service->remover($id);

            return response()->json([
                'mensagem' => 'Cliente removido com sucesso'
            ]);
        } catch (ModelNotFoundException $e) {
            return response()->json([
                'message' => 'Cliente não encontrado'
            ], 404);
        }
    }
} 