<?php
/**
 * Obrômetro — Custom Post Type "Obra", taxonomias e regras de negócio.
 *
 * O cadastro é 100% manual pela SECOM via painel adm (integração Elotech
 * descartada). Obra nunca é excluída fisicamente: o campo "Visível" oculta
 * preservando o histórico. Os campos ACF ficam em inc/obras-campos.php.
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * CPT "obra" + taxonomias Eixo/Área, Região e Bairro.
 * URL própria por obra (/obras/nome-da-obra) — nada de modal, cada obra
 * precisa de link compartilhável com Open Graph próprio.
 */
function mfm_registra_obra() {
	register_post_type(
		'obra',
		array(
			'labels'       => array(
				'name'               => 'Obras e Serviços',
				'singular_name'      => 'Obra',
				'add_new'            => 'Cadastrar nova',
				'add_new_item'       => 'Cadastrar obra ou serviço',
				'edit_item'          => 'Editar obra',
				'new_item'           => 'Nova obra',
				'view_item'          => 'Ver no site',
				'search_items'       => 'Buscar obras',
				'not_found'          => 'Nenhuma obra cadastrada ainda.',
				'not_found_in_trash' => 'Nenhuma obra na lixeira.',
				'all_items'          => 'Todas as obras',
				'featured_image'     => 'Foto principal',
				'set_featured_image' => 'Definir foto principal',
				'remove_featured_image' => 'Remover foto principal',
				'use_featured_image' => 'Usar como foto principal',
			),
			'public'       => true,
			'menu_position' => 4,
			'menu_icon'    => 'dashicons-building',
			'supports'     => array( 'title', 'thumbnail' ),
			'has_archive'  => true, // /obras/ = listagem geral com filtros (etapa 4).
			// Caps próprias: dá pra liberar Obras pra role SECOM (plugin
			// MFM Painel) sem abrir os Posts junto.
			'capability_type' => array( 'obra', 'obras' ),
			'map_meta_cap' => true,
			'rewrite'      => array(
				'slug'       => 'obras',
				'with_front' => false,
			),
			'show_in_rest' => false, // editor clássico: tela mais simples pra SECOM.
		)
	);

	// Eixo/Área e Região são taxonomias FIXAS (escopo jul/2026): os termos
	// vêm do seed versionado abaixo e ninguém cria/edita termo pela
	// interface — por isso manage/edit/delete apontam pra do_not_allow.
	register_taxonomy(
		'eixo',
		'obra',
		array(
			'labels'            => array(
				'name'          => 'Eixos/Áreas',
				'singular_name' => 'Eixo/Área',
			),
			'hierarchical'      => true, // select simples no admin (sem tag cloud).
			'show_admin_column' => true,
			'rewrite'           => array( 'slug' => 'area', 'with_front' => false ),
			'capabilities'      => mfm_taxonomia_fixa_caps(),
		)
	);

	register_taxonomy(
		'regiao',
		'obra',
		array(
			'labels'            => array(
				'name'          => 'Regiões',
				'singular_name' => 'Região',
			),
			'hierarchical'      => true,
			'show_admin_column' => true,
			'rewrite'           => array( 'slug' => 'regiao', 'with_front' => false ),
			'capabilities'      => mfm_taxonomia_fixa_caps(),
		)
	);

	// Taxonomia APOSENTADA (v1) — substituída por "eixo". Continua registrada
	// escondida só pra migração e histórico conseguirem ler os termos antigos;
	// não aparece em tela nenhuma e não gera URL.
	register_taxonomy(
		'categoria_obra',
		'obra',
		array(
			'labels'       => array( 'name' => 'Categorias (v1 — aposentada)' ),
			'hierarchical' => true,
			'public'       => false,
			'show_ui'      => false,
			'rewrite'      => false,
			'capabilities' => mfm_taxonomia_fixa_caps(),
		)
	);

	register_taxonomy(
		'bairro',
		'obra',
		array(
			'labels'            => array(
				'name'          => 'Bairros',
				'singular_name' => 'Bairro',
				'add_new_item'  => 'Adicionar bairro',
				'parent_item'   => 'Zona da cidade',
			),
			'description'       => 'Zonas da cidade são termos-pai; cadastre cada bairro dentro da sua zona.',
			'hierarchical'      => true,
			'show_admin_column' => true,
			'rewrite'           => array( 'slug' => 'bairro', 'with_front' => false ),
			'capabilities'      => mfm_obra_caps_taxonomia(),
		)
	);
}
add_action( 'init', 'mfm_registra_obra' );

