<?php
declare(strict_types=1);

use Phinx\Migration\AbstractMigration;

final class TaskSr62728 extends AbstractMigration
{
    public function up(): void
    {
        $this->execute("CREATE TABLE manutencao.update_coord_item_segurado AS SELECT itens_segurados_complemento.id_item_segurado
                                                                                   , itens_segurados_complemento.ds_coordenadas_geograficas
                                                                                FROM seguro.itens_segurados_complemento
                                                                                JOIN seguro.itens_segurados
                                                                                  ON itens_segurados_complemento.id_item_segurado = itens_segurados.id
                                                                                JOIN seguro.propostas
                                                                                  ON propostas.id = itens_segurados.id_proposta
                                                                                JOIN produto.produtos
                                                                                  ON produtos.id = propostas.id_produto
                                                                               WHERE produtos.id_safra = 29
                                                                                 AND propostas.id_status = 2
                      ");

        $this->execute("CREATE OR REPLACE FUNCTION dd_to_dms( dd                double precision
                                                            , use_hemisphere    boolean default false
                                                            , is_latitude       boolean default true
                                                            ) RETURNS TEXT AS $$
                        DECLARE
                            sign_char   TEXT;
                            a           DOUBLE PRECISION := abs(dd);
                            deg         INTEGER;
                            min         INTEGER;
                            sec         INTEGER;
                            min_full    DOUBLE PRECISION;
                            sec_full    DOUBLE PRECISION;
                            deg_out     INTEGER;
                        BEGIN
                            -- calcula partes
                            deg := floor(a)::INT;
                            min_full := (a - deg) * 60.0;
                            min := floor(min_full)::INT;
                            sec_full := (min_full - min) * 60.0;
                        
                            -- arredonda segundos
                            sec := round(sec_full)::INT;
                        
                            -- ajustes (carry)
                            IF sec = 60 THEN
                                sec := 0;
                                min := min + 1;
                            END IF;
                        
                            IF min = 60 then
                                min := 0;
                                deg := deg + 1;
                            END IF;
                        
                            -- monta sinal
                            deg_out := CASE WHEN dd < 0 THEN -deg else deg END;
                        
                            -- padding garantido
                            IF use_hemisphere THEN
                                IF is_latitude THEN
                                    sign_char := CASE WHEN dd < 0 THEN 'S' else 'N' END;
                                else
                                    sign_char := CASE WHEN dd < 0 THEN 'W' else 'E' END;
                                END IF;
                        
                                RETURN
                                    deg_out::TEXT || ' ' ||
                                    lpad(min::TEXT, 2, '0') || ' ' ||
                                    lpad(sec::TEXT, 2, '0') || ' ' ||
                                    sign_char;
                            ELSE
                                RETURN
                                    deg_out::TEXT || ' ' ||
                                    lpad(min::TEXT, 2, '0') || ' ' ||
                                    lpad(sec::TEXT, 2, '0');
                            END IF;
                        
                        END;
                        $$ LANGUAGE plpgsql;
                      ");

        $this->execute(" UPDATE seguro.itens_segurados_complemento
                            SET ds_coordenadas_geograficas = dd_to_dms(split_part(propostas_croquis_talhoes.ds_coordenadas_centroide, ',', 1)::NUMERIC) || ' , '|| dd_to_dms(split_part(propostas_croquis_talhoes.ds_coordenadas_centroide, ',', 2)::NUMERIC)
                           FROM seguro.propostas_croquis_talhoes
                           JOIN seguro.propostas_croquis
                             ON propostas_croquis.id = propostas_croquis_talhoes.id_croqui
                           JOIN seguro.propostas
                             ON propostas.id = propostas_croquis.id_proposta
                            AND propostas_croquis.fl_vigente = TRUE
                           JOIN produto.produtos
                             ON produtos.id = propostas.id_produto
                           JOIN seguro.itens_segurados
                             ON itens_segurados.id_proposta = propostas.id
                           JOIN seguro.itens_segurados_complemento AS interna
                             ON interna.id_item_segurado = itens_segurados.id
                            AND itens_segurados.id::varchar = any(string_to_array(propostas_croquis_talhoes.ds_item_segurado,','))
                          WHERE produtos.id_safra = 29
                            AND propostas.id_status = 2
                            AND interna.id_item_segurado = itens_segurados_complemento.id_item_segurado
                      ");
    }

    public function down(): void
    {
        $this->execute("UPDATE seguro.itens_segurados_complemento
                           SET ds_coordenadas_geograficas = update_coord_item_segurado.ds_coordenadas_geograficas
                          FROM manutencao.update_coord_item_segurado
                         WHERE update_coord_item_segurado.id_item_segurado = itens_segurados_complemento.id_item_segurado
                      ");
    }
}