<?php
/**
 * Plugin Name:     WPJM Loxo Twice Daily Sync
 * Description:     Fetch open Loxo jobs twice daily and sync into WP Job Manager, dynamically creating and assigning types, categories, proper apply URL, geocoding locations, and letting WP handle permalinks.
 * Version:         2.1
 * Author:          Zaheer Anjum
 * Text Domain:     wpjm-loxo-daily-sync
 */

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

class WPJM_Loxo_Twice_Daily_Sync {
    const CRON_HOOK    = 'wpjm_loxo_twicedaily_sync';
    const AGENCY_SLUG  = 'red-seal-recruiting-solutions-ltd';
    const BEARER_TOKEN = '3c4e0ea97680e3c3c1d9499c2acab8bc513ab631b0966e2fc82653456b45716ba86b5c9c1346f5cdccad7b188235e222badb8be84b16674c9e4ff0f148c32750209945caa1a9ed03a5cc56eca42a5a2a4b34a72d5e1c6a2e249076772dcb93ae23dd4cbcee81ba2121833cf896890c4914a7e08ce96debe90bc205df0c04d1dc';
    const PER_PAGE      = 100;

    public function __construct() {
        add_action( 'init',         [ $this, 'maybe_schedule_cron' ], 20 );
        add_action( self::CRON_HOOK, [ $this, 'do_sync' ], 20 );
        register_activation_hook(   __FILE__, [ $this, 'on_activation' ] );
        register_deactivation_hook( __FILE__, [ $this, 'on_deactivation' ] );
    }

    public function maybe_schedule_cron() {
        if ( ! wp_next_scheduled( self::CRON_HOOK ) ) {
            wp_schedule_event( time(), 'twicedaily', self::CRON_HOOK );
        }
    }

    public function on_activation() {
        $this->maybe_schedule_cron();
    }

    public function on_deactivation() {
        wp_clear_scheduled_hook( self::CRON_HOOK );
    }

    public function do_sync() {
        $slug  = self::AGENCY_SLUG;
        $token = self::BEARER_TOKEN;

        if ( empty( $slug ) || empty( $token ) ) {
            error_log( 'WPJM Loxo Sync: Missing slug or token' );
            return;
        }

        $run_id      = gmdate( 'YmdHis' );
        $page        = 1;
        $total_pages = 1;

        do {
            $url = esc_url_raw(
                sprintf(
                    'https://app.loxo.co/api/%s/jobs?published=true&per_page=%d&page=%d',
                    $slug, self::PER_PAGE, $page
                )
            );
            $response = wp_remote_get( $url, [
                'headers' => [
                    'Accept'        => 'application/json',
                    'Authorization' => 'Bearer ' . $token,
                ],
                'timeout' => 20,
            ] );

            if ( is_wp_error( $response ) ) {
                error_log( 'WPJM Loxo Sync Error: ' . $response->get_error_message() );
                return;
            }

            $data = json_decode( wp_remote_retrieve_body( $response ) );
            if ( empty( $data->results ) || ! is_array( $data->results ) ) {
                break;
            }

            $total_pages = intval( $data->total_pages ?? $page );
            foreach ( $data->results as $summary ) {
                if ( isset( $summary->status->name ) && strcasecmp( $summary->status->name, 'Closed' ) === 0 ) {
                    continue;
                }
				
				if ( ! empty( $summary->categories ) && is_array( $summary->categories ) ) {
					foreach ( $summary->categories as $cat ) {
						if ( isset( $cat->name ) && strcasecmp( $cat->name, 'Allai' ) === 0 ) {
							continue 2;
						}
					}
				}

                $detail_url  = esc_url_raw( sprintf( 'https://app.loxo.co/api/%s/jobs/%d', $slug, intval( $summary->id ) ) );
                $detail_resp = wp_remote_get( $detail_url, [ 'headers'=>['Accept'=>'application/json','Authorization'=>'Bearer '.$token], 'timeout'=>20 ] );
                $job = is_wp_error( $detail_resp ) ? $summary : json_decode( wp_remote_retrieve_body( $detail_resp ) );

                $this->upsert_job( $job, $run_id );
            }

            $page++;
        } while ( $page <= $total_pages );

        $this->cleanup_stale( $run_id );
    }

