<?php
namespace Gestoreasy\Core\Fiscal\Sped\Blocks;

use PDO;
use Gestoreasy\Core\Fiscal\Sped\BlockInterface;
use Gestoreasy\Core\Fiscal\Sped\Period;
use Gestoreasy\Core\Fiscal\Sped\Validation\SpedValidator;

class Block0 implements BlockInterface {
    public function id(): string { return '0'; }

    public function generate(PDO $pdo, Period $period, array $options = []): array {
        $perfil = strtoupper((string)($options['perfil'] ?? 'A')); // A/B/C
        $ind_ativ = (int)($options['ind_ativ'] ?? 0); // 0=inativo, 1=ativo

        $company = $this->loadCompany($pdo);
        $uf = strtoupper((string)($company['estado'] ?? ''));
        if (!SpedValidator::validateUF($uf)) $uf = '';

        $lines = [];
        // 0000 - Abertura do arquivo
        // |0000|<cod_ver>|<cod_fin>|<dt_ini>|<dt_fin>|<nome>|<cnpj>|<cpf>|<uf>|<ins_est>|<ins_mun>|<suframa>|<ind_nat_pj>|<ind_ativ>|
        $cod_ver = (string)($options['cod_ver'] ?? '017'); // layout version (placeholder; adjustable via options)
        $cod_fin = (int)($options['cod_fin'] ?? 0); // finalidade: 0=original, 1=substituto
        $dt_ini = str_replace('-', '', $period->startDate());
        $dt_fin = str_replace('-', '', $period->endDate());
        $nome = (string)($company['razao_social'] ?: ($company['nome'] ?? ''));
        $cnpj = SpedValidator::digitsOnly((string)($company['cnpj'] ?? ''));
        $cpf = '';
        $ie = SpedValidator::digitsOnly((string)($company['ie'] ?? ''));
        $im = SpedValidator::digitsOnly((string)($company['im'] ?? ''));
        $suframa = '';
        $ind_nat_pj = 0; // 0=Pessoa Jurídica; 1=Pessoa Física
        if (!$cnpj) { $ind_nat_pj = 1; $cpf = SpedValidator::digitsOnly((string)($options['company_cpf'] ?? '')); }
        $lines[] = sprintf('|0000|%s|%d|%s|%s|%s|%s|%s|%s|%s|%s|%s|%d|%d|',
            $cod_ver, $cod_fin, $dt_ini, $dt_fin, $nome, $cnpj, $cpf, $uf, $ie, $im, $suframa, $ind_nat_pj, $ind_ativ);

        // 0001 - Abertura do bloco 0
        $lines[] = '|0001|0|'; // 0=movimento, 1=sem dados (ajustar conforme options['ind_mov_0'])

        // 0005 - Dados complementares da entidade
        $fantasia = (string)($company['nome'] ?? '');
        $logradouro = (string)($company['logradouro'] ?? '');
        $numero = (string)($company['numero'] ?? '');
        $complemento = (string)($company['complemento'] ?? '');
        $bairro = (string)($company['bairro'] ?? '');
        $fone = (string)($company['telefone'] ?? '');
        $email = (string)($company['email'] ?? '');
        $cod_mun = ''; // pode ser mapeado por IBGE futuramente
        $cep = SpedValidator::digitsOnly((string)($company['cep'] ?? ''));
        $lines[] = sprintf('|0005|%s|%s|%s|%s|%s|%s|%s|%s|%s|',
            $fantasia, $logradouro, $numero, $complemento, $bairro, $fone, $email, $cod_mun, $cep);

        // 0190 - Unidades de medida utilizadas (derivadas dos produtos)
        foreach ($this->distinctUnits($pdo) as $u) {
            $lines[] = sprintf('|0190|%s|%s|', $u['unidade'], $u['descricao']);
        }

        // 0200 - Identificação de itens
        foreach ($this->products($pdo) as $p) {
            $lines[] = sprintf('|0200|%s|%s|%s|%s|%s|%s|%s|',
                $p['codigo'], $p['descricao'], $p['codigo_barras'], $p['unidade'], $p['tipo_item'], $p['ncm'], $p['ex_ipi']);
        }

        // 0150 - Tabela de participantes (clientes/fornecedores)
        foreach ($this->participants($pdo) as $c) {
            $lines[] = sprintf('|0150|%s|%s|%s|%s|%s|%s|%s|%s|%s|',
                $c['cod_part'], $c['nome'], $c['cnpj'], $c['cpf'], $c['ie'], $c['cod_mun'], $c['suframa'], $c['endereco'], $c['bairro']);
        }

        return $lines;
    }