/**
 * Bairros têm cap própria: quem gerencia obra gerencia os termos dela,
 * sem precisar de manage_categories (que abriria os Posts).
 */
function mfm_obra_caps_taxonomia() {
	return array(
		'manage_terms' => 'manage_obra_terms',
		'edit_terms'   => 'manage_obra_terms',
		'delete_terms' => 'manage_obra_terms',
		'assign_terms' => 'edit_obras',
	);
}

/**
 * Taxonomias fixas (eixo, região): termos só via código — a interface de
 * gerenciar termos fica bloqueada até pro administrador; atribuir a uma
 * obra continua liberado pra quem edita obras.
 */
function mfm_taxonomia_fixa_caps() {
	return array(
		'manage_terms' => 'do_not_allow',
		'edit_terms'   => 'do_not_allow',
		'delete_terms' => 'do_not_allow',
		'assign_terms' => 'edit_obras',
	);
}

/**
 * Concede as caps do CPT ao administrador (uma vez por versão) — com
 * capability_type próprio, nem o admin enxergaria Obras sem isso.
 */
function mfm_obras_concede_caps_admin() {
	if ( '1' === get_option( 'mfm_obras_caps' ) ) {
		return;
	}
	$admin = get_role( 'administrator' );
	if ( ! $admin ) {
		return;
	}

	$caps = array(
		'edit_obras',
		'edit_others_obras',
		'edit_published_obras',
		'edit_private_obras',
		'publish_obras',
		'read_private_obras',
		'delete_obras',
		'delete_others_obras',
		'delete_published_obras',
		'delete_private_obras',
		'manage_obra_terms',
	);
	foreach ( $caps as $cap ) {
		$admin->add_cap( $cap );
	}

	update_option( 'mfm_obras_caps', '1' );
}
add_action( 'init', 'mfm_obras_concede_caps_admin', 11 );

/**
 * Os eixos/áreas e as 6 regiões da cidade. Fonte única: seed, migração,
 * filtros, menus e mapa leem daqui. A lista de eixos pode ser ajustada no
 * painel "Maringá Faz Mais" (uma área por linha); vazia, vale o padrão
 * dos 9 eixos do escopo jul/2026.
 */
function mfm_eixos_fixos() {
	$padrao = array( 'Mobilidade', 'Saúde', 'Educação', 'Infraestrutura', 'Zeladoria', 'Esporte', 'Sustentabilidade', 'Tecnologia', 'Assistência Social' );

	$texto = function_exists( 'mfm_get' ) ? (string) mfm_get( 'eixos' ) : '';
	$eixos = array_values( array_filter( array_map( 'trim', preg_split( '/\r\n|\r|\n/', $texto ) ) ) );

	return $eixos ? $eixos : $padrao;
}

function mfm_regioes_fixas() {
	return array( 'Norte', 'Sul', 'Leste', 'Oeste', 'Centro', 'Distritos' );
}

/**
 * Termos iniciais (uma vez por versão): eixos e regiões fixos do escopo
 * jul/2026 + os termos-pai de bairro espelhando as regiões. Bairros em si
 * são cadastrados pela SECOM dentro da região.
 */
function mfm_seed_termos() {
	if ( get_option( 'mfm_obras_seed_v2' ) ) {
		return;
	}

	foreach ( mfm_eixos_fixos() as $eixo ) {
		if ( ! term_exists( $eixo, 'eixo' ) ) {
			wp_insert_term( $eixo, 'eixo' );
		}
	}

	foreach ( mfm_regioes_fixas() as $regiao ) {
		if ( ! term_exists( $regiao, 'regiao' ) ) {
			wp_insert_term( $regiao, 'regiao' );
		}
		// Termo-pai de bairro com o nome da região: é o vínculo
		// bairro → região (cada bairro nasce dentro de uma região).
		if ( ! term_exists( $regiao, 'bairro' ) ) {
			wp_insert_term( $regiao, 'bairro' );
		}
	}

	update_option( 'mfm_obras_seed_v2', 1 );
}
add_action( 'admin_init', 'mfm_seed_termos' );

/**
 * Regrava as regras de URL quando a estrutura do CPT muda de versão.
 */