    private function upsert_job( $job, $run_id ) {
        $job_id = intval( $job->id );
        $existing = get_posts( [
            'post_type'  => 'job_listing',
            'meta_key'   => '_loxo_job_id',
            'meta_value' => $job_id,
            'fields'     => 'ids',
        ] );

        $post_args = [
            'post_type'    => 'job_listing',
            'post_status'  => 'publish',
            'post_title'   => sanitize_text_field( $job->title ?? '' ),
            'post_content' => wp_kses_post( $job->description ?? '' ),
            'post_date'    => date( 'Y-m-d H:i:s', strtotime( $job->published_at ?? '' ) ),
        ];

        if ( $existing ) {
            $post_args['ID'] = $existing[0];
        }

        $post_id = wp_insert_post( $post_args, true );
        if ( is_wp_error( $post_id ) ) {
            error_log( 'WPJM Loxo Sync: failed job ' . $job_id );
            return;
        }

        update_post_meta( $post_id, '_loxo_job_id',   $job_id );
        update_post_meta( $post_id, '_loxo_sync_run',  $run_id );
        update_post_meta( $post_id, '_job_location',   sanitize_text_field( $job->macro_address ?? '' ) );
        update_post_meta( $post_id, '_job_salary',     sanitize_text_field( $job->salary ?? '' ) );
        update_post_meta( $post_id, '_company_name',   sanitize_text_field( $job->company->name ?? '' ) );

		// mark _every_ Loxo job as featured
		update_post_meta( $post_id, '_featured', '1' );
		
        // apply URL
        $apply_url = rtrim( esc_url_raw( $job->public_url ?? '' ), '/' ) . '/form?source_type=app';
        update_post_meta( $post_id, '_application', esc_url_raw( $apply_url ) );

        // Job Type
        if ( ! empty( $job->job_type->name ) ) {
            $type_name = sanitize_text_field( $job->job_type->name );
            if ( ! term_exists( $type_name, 'job_listing_type' ) ) {
                wp_insert_term( $type_name, 'job_listing_type' );
            }
            wp_set_object_terms( $post_id, $type_name, 'job_listing_type', false );
            update_post_meta( $post_id, '_job_type', $type_name );
        }

        // Job Categories
        if ( ! empty( $job->categories ) && is_array( $job->categories ) ) {
            $names = [];
            foreach ( $job->categories as $cat ) {
                $name = sanitize_text_field( $cat->name );
                if ( $name && ! term_exists( $name, 'job_listing_category' ) ) {
                    wp_insert_term( $name, 'job_listing_category' );
                }
                $names[] = $name;
            }
            if ( $names ) {
                wp_set_object_terms( $post_id, $names, 'job_listing_category', false );
            }
        }

        // Region
        if ( ! empty( $job->macro_address ) ) {
            $region = sanitize_text_field( $job->macro_address );
            if ( ! term_exists( $region, 'job_listing_region' ) ) {
                wp_insert_term( $region, 'job_listing_region' );
            }
            wp_set_object_terms( $post_id, $region, 'job_listing_region', true );
        }

        // Geocode
        if ( function_exists( 'update_job_location_data' ) ) {
            update_job_location_data( $post_id, sanitize_text_field( $job->macro_address ?? '' ) );
        }
    }

    private function cleanup_stale( $run_id ) {
        $stale = get_posts( [
            'post_type'      => 'job_listing',
            'posts_per_page' => -1,
            'meta_query'     => [[ 'key' => '_loxo_sync_run','value'=>$run_id,'compare'=>'!=' ]],
            'fields'         => 'ids',
        ] );
        foreach ( $stale as $id ) {
            wp_delete_post( $id, true );
        }
    }
}

new WPJM_Loxo_Twice_Daily_Sync();