    private function loadCompany(PDO $pdo): array {
        try {
            $stmt = $pdo->query('SELECT * FROM empresas ORDER BY id ASC LIMIT 1');
            $row = $stmt->fetch();
            return $row ?: [];
        } catch (\Throwable $e) { return []; }
    }

    private function distinctUnits(PDO $pdo): array {
        $items = [];
        try {
            $stmt = $pdo->query("SELECT DISTINCT unidade FROM products WHERE unidade IS NOT NULL AND unidade <> ''");
            while ($row = $stmt->fetch()) {
                $un = (string)$row['unidade'];
                $items[] = [ 'unidade' => $un, 'descricao' => $un ];
            }
        } catch (\Throwable $e) {}
        return $items;
    }

    private function products(PDO $pdo): array {
        $items = [];
        try {
            $stmt = $pdo->query("SELECT codigo, descricao, ean, unidade, ncm FROM products ORDER BY id ASC");
            while ($row = $stmt->fetch()) {
                $items[] = [
                    'codigo' => (string)($row['codigo'] ?? ''),
                    'descricao' => (string)($row['descricao'] ?? ''),
                    'codigo_barras' => (string)($row['ean'] ?? ''),
                    'unidade' => (string)($row['unidade'] ?? ''),
                    'tipo_item' => '00', // 00=mercadoria para revenda (ajustar com meta futuramente)
                    'ncm' => (string)($row['ncm'] ?? ''),
                    'ex_ipi' => ''
                ];
            }
        } catch (\Throwable $e) {}
        return $items;
    }

    private function participants(PDO $pdo): array {
        $items = [];
        // Clients
        try {
            $stmt = $pdo->query("SELECT id, nome, cpf, cnpj, ie FROM clients ORDER BY id ASC LIMIT 10000");
            while ($row = $stmt->fetch()) {
                $cnpj = SpedValidator::digitsOnly((string)($row['cnpj'] ?? ''));
                $cpf = SpedValidator::digitsOnly((string)($row['cpf'] ?? ''));
                $items[] = [
                    'cod_part' => 'C'.(string)$row['id'],
                    'nome' => (string)($row['nome'] ?? ''),
                    'cnpj' => $cnpj,
                    'cpf' => $cpf,
                    'ie' => SpedValidator::digitsOnly((string)($row['ie'] ?? '')),
                    'cod_mun' => '',
                    'suframa' => '',
                    'endereco' => '',
                    'bairro' => ''
                ];
            }
        } catch (\Throwable $e) {}
        // Suppliers
        foreach ([
            'suppliers' => ['id','nome','cnpj'],
            'fornecedores' => ['id','nome','cnpj']
        ] as $table => $cols) {
            try {
                $stmt = $pdo->query("SELECT id, nome, cnpj, ie FROM {$table} ORDER BY id ASC LIMIT 10000");
                while ($row = $stmt->fetch()) {
                    $cnpj = SpedValidator::digitsOnly((string)($row['cnpj'] ?? ''));
                    $items[] = [
                        'cod_part' => 'F'.(string)$row['id'],
                        'nome' => (string)($row['nome'] ?? ''),
                        'cnpj' => $cnpj,
                        'cpf' => '',
                        'ie' => SpedValidator::digitsOnly((string)($row['ie'] ?? '')),
                        'cod_mun' => '',
                        'suframa' => '',
                        'endereco' => '',
                        'bairro' => ''
                    ];
                }
            } catch (\Throwable $e) {}
        }
        return $items;
    }
}