function mfm_obras_flush_rewrite() {
	if ( '3' !== get_option( 'mfm_obras_rewrite' ) ) {
		flush_rewrite_rules();
		update_option( 'mfm_obras_rewrite', '3' );
	}
}
add_action( 'init', 'mfm_obras_flush_rewrite', 20 );

/**
 * Regra de negócio central — ao salvar como "Entregue":
 * progresso vai a 100%, a etapa do andamento fecha em "Entrega" e a data
 * de entrega é registrada (uma vez). Os contadores dos selos derivam
 * dessa meta, então o cache é invalidado.
 *
 * Vínculo bairro → região: se a obra tem bairro e a região ficou vazia,
 * herda a região do termo-pai do bairro.
 */
function mfm_obra_ao_salvar( $post_id ) {
	if ( 'obra' !== get_post_type( $post_id ) ) {
		return;
	}

	if ( 'entregue' === get_post_meta( $post_id, 'status', true ) ) {
		update_post_meta( $post_id, 'progresso', 100 );
		update_post_meta( $post_id, 'etapa_andamento', 'entrega' );
		if ( ! get_post_meta( $post_id, 'data_entrega', true ) ) {
			update_post_meta( $post_id, 'data_entrega', current_time( 'Ymd' ) );
		}
	} else {
		delete_post_meta( $post_id, 'data_entrega' );
	}

	if ( ! has_term( '', 'regiao', $post_id ) ) {
		$regiao = mfm_regiao_do_bairro( $post_id );
		if ( $regiao ) {
			wp_set_object_terms( $post_id, $regiao->term_id, 'regiao' );
			update_post_meta( $post_id, 'regiao', $regiao->term_id );
		}
	}

	// "As mais recentes marcadas": registra quando o destaque foi ligado —
	// mfm_obras_destaque() usa essa marca pra escolher as 4 da home.
	if ( '1' === get_post_meta( $post_id, 'destaque', true ) ) {
		if ( ! get_post_meta( $post_id, 'destaque_em', true ) ) {
			update_post_meta( $post_id, 'destaque_em', time() );
		}
	} else {
		delete_post_meta( $post_id, 'destaque_em' );
	}

	delete_transient( 'mfm_contadores' );
	delete_transient( 'mfm_contadores_status' );
}
add_action( 'acf/save_post', 'mfm_obra_ao_salvar', 20 );

/**
 * Descobre a região da obra pelo bairro: sobe até o termo-pai do bairro
 * (que tem o nome de uma região) e devolve o termo equivalente em "regiao".
 */
function mfm_regiao_do_bairro( $post_id ) {
	$bairros = get_the_terms( $post_id, 'bairro' );
	if ( ! $bairros || is_wp_error( $bairros ) ) {
		return null;
	}

	$topo = $bairros[0];
	while ( $topo->parent ) {
		$pai = get_term( $topo->parent, 'bairro' );
		if ( ! $pai || is_wp_error( $pai ) ) {
			break;
		}
		$topo = $pai;
	}

	$regiao = get_term_by( 'name', $topo->name, 'regiao' );
	return $regiao instanceof WP_Term ? $regiao : null;
}

// Mudanças fora do formulário ACF (quick edit, lixeira, wp-cli) também
// precisam derrubar o cache dos contadores.
function mfm_obra_limpa_contadores( $post_id ) {
	if ( 'obra' === get_post_type( $post_id ) ) {
		delete_transient( 'mfm_contadores' );
		delete_transient( 'mfm_contadores_status' );
	}
}
add_action( 'save_post_obra', 'mfm_obra_limpa_contadores' );
add_action( 'trashed_post', 'mfm_obra_limpa_contadores' );
add_action( 'untrashed_post', 'mfm_obra_limpa_contadores' );

/**
 * Cláusula de visibilidade: obras com "Visível" desligado saem do site
 * (meta ausente conta como visível — padrão do campo é ligado).
 */
function mfm_clausula_visivel() {
	return array(
		'relation' => 'OR',
		array(
			'key'   => 'visivel',
			'value' => '1',
		),
		array(
			'key'     => 'visivel',
			'compare' => 'NOT EXISTS',
		),
	);
}

/**
 * Esconde obras ocultas de qualquer listagem pública.
 */
