<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Clientes extends MY_Controller {

    public function __construct() {
        parent::__construct();
        $this->load->model('ventas/Cliente_model');
    }

    protected function normalizarTexto($texto) {
        return strtoupper(trim($texto));
    }

    protected function validar_permiso_ajax_cliente() {
        if (!tiene_permiso('clientes_crear') && !tiene_permiso('clientes_editar')) {
            echo json_encode(array(
                'status' => false,
                'message' => 'No tienes permisos para esta acción'
            ));
            exit;
        }
    }

    protected function validar_documento_por_tipo($documento_identidad_id, $nro_documento) {
        $doc = $this->db->where('id', $documento_identidad_id)->get('mt_documento_identidad')->row();

        if (!$doc) return 'Tipo de documento no válido';

        $abreviado = strtoupper(trim($doc->abreviado));
        $nro = trim($nro_documento);

        if (in_array($abreviado, array('DNI', 'RUC'))) {
            if (!ctype_digit($nro)) {
                return 'El número de documento debe contener solo números';
            }
        }

        if ($abreviado === 'DNI' && strlen($nro) != 8) {
            return 'El DNI debe tener exactamente 8 dígitos';
        }

        if ($abreviado === 'RUC' && strlen($nro) != 11) {
            return 'El RUC debe tener exactamente 11 dígitos';
        }

        return true;
    }

    public function index() {
        $this->validar_permiso('clientes_ver');

        $data['titulo'] = 'Clientes';
        $data['clientes'] = $this->Cliente_model->listar();
        $this->layout('ventas/clientes/index', $data);
    }

    public function create() {
        $this->validar_permiso('clientes_crear');

        $data['titulo'] = 'Nuevo Cliente';
        $data['documentos'] = $this->Cliente_model->listar_documentos();
        $data['monedas'] = $this->Cliente_model->listar_monedas();
        $data['formas_pago'] = $this->Cliente_model->listar_formas_pago();
        $data['vendedores'] = $this->Cliente_model->listar_vendedores();
        $data['departamentos'] = $this->Cliente_model->get_departamentos();

        $this->layout('ventas/clientes/create', $data);
    }

    public function store() {
        $this->validar_permiso('clientes_crear');

        $this->form_validation->set_rules('codigo', 'Código', 'required|trim|max_length[20]');
        $this->form_validation->set_rules('razon_social', 'Razón social', 'required|trim|max_length[150]');
        $this->form_validation->set_rules('documento_identidad_id', 'Tipo documento', 'required');
        $this->form_validation->set_rules('nro_documento', 'Número documento', 'required|trim|max_length[20]');
        $this->form_validation->set_rules('nombre_corto', 'Nombre corto', 'trim|max_length[100]');
        $this->form_validation->set_rules('domicilio_fiscal', 'Domicilio fiscal', 'trim|max_length[255]');
        $this->form_validation->set_rules('moneda_id', 'Moneda', 'required');
        $this->form_validation->set_rules('fp_descripcion', 'Descripción forma pago', 'trim|max_length[50]');
        $this->form_validation->set_rules('linea_credito', 'Línea de crédito', 'required');

        if ($this->form_validation->run() == FALSE) {
            $this->create();
            return;
        }

        $codigo = strtoupper(trim($this->input->post('codigo', TRUE)));
        $razon_social = $this->normalizarTexto($this->input->post('razon_social', TRUE));
        $documento_identidad_id = $this->input->post('documento_identidad_id', TRUE);
        $nro_documento = trim($this->input->post('nro_documento', TRUE));
        $linea_credito = $this->input->post('linea_credito', TRUE);

        if ($this->Cliente_model->existe_codigo($codigo)) {
            $this->session->set_flashdata('error', 'El código del cliente ya existe');
            redirect('ventas/clientes/create');
        }

        if ($this->Cliente_model->existe_documento($nro_documento)) {
            $this->session->set_flashdata('error', 'El número de documento ya existe');
            redirect('ventas/clientes/create');
        }

        $validacion_documento = $this->validar_documento_por_tipo($documento_identidad_id, $nro_documento);
        if ($validacion_documento !== true) {
            $this->session->set_flashdata('error', $validacion_documento);
            redirect('ventas/clientes/create');
        }

        if ((float)$linea_credito < 0) {
            $this->session->set_flashdata('error', 'La línea de crédito no puede ser negativa');
            redirect('ventas/clientes/create');
        }

        $data = array(
            'codigo' => $codigo,
            'razon_social' => $razon_social,
            'documento_identidad_id' => $documento_identidad_id,
            'nro_documento' => $nro_documento,
            'nombre_corto' => $this->normalizarTexto($this->input->post('nombre_corto', TRUE)),
            'domicilio_fiscal' => trim($this->input->post('domicilio_fiscal', TRUE)),
            'ubigeo_id' => $this->input->post('ubigeo_id', TRUE) ? $this->input->post('ubigeo_id', TRUE) : null,
            'moneda_id' => $this->input->post('moneda_id', TRUE),
            'vendedor_id' => $this->input->post('vendedor_id', TRUE) ? $this->input->post('vendedor_id', TRUE) : null,
            'fp_id' => $this->input->post('fp_id', TRUE) ? $this->input->post('fp_id', TRUE) : null,
            'fp_descripcion' => trim($this->input->post('fp_descripcion', TRUE)),
            'linea_credito' => $linea_credito,
            'estado' => 1,
            'created_by' => $this->session->userdata('id')
        );

        if ($this->Cliente_model->insertar($data)) {
            $this->session->set_flashdata('success', 'Cliente registrado correctamente');
        } else {
            $this->session->set_flashdata('error', 'No se pudo registrar el cliente');
        }

        redirect('ventas/clientes');
    }

    public function edit($id) {
        $this->validar_permiso('clientes_editar');

        $cliente = $this->Cliente_model->obtener($id);

        if (!$cliente) {
            show_404();
        }

        $ubigeo = null;
        if (!empty($cliente->ubigeo_id)) {
            $ubigeo = $this->Cliente_model->get_ubigeo_by_id($cliente->ubigeo_id);
        }

        $data['titulo'] = 'Editar Cliente';
        $data['cliente'] = $cliente;
        $data['documentos'] = $this->Cliente_model->listar_documentos();
        $data['monedas'] = $this->Cliente_model->listar_monedas();
        $data['formas_pago'] = $this->Cliente_model->listar_formas_pago();
        $data['vendedores'] = $this->Cliente_model->listar_vendedores();
        $data['departamentos'] = $this->Cliente_model->get_departamentos();
        $data['ubigeo_actual'] = $ubigeo;

        if ($ubigeo) {
            $data['provincias'] = $this->Cliente_model->get_provincias($ubigeo->departamento);
            $data['distritos'] = $this->Cliente_model->get_distritos($ubigeo->departamento, $ubigeo->provincia);
        } else {
            $data['provincias'] = array();
            $data['distritos'] = array();
        }

        $this->layout('ventas/clientes/edit', $data);
    }

    public function update($id) {
        $this->validar_permiso('clientes_editar');

        $cliente = $this->Cliente_model->obtener($id);

        if (!$cliente) {
            show_404();
        }

        $this->form_validation->set_rules('codigo', 'Código', 'required|trim|max_length[20]');
        $this->form_validation->set_rules('razon_social', 'Razón social', 'required|trim|max_length[150]');
        $this->form_validation->set_rules('documento_identidad_id', 'Tipo documento', 'required');
        $this->form_validation->set_rules('nro_documento', 'Número documento', 'required|trim|max_length[20]');
        $this->form_validation->set_rules('nombre_corto', 'Nombre corto', 'trim|max_length[100]');
        $this->form_validation->set_rules('domicilio_fiscal', 'Domicilio fiscal', 'trim|max_length[255]');
        $this->form_validation->set_rules('moneda_id', 'Moneda', 'required');
        $this->form_validation->set_rules('fp_descripcion', 'Descripción forma pago', 'trim|max_length[50]');
        $this->form_validation->set_rules('linea_credito', 'Línea de crédito', 'required');

        if ($this->form_validation->run() == FALSE) {
            $this->edit($id);
            return;
        }

        $codigo = strtoupper(trim($this->input->post('codigo', TRUE)));
        $razon_social = $this->normalizarTexto($this->input->post('razon_social', TRUE));
        $documento_identidad_id = $this->input->post('documento_identidad_id', TRUE);
        $nro_documento = trim($this->input->post('nro_documento', TRUE));
        $linea_credito = $this->input->post('linea_credito', TRUE);

        if ($this->Cliente_model->existe_codigo($codigo, $id)) {
            $this->session->set_flashdata('error', 'El código del cliente ya existe');
            redirect('ventas/clientes/edit/'.$id);
        }

        if ($this->Cliente_model->existe_documento($nro_documento, $id)) {
            $this->session->set_flashdata('error', 'El número de documento ya existe');
            redirect('ventas/clientes/edit/'.$id);
        }

        $validacion_documento = $this->validar_documento_por_tipo($documento_identidad_id, $nro_documento);
        if ($validacion_documento !== true) {
            $this->session->set_flashdata('error', $validacion_documento);
            redirect('ventas/clientes/edit/'.$id);
        }

        if ((float)$linea_credito < 0) {
            $this->session->set_flashdata('error', 'La línea de crédito no puede ser negativa');
            redirect('ventas/clientes/edit/'.$id);
        }

        $data = array(
            'codigo' => $codigo,
            'razon_social' => $razon_social,
            'documento_identidad_id' => $documento_identidad_id,
            'nro_documento' => $nro_documento,
            'nombre_corto' => $this->normalizarTexto($this->input->post('nombre_corto', TRUE)),
            'domicilio_fiscal' => trim($this->input->post('domicilio_fiscal', TRUE)),
            'ubigeo_id' => $this->input->post('ubigeo_id', TRUE) ? $this->input->post('ubigeo_id', TRUE) : null,
            'moneda_id' => $this->input->post('moneda_id', TRUE),
            'vendedor_id' => $this->input->post('vendedor_id', TRUE) ? $this->input->post('vendedor_id', TRUE) : null,
            'fp_id' => $this->input->post('fp_id', TRUE) ? $this->input->post('fp_id', TRUE) : null,
            'fp_descripcion' => trim($this->input->post('fp_descripcion', TRUE)),
            'linea_credito' => $linea_credito,
            'updated_at' => date('Y-m-d H:i:s'),
            'updated_by' => $this->session->userdata('id')
        );

        if ($this->Cliente_model->actualizar($id, $data)) {
            $this->session->set_flashdata('success', 'Cliente actualizado correctamente');
        } else {
            $this->session->set_flashdata('error', 'No se pudo actualizar el cliente');
        }

        redirect('ventas/clientes');
    }

    public function ver($id) {
        $this->validar_permiso('clientes_ver');

        $cliente = $this->db
            ->select('
                c.*,
                td.nombre as tipo_documento,
                td.abreviado as documento_abreviado,
                m.nombre as moneda,
                m.abreviado as moneda_abreviado,
                fp.nombre as forma_pago,
                v.apellidos,
                v.nombres,
                u.nombre as distrito_nombre,
                u.departamento as ub_departamento,
                u.provincia as ub_provincia
            ')
            ->from('vt_cliente c')
            ->join('mt_documento_identidad td', 'td.id = c.documento_identidad_id')
            ->join('mt_moneda m', 'm.id = c.moneda_id')
            ->join('mt_forma_pago fp', 'fp.id = c.fp_id', 'left')
            ->join('rh_empleado v', 'v.id = c.vendedor_id', 'left')
            ->join('mt_ubigeo u', 'u.id = c.ubigeo_id', 'left')
            ->where('c.id', $id)
            ->get()
            ->row();

        if (!$cliente) {
            show_404();
        }

        $departamento = null;
        $provincia = null;

        if (!empty($cliente->ub_departamento)) {
            $departamento = $this->db
                ->select('nombre')
                ->from('mt_ubigeo')
                ->where('departamento', $cliente->ub_departamento)
                ->where('provincia', '00')
                ->where('distrito', '00')
                ->where('estado', 1)
                ->get()
                ->row();
        }

        if (!empty($cliente->ub_departamento) && !empty($cliente->ub_provincia)) {
            $provincia = $this->db
                ->select('nombre')
                ->from('mt_ubigeo')
                ->where('departamento', $cliente->ub_departamento)
                ->where('provincia', $cliente->ub_provincia)
                ->where('distrito', '00')
                ->where('estado', 1)
                ->get()
                ->row();
        }

        $cliente->departamento_nombre = $departamento ? $departamento->nombre : '';
        $cliente->provincia_nombre = $provincia ? $provincia->nombre : '';
        $cliente->vendedor = trim(($cliente->apellidos ?? '') . ' ' . ($cliente->nombres ?? ''));

        $data['titulo'] = 'Detalle de Cliente';
        $data['cliente'] = $cliente;

        $this->layout('ventas/clientes/ver', $data);
    }

    public function estado($id) {
        $this->validar_permiso('clientes_eliminar');

        $cliente = $this->Cliente_model->obtener($id);

        if (!$cliente) {
            show_404();
        }

        $nuevoEstado = ($cliente->estado == 1) ? 0 : 1;

        if ($this->Cliente_model->cambiarEstado($id, $nuevoEstado, $this->session->userdata('id'))) {
            $mensaje = ($nuevoEstado == 1) ? 'Cliente activado correctamente' : 'Cliente desactivado correctamente';
            $this->session->set_flashdata('success', $mensaje);
        } else {
            $this->session->set_flashdata('error', 'No se pudo cambiar el estado del cliente');
        }

        redirect('ventas/clientes');
    }

    public function provincias_ajax() {
        $this->validar_permiso_ajax_cliente();

        $departamento = $this->input->post('departamento', TRUE);
        $provincias = $this->Cliente_model->get_provincias($departamento);

        echo json_encode($provincias);
    }

    public function distritos_ajax() {
        $this->validar_permiso_ajax_cliente();

        $departamento = $this->input->post('departamento', TRUE);
        $provincia = $this->input->post('provincia', TRUE);
        $distritos = $this->Cliente_model->get_distritos($departamento, $provincia);

        echo json_encode($distritos);
    }

    /**
     * Consulta RUC u DNI en la API externa (apis.net.pe / decolecta)
     * y devuelve los datos para autocompletar el formulario de cliente.
     * Se invoca desde JS al completar 8 (DNI) u 11 (RUC) dígitos.
     */
    public function consultar_documento_ajax() {
        $this->validar_permiso_ajax_cliente();

        $numero = trim($this->input->post('numero', TRUE));

        if (!ctype_digit($numero) || !in_array(strlen($numero), array(8, 11))) {
            echo json_encode(array(
                'status' => false,
                'message' => 'Número de documento inválido'
            ));
            return;
        }

        $token = $this->Cliente_model->get_token_api_consulta();

        if (empty($token)) {
            echo json_encode(array(
                'status' => false,
                'message' => 'No hay un token de API de consulta configurado para la empresa'
            ));
            return;
        }

        $es_ruc = (strlen($numero) === 11);

        $url = $es_ruc
            ? 'https://api.decolecta.com/v1/sunat/ruc?numero=' . $numero
            : 'https://api.decolecta.com/v1/reniec/dni?numero=' . $numero;

        $referer = $es_ruc
            ? 'http://apis.net.pe/api-ruc'
            : 'https://apis.net.pe/consulta-dni-api';

        $curl = curl_init();

        curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_SSL_VERIFYPEER => 0,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 15,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_CUSTOMREQUEST => 'GET',
            CURLOPT_HTTPHEADER => array(
                'Referer: ' . $referer,
                'Authorization: Bearer ' . $token
            ),
        ));

        $response = curl_exec($curl);
        $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $curl_error = curl_error($curl);
        curl_close($curl);

        if ($curl_error) {
            log_message('error', 'CONSULTA DOC - CURL ERROR: ' . $curl_error . ' | URL: ' . $url);
            echo json_encode(array(
                'status' => false,
                'message' => 'Error de conexión con el servicio de consulta'
            ));
            return;
        }

        if ($http_code === 404) {
            echo json_encode(array(
                'status' => false,
                'message' => $es_ruc ? 'RUC no encontrado' : 'DNI no encontrado'
            ));
            return;
        }

        if ($http_code === 422) {
            echo json_encode(array(
                'status' => false,
                'message' => 'El número de documento no pasó la validación del servicio'
            ));
            return;
        }

        if ($http_code !== 200) {
            echo json_encode(array(
                'status' => false,
                'message' => 'El servicio de consulta no respondió correctamente'
            ));
            return;
        }

        $data = json_decode($response);

        if (!$data) {
            echo json_encode(array(
                'status' => false,
                'message' => 'Respuesta inválida del servicio de consulta'
            ));
            return;
        }

        if ($es_ruc) {
            $resultado = array(
                'status' => true,
                'razon_social' => isset($data->razon_social) ? $data->razon_social : '',
                'direccion' => (isset($data->direccion) && $data->direccion !== '-') ? trim($data->direccion) : '',
                'ubigeo' => (isset($data->ubigeo) && $data->ubigeo !== '-') ? $data->ubigeo : ''
            );
        } else {
            $resultado = array(
                'status' => true,
                'razon_social' => isset($data->full_name) ? $data->full_name : '',
                'direccion' => '',
                'ubigeo' => ''
            );
        }

        // Autoseleccionar tipo de documento (DNI/RUC) según la longitud consultada
        $doc_row = $this->Cliente_model->get_documento_identidad_by_abreviado($es_ruc ? 'RUC' : 'DNI');
        if ($doc_row) {
            $resultado['documento_identidad_id'] = $doc_row->id;
        }

        // Si hay ubigeo de 6 dígitos, lo partimos y buscamos el id interno
        if (!empty($resultado['ubigeo']) && strlen($resultado['ubigeo']) === 6) {
            $cod_dep = substr($resultado['ubigeo'], 0, 2);
            $cod_prov = substr($resultado['ubigeo'], 2, 2);
            $cod_dist = substr($resultado['ubigeo'], 4, 2);

            $ubigeo_row = $this->Cliente_model->get_ubigeo_by_codigo($cod_dep, $cod_prov, $cod_dist);

            if ($ubigeo_row) {
                $resultado['ubigeo_id'] = $ubigeo_row->id;
                $resultado['departamento_codigo'] = $cod_dep;
                $resultado['provincia_codigo'] = $cod_prov;
            }
        }

        echo json_encode($resultado);
    }

}