function mfm_oculta_invisiveis( $query ) {
	if ( is_admin() ) {
		return;
	}
	$eh_obra = 'obra' === $query->get( 'post_type' ) || $query->is_tax( array( 'bairro', 'eixo', 'regiao' ) );
	if ( ! $eh_obra ) {
		return;
	}
	$meta_query   = (array) $query->get( 'meta_query' );
	$meta_query[] = mfm_clausula_visivel();
	$query->set( 'meta_query', $meta_query );
}
add_action( 'pre_get_posts', 'mfm_oculta_invisiveis' );

/**
 * Contadores dos selos do topo: "+X obras entregues", "X serviços
 * entregues", "X em andamento". Cacheado; invalidado a cada salvamento.
 */
function mfm_contadores() {
	$contadores = get_transient( 'mfm_contadores' );
	if ( is_array( $contadores ) ) {
		return $contadores;
	}

	$contadores = array(
		'obras_entregues'    => mfm_conta_obras( array( 'status' => 'entregue', 'tipo' => 'obra' ) ),
		'servicos_entregues' => mfm_conta_obras( array( 'status' => 'entregue', 'tipo' => 'servico' ) ),
		'em_andamento'       => mfm_conta_obras( array( 'status' => 'andamento' ) ),
	);
	set_transient( 'mfm_contadores', $contadores, HOUR_IN_SECONDS );

	return $contadores;
}

/**
 * Conta obras publicadas e visíveis filtrando por metas (status, tipo…).
 */
function mfm_conta_obras( $filtros ) {
	$meta_query = array( 'relation' => 'AND', mfm_clausula_visivel() );
	foreach ( $filtros as $chave => $valor ) {
		$meta_query[] = array(
			'key'   => $chave,
			'value' => $valor,
		);
	}

	$busca = new WP_Query(
		array(
			'post_type'      => 'obra',
			'post_status'    => 'publish',
			'posts_per_page' => -1,
			'fields'         => 'ids',
			'no_found_rows'  => true,
			'meta_query'     => $meta_query,
		)
	);

	return count( $busca->posts );
}

/**
 * Contagem de obras por status (os 5 do escopo jul/2026) — alimenta o
 * dashboard do painel (plugin MFM Painel). Cache próprio, invalidado nos
 * mesmos pontos do cache dos selos.
 */
function mfm_contadores_status() {
	$contadores = get_transient( 'mfm_contadores_status' );
	if ( is_array( $contadores ) ) {
		return $contadores;
	}

	$contadores = array();
	foreach ( array_keys( MFM_STATUS_ROTULOS ) as $status ) {
		$contadores[ $status ] = mfm_conta_obras( array( 'status' => $status ) );
	}
	set_transient( 'mfm_contadores_status', $contadores, HOUR_IN_SECONDS );

	return $contadores;
}

/**
 * Obras dos cards de destaque da home: marcadas como "Obra em destaque",
 * publicadas e visíveis — no máximo $limite (a home usa 4), ordenadas
 * pela movimentação mais recente: vale o que aconteceu por último entre
 * a última atualização (CPT) cadastrada e a última edição da própria
 * obra (mudou %, status etc., subiu na fila).
 */
function mfm_obras_destaque( $limite = 4 ) {
	$busca = new WP_Query(
		array(
			'post_type'      => 'obra',
			'post_status'    => 'publish',
			'posts_per_page' => -1,
			'no_found_rows'  => true,
			'meta_query'     => array(
				'relation' => 'AND',
				mfm_clausula_visivel(),
				array(
					'key'   => 'destaque',
					'value' => '1',
				),
			),
		)
	);

	$obras = $busca->posts;

	// Última atualização de cada obra candidata, numa consulta só. A data
	// do post da atualização já espelha o campo "Data" do cadastro.
	$ultimas = array();
	if ( $obras ) {
		$atualizacoes = get_posts(
			array(
				'post_type'      => 'atualizacao',
				'post_status'    => 'publish',
				'posts_per_page' => -1,
				'no_found_rows'  => true,
				'meta_query'     => array(
					array(
						'key'     => 'obra_relacionada',
						'value'   => wp_list_pluck( $obras, 'ID' ),
						'compare' => 'IN',
					),
				),
			)
		);
		foreach ( $atualizacoes as $atualizacao ) {
			$obra_id = (int) get_post_meta( $atualizacao->ID, 'obra_relacionada', true );
			$marca   = (int) get_post_time( 'U', false, $atualizacao );
			if ( $marca > ( $ultimas[ $obra_id ] ?? 0 ) ) {
				$ultimas[ $obra_id ] = $marca;
			}
		}
	}

	usort(
		$obras,
		function ( $a, $b ) use ( $ultimas ) {
			$marca_a = max( $ultimas[ $a->ID ] ?? 0, (int) get_post_modified_time( 'U', false, $a ) );
			$marca_b = max( $ultimas[ $b->ID ] ?? 0, (int) get_post_modified_time( 'U', false, $b ) );
			return $marca_b <=> $marca_a;
		}
	);

	return array_slice( $obras, 0, max( 1, (int) $limite ) );
}

/* -------------------------------------------------------------------------
 * Helpers do front público — home (etapa 3) e, na etapa 4, listagens,
 * ficha e página do mapa.
 * ---------------------------------------------------------------------- */

/**
 * Investimento formatado pra exibição: "R$ 1.250.000,50" (centavos zerados
 * são omitidos). Devolve '' sem valor — o template pula a linha.
 */
function mfm_formata_investimento( $valor ) {
	$valor = (float) $valor;
	if ( $valor <= 0 ) {
		return '';
	}
	$texto = number_format( $valor, 2, ',', '.' );
	return 'R$ ' . preg_replace( '/,00$/', '', $texto );
}

/**
 * Data de campo ACF (Ymd) como d/m/Y. Devolve '' se vazia/ inválida.
 */
function mfm_formata_data_campo( $ymd ) {
	$data = DateTime::createFromFormat( 'Ymd', (string) $ymd );
	return $data ? $data->format( 'd/m/Y' ) : '';
}

/**
 * Primeiro termo da obra numa taxonomia: [ 'nome' => …, 'slug' => … ]
 * (vazios se não houver) — eixo e região são termo único por obra.
 */
function mfm_termo_da_obra( $post_id, $taxonomia ) {
	$termos = get_the_terms( $post_id, $taxonomia );
	if ( ! $termos || is_wp_error( $termos ) ) {
		return array(
			'nome' => '',
			'slug' => '',
		);
	}
	return array(
		'nome' => $termos[0]->name,
		'slug' => $termos[0]->slug,
	);
}

/**
 * Obras pro mapa interativo (home e página Mapa de Obras): publicadas,
 * visíveis e com coordenadas. Cada item já sai pronto pro pin + popup —
 * o JS não formata nada, só monta o DOM.
 */
function mfm_obras_para_mapa() {
	$busca = new WP_Query(
		array(
			'post_type'      => 'obra',
			'post_status'    => 'publish',
			'posts_per_page' => -1,
			'no_found_rows'  => true,
			'meta_query'     => array(
				'relation' => 'AND',
				mfm_clausula_visivel(),
				array(
					'key'     => 'latitude',
					'value'   => '',
					'compare' => '!=',
				),
				array(
					'key'     => 'longitude',
					'value'   => '',
					'compare' => '!=',
				),
			),
		)
	);

	$obras = array();
	foreach ( $busca->posts as $obra ) {
		$lat = (float) get_post_meta( $obra->ID, 'latitude', true );
		$lng = (float) get_post_meta( $obra->ID, 'longitude', true );
		if ( ! $lat || ! $lng ) {
			continue;
		}

		$status = (string) get_post_meta( $obra->ID, 'status', true );
		$regiao = mfm_termo_da_obra( $obra->ID, 'regiao' );
		$eixo   = mfm_termo_da_obra( $obra->ID, 'eixo' );
		$bairro = mfm_termo_da_obra( $obra->ID, 'bairro' );

		$obras[] = array(
			'titulo'       => get_the_title( $obra ),
			'url'          => (string) get_permalink( $obra ),
			'lat'          => $lat,
			'lng'          => $lng,
			'status'       => $status,
			'statusRotulo' => mfm_status_rotulos()[ $status ] ?? '',
			'regiao'       => $regiao['slug'],
			'regiaoNome'   => $regiao['nome'],
			'eixo'         => $eixo['slug'],
			'eixoNome'     => $eixo['nome'],
			'bairro'       => $bairro['nome'],
			'bairroSlug'   => $bairro['slug'],
			'resumo'       => (string) get_post_meta( $obra->ID, 'descritivo_breve', true ),
			'investimento' => mfm_formata_investimento( get_post_meta( $obra->ID, 'investimento', true ) ),
			'previsao'     => mfm_formata_data_campo( get_post_meta( $obra->ID, 'prazo_previsto', true ) ),
			// Extras da página Mapa de Obras: card da obra selecionada abaixo do mapa.
			'foto'         => (string) get_the_post_thumbnail_url( $obra, 'medium_large' ),
			'progresso'    => min( 100, max( 0, (int) get_post_meta( $obra->ID, 'progresso', true ) ) ),
		);
	}

	return $obras;
}

/**
 * Pacote completo pro mapa interativo (window.mfmMapa) — home e página
 * Mapa de Obras usam o mesmo formato.
 */
function mfm_dados_mapa() {
	return array(
		'obras'  => mfm_obras_para_mapa(),
		'centro' => array( -23.4205, -51.9331 ), // Maringá.
		'zoom'   => 12,
	);
}

/* -------------------------------------------------------------------------
 * Admin: lista de obras amigável pra SECOM.
 * ---------------------------------------------------------------------- */

// 5 status do escopo jul/2026. As chaves antigas (planejada/andamento/
// entregue) não mudam: obra existente no banco continua válida sem
// recadastro. "chegando" × "planejada" seguem distintos até o cliente
// responder a pendência 1 do instrucoes.md.
const MFM_STATUS_ROTULOS = array(
	'entregue'  => 'Entregue',
	'andamento' => 'Em andamento',
	'recurso'   => 'Com recurso viabilizado',
	'chegando'  => 'Chegando',
	'planejada' => 'Planejada',
);

/**
 * Bairros com obra publicada, agrupados pela zona (termo-pai = região):
 * [ 'Norte' => [ WP_Term bairro, … ], … ]. Alimenta os selects de filtro
 * por bairro (listagens, mapas).
 */
function mfm_bairros_por_regiao() {
	$grupos = array();
	foreach ( get_terms( array( 'taxonomy' => 'bairro', 'parent' => 0, 'hide_empty' => false ) ) as $zona ) {
		$filhos = get_terms(
			array(
				'taxonomy'   => 'bairro',
				'parent'     => $zona->term_id,
				'hide_empty' => true,
				'orderby'    => 'name',
			)
		);
		if ( $filhos && ! is_wp_error( $filhos ) ) {
			$grupos[ $zona->name ] = $filhos;
		}
	}
	return $grupos;
}

/**
 * Rótulos exibidos dos 5 status: os padrões da constante, sobrescritos
 * pelo que o painel "Maringá Faz Mais" definir. As chaves são fixas —
 * cores, carimbo de entregue e contadores dependem delas; só o nome
 * mostrado no site muda.
 */
function mfm_status_rotulos() {
	$rotulos        = MFM_STATUS_ROTULOS;
	$personalizados = function_exists( 'mfm_get' ) ? (array) mfm_get( 'status_rotulos' ) : array();
	foreach ( $personalizados as $chave => $rotulo ) {
		$rotulo = trim( (string) $rotulo );
		if ( '' !== $rotulo && isset( $rotulos[ $chave ] ) ) {
			$rotulos[ $chave ] = $rotulo;
		}
	}
	return $rotulos;
}

// Etapas da linha de andamento da ficha (4 passos, nessa ordem).
const MFM_ETAPAS_ROTULOS = array(
	'planejamento' => 'Planejamento',
	'licitacao'    => 'Licitação',
	'execucao'     => 'Execução',
	'entrega'      => 'Entrega',
);

function mfm_obra_colunas( $colunas ) {
	return array(
		'cb'              => $colunas['cb'],
		'mfm_capa'        => 'Foto',
		'title'           => 'Título',
		'mfm_tipo'        => 'Tipo',
		'mfm_status'      => 'Status',
		'mfm_progresso'   => 'Progresso',
		'taxonomy-eixo'   => 'Eixo/Área',
		'taxonomy-regiao' => 'Região',
		'taxonomy-bairro' => 'Bairro',
		'mfm_visivel'     => 'Visível',
		'mfm_atualizada'  => 'Atualizada',
	);
}
add_filter( 'manage_obra_posts_columns', 'mfm_obra_colunas' );

function mfm_obra_colunas_ordenaveis( $colunas ) {
	$colunas['mfm_atualizada'] = 'modified';
	return $colunas;
}
add_filter( 'manage_edit-obra_sortable_columns', 'mfm_obra_colunas_ordenaveis' );

function mfm_obra_coluna_conteudo( $coluna, $post_id ) {
	switch ( $coluna ) {
		case 'mfm_capa':
			$thumb = get_the_post_thumbnail( $post_id, array( 60, 45 ) );
			if ( ! $thumb ) {
				$thumb = '<span class="mfm-capa--vazia dashicons dashicons-building" title="Sem foto de capa"></span>';
			}
			printf(
				'<a class="mfm-capa" href="%s" aria-label="Editar obra">%s</a>',
				esc_url( (string) get_edit_post_link( $post_id ) ),
				$thumb // get_the_post_thumbnail já vem escapado.
			);
			break;

		case 'mfm_tipo':
			echo 'servico' === get_post_meta( $post_id, 'tipo', true ) ? 'Serviço' : 'Obra';
			break;

		case 'mfm_status':
			$status = get_post_meta( $post_id, 'status', true );
			$rotulo = mfm_status_rotulos()[ $status ] ?? '—';
			printf( '<span class="mfm-badge mfm-badge--%s">%s</span>', esc_attr( $status ), esc_html( $rotulo ) );
			break;

		case 'mfm_progresso':
			$progresso = min( 100, max( 0, (int) get_post_meta( $post_id, 'progresso', true ) ) );
			printf(
				'<span class="mfm-barra" aria-hidden="true"><span class="mfm-barra__fill" style="width:%1$d%%"></span></span> %1$d%%',
				$progresso
			);
			break;

		case 'mfm_visivel':
			$oculta = '0' === get_post_meta( $post_id, 'visivel', true );
			echo $oculta ? '<span class="mfm-oculta">Oculta</span>' : 'Sim';
			break;

		case 'mfm_atualizada':
			printf(
				'%s<br><span class="mfm-col-apoio">há %s</span>',
				esc_html( (string) get_post_modified_time( 'd/m/Y H:i', false, $post_id ) ),
				esc_html( human_time_diff( (int) get_post_modified_time( 'U', false, $post_id ) ) )
			);
			break;
	}
}
add_action( 'manage_obra_posts_custom_column', 'mfm_obra_coluna_conteudo', 10, 2 );

/**
 * Filtros por status e tipo no topo da lista de obras.
 */
function mfm_obra_filtros_lista() {
	if ( 'obra' !== get_current_screen()->post_type ) {
		return;
	}

	$status_atual = sanitize_key( $_GET['mfm_status'] ?? '' );
	echo '<select name="mfm_status"><option value="">Todos os status</option>';
	foreach ( mfm_status_rotulos() as $valor => $rotulo ) {
		printf( '<option value="%s"%s>%s</option>', esc_attr( $valor ), selected( $status_atual, $valor, false ), esc_html( $rotulo ) );
	}
	echo '</select>';

	$tipo_atual = sanitize_key( $_GET['mfm_tipo'] ?? '' );
	echo '<select name="mfm_tipo"><option value="">Obras e serviços</option>';
	foreach ( array( 'obra' => 'Só obras', 'servico' => 'Só serviços' ) as $valor => $rotulo ) {
		printf( '<option value="%s"%s>%s</option>', esc_attr( $valor ), selected( $tipo_atual, $valor, false ), esc_html( $rotulo ) );
	}
	echo '</select>';

	// Eixo, região e bairro: o name do select é a query var da taxonomia,
	// então o WordPress aplica o filtro sozinho no edit.php.
	$taxonomias = array(
		'eixo'   => 'Todos os eixos',
		'regiao' => 'Todas as regiões',
		'bairro' => 'Todos os bairros',
	);
	foreach ( $taxonomias as $taxonomia => $rotulo ) {
		wp_dropdown_categories(
			array(
				'taxonomy'        => $taxonomia,
				'name'            => $taxonomia,
				'value_field'     => 'slug',
				'selected'        => sanitize_title( wp_unslash( $_GET[ $taxonomia ] ?? '' ) ),
				'show_option_all' => $rotulo,
				'hierarchical'    => 1,
				'hide_empty'      => 0,
			)
		);
	}
}
add_action( 'restrict_manage_posts', 'mfm_obra_filtros_lista' );

function mfm_obra_aplica_filtros( $query ) {
	global $typenow;
	if ( ! is_admin() || 'obra' !== $typenow || ! $query->is_main_query() ) {
		return;
	}

	$meta_query = (array) $query->get( 'meta_query' );
	foreach ( array( 'mfm_status' => 'status', 'mfm_tipo' => 'tipo' ) as $parametro => $meta ) {
		$valor = sanitize_key( $_GET[ $parametro ] ?? '' );
		if ( $valor ) {
			$meta_query[] = array(
				'key'   => $meta,
				'value' => $valor,
			);
		}
	}
	if ( $meta_query ) {
		$query->set( 'meta_query', $meta_query );
	}

	// Sem ordenação escolhida, a lista mostra o que mudou por último.
	if ( ! $query->get( 'orderby' ) && empty( $_GET['orderby'] ) ) {
		$query->set( 'orderby', 'modified' );
		$query->set( 'order', 'DESC' );
	}
}
add_action( 'pre_get_posts', 'mfm_obra_aplica_filtros' );

/**
 * Obra não se exclui, se oculta: tira lixeira da lista pra quem não é
 * administrador (SECOM usa o botão "Visível" e o histórico fica preservado).
 */
function mfm_obra_sem_lixeira( $acoes, $post ) {
	if ( 'obra' !== $post->post_type ) {
		return $acoes;
	}
	// "Edição rápida" sai pra todos: salva por fora do formulário da obra,
	// pulando as regras de negócio do cadastro (entregue, região etc.).
	unset( $acoes['inline hide-if-no-js'] );
	if ( ! current_user_can( 'manage_options' ) ) {
		unset( $acoes['trash'] );
	}
	return $acoes;
}
add_filter( 'post_row_actions', 'mfm_obra_sem_lixeira', 10, 2 );

/**
 * Dica no título e na foto de capa.
 */
function mfm_obra_placeholder_titulo( $texto, $post ) {
	return 'obra' === $post->post_type ? 'Nome da obra — curto e direto (máx. 40 caracteres)' : $texto;
}
add_filter( 'enter_title_here', 'mfm_obra_placeholder_titulo', 10, 2 );

function mfm_obra_dica_capa( $html, $post_id ) {
	if ( 'obra' === get_post_type( $post_id ) ) {
		$html .= '<p class="description">Foto principal do card na página e no compartilhamento em redes sociais. Recomendado: horizontal, 1200×675.</p>';
	}
	return $html;
}
add_filter( 'admin_post_thumbnail_html', 'mfm_obra_dica_capa', 10, 2 );

/**
 * Assets do admin nas telas da obra e da atualização: Leaflet (seletor de
 * coordenadas no mapa), JS de apoio e o CSS com a identidade da campanha
 * (cadastro e listagem).
 */
function mfm_obra_admin_assets( $hook ) {
	$screen = get_current_screen();
	if ( ! $screen || ! in_array( $screen->post_type, array( 'obra', 'atualizacao' ), true ) ) {
		return;
	}

	if ( 'obra' !== $screen->post_type ) {
		wp_enqueue_style(
			'mfm-admin-obra',
			MFM_URI . '/assets/css/admin-obra.css',
			array(),
			(string) filemtime( MFM_DIR . '/assets/css/admin-obra.css' )
		);
		return;
	}

	if ( in_array( $hook, array( 'post.php', 'post-new.php' ), true ) ) {
		wp_enqueue_style( 'mfm-leaflet', MFM_URI . '/assets/vendor/leaflet/leaflet.css', array(), '1.9.4' );
		wp_enqueue_script( 'mfm-leaflet', MFM_URI . '/assets/vendor/leaflet/leaflet.js', array(), '1.9.4', true );
		wp_enqueue_script(
			'mfm-admin-obra',
			MFM_URI . '/assets/js/admin-obra.js',
			array( 'jquery', 'mfm-leaflet' ),
			(string) filemtime( MFM_DIR . '/assets/js/admin-obra.js' ),
			true
		);
	}

	wp_enqueue_style(
		'mfm-admin-obra',
		MFM_URI . '/assets/css/admin-obra.css',
		array(),
		(string) filemtime( MFM_DIR . '/assets/css/admin-obra.css' )
	);
}
add_action( 'admin_enqueue_scripts', 'mfm_obra_admin_assets' );
