<?php
/**
 * Plugin Name: Category Sync — Importer (NEW SITE)
 * Description: Connects to the old site's API, imports correct categories, and auto-reassigns all posts. Install on NEW site only.
 * Version: 1.0
 * Author: Migration Tool
 */

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

class CategorySyncImporter {

    private $settings_key = 'cat_sync_importer_settings';
    private $log_key      = 'cat_sync_import_log';

    public function __construct() {
        add_action('admin_menu',               [$this, 'add_menu']);
        add_action('admin_init',               [$this, 'handle_actions']);
        add_action('wp_ajax_cat_sync_run',     [$this, 'ajax_run_sync']);
        add_action('wp_ajax_cat_sync_preview', [$this, 'ajax_preview']);
        add_action('admin_enqueue_scripts',    [$this, 'enqueue_assets']);
    }

    public function enqueue_assets($hook) {
        if ($hook !== 'toplevel_page_cat-sync-importer') return;
        wp_enqueue_style('google-fonts-importer', 'https://fonts.googleapis.com/css2?family=Syne:wght@400;700;800&family=DM+Mono:wght@400;500&display=swap', [], null);
    }

    public function add_menu() {
        add_menu_page(
            'Category Sync Importer',
            '📥 Cat Sync Importer',
            'manage_options',
            'cat-sync-importer',
            [$this, 'render_page'],
            'dashicons-database-import',
            80
        );
    }

    public function handle_actions() {
        if (isset($_POST['cat_sync_save_settings']) && check_admin_referer('cat_sync_importer')) {
            update_option($this->settings_key, [
                'api_url' => sanitize_url($_POST['api_url']),
                'api_key' => sanitize_text_field($_POST['api_key']),
            ]);
        }
        if (isset($_POST['cat_sync_clear_log']) && check_admin_referer('cat_sync_importer')) {
            delete_option($this->log_key);
        }
    }

    private function fetch_from_old_site($settings) {
        $response = wp_remote_get($settings['api_url'], [
            'timeout' => 60,
            'headers' => ['X-Cat-Sync-Key' => $settings['api_key']],
        ]);
        if (is_wp_error($response)) return ['error' => $response->get_error_message()];
        $code = wp_remote_retrieve_response_code($response);
        if ($code !== 200) return ['error' => "HTTP $code — Check your API URL and Key"];
        $body = json_decode(wp_remote_retrieve_body($response), true);
        if (!$body || !$body['success']) return ['error' => 'Invalid response from old site'];
        return $body;
    }

    public function ajax_preview() {
        check_ajax_referer('cat_sync_ajax', 'nonce');
        if (!current_user_can('manage_options')) wp_send_json_error('Unauthorized');
        $settings = get_option($this->settings_key, []);
        if (empty($settings['api_url']) || empty($settings['api_key'])) {
            wp_send_json_error('Please save your API URL and Key first.');
        }
        $data = $this->fetch_from_old_site($settings);
        if (isset($data['error'])) wp_send_json_error($data['error']);
        wp_send_json_success($this->build_sync_plan($data));
    }

    public function ajax_run_sync() {
        check_ajax_referer('cat_sync_ajax', 'nonce');
        if (!current_user_can('manage_options')) wp_send_json_error('Unauthorized');
        $settings = get_option($this->settings_key, []);
        if (empty($settings['api_url']) || empty($settings['api_key'])) {
            wp_send_json_error('Please save your API URL and Key first.');
        }
        $data = $this->fetch_from_old_site($settings);
        if (isset($data['error'])) wp_send_json_error($data['error']);
        $result = $this->run_sync($data);
        update_option($this->log_key, $result);
        wp_send_json_success($result);
    }

    private function build_sync_plan($data) {
        $plan = [
            'categories_to_create' => [],
            'posts_to_reassign'    => 0,
            'matches'              => [],
        ];
        foreach ($data['categories'] as $cat) {
            if (!get_term_by('slug', $cat['slug'], 'category')) {
                $plan['categories_to_create'][] = $cat;
            }
        }
        foreach ($data['post_category_map'] as $item) {
            $local = get_posts(['name' => $item['post_slug'], 'post_status' => 'any', 'numberposts' => 1]);
            if ($local) {
                $plan['posts_to_reassign']++;
                $plan['matches'][] = [
                    'post_id'    => $local[0]->ID,
                    'post_title' => $item['post_title'],
                    'categories' => $item['categories'],
                ];
            }
        }
        return $plan;
    }

    private function run_sync($data) {
        $plan = $this->build_sync_plan($data);
        $log  = [
            'ran_at'             => current_time('mysql'),
            'categories_created' => [],
            'posts_fixed'        => 0,
            'posts_skipped'      => 0,
            'junk_deleted'       => 0,
            'errors'             => [],
        ];

        foreach ($plan['categories_to_create'] as $cat) {
            $result = wp_insert_term($cat['name'], 'category', ['slug' => $cat['slug'], 'description' => $cat['description']]);
            if (!is_wp_error($result)) {
                $log['categories_created'][] = $cat['name'];
            } else {
                $log['errors'][] = "Failed to create: {$cat['name']} — " . $result->get_error_message();
            }
        }

        foreach ($plan['matches'] as $match) {
            $cat_ids = [];
            foreach ($match['categories'] as $slug) {
                $term = get_term_by('slug', $slug, 'category');
                if ($term) $cat_ids[] = $term->term_id;
            }
            if (!empty($cat_ids)) {
                wp_set_post_categories($match['post_id'], $cat_ids, false);
                $log['posts_fixed']++;
            } else {
                $log['posts_skipped']++;
                $log['errors'][] = "No categories found for: {$match['post_title']}";
            }
        }

        $old_slugs    = array_column($data['categories'], 'slug');
        $all_new_cats = get_terms(['taxonomy' => 'category', 'hide_empty' => false]);
        foreach ($all_new_cats as $cat) {
            if (!in_array($cat->slug, $old_slugs) && $cat->count == 0 && $cat->slug !== 'uncategorized') {
                wp_delete_term($cat->term_id, 'category');
                $log['junk_deleted']++;
            }
        }

        return $log;
    }

    public function render_page() {
        $settings = get_option($this->settings_key, ['api_url' => '', 'api_key' => '']);
        $last_log = get_option($this->log_key, null);
        $nonce    = wp_create_nonce('cat_sync_ajax');
        ?>
        <style>
        *{box-sizing:border-box;margin:0;padding:0}
        #csi-wrap{font-family:'Syne',sans-serif;background:#060610;min-height:100vh;padding:40px;color:#e8e8f0}
        .csi-badge{display:inline-block;background:linear-gradient(135deg,#6366f1,#a5b4fc);color:#fff;font-size:11px;font-weight:700;letter-spacing:2px;text-transform:uppercase;padding:4px 12px;border-radius:20px;margin-bottom:10px}
        .csi-h1{font-size:32px;font-weight:800;background:linear-gradient(90deg,#6366f1,#a5b4fc);-webkit-background-clip:text;-webkit-text-fill-color:transparent}
        .csi-sub{color:#555;font-size:14px;margin-top:4px;font-family:'DM Mono',monospace}
        .csi-layout{display:grid;grid-template-columns:380px 1fr;gap:24px;max-width:1100px;margin-top:36px}
        .csi-card{background:#0e0e1a;border:1px solid #1a1a2e;border-radius:16px;padding:28px;margin-bottom:24px}
        .csi-card h2{font-size:13px;font-weight:700;color:#6366f1;margin-bottom:18px;text-transform:uppercase;letter-spacing:1px}
        .csi-field{margin-bottom:16px}
        .csi-field label{display:block;font-size:11px;color:#777;margin-bottom:7px;text-transform:uppercase;letter-spacing:1px}
        .csi-field input{width:100%;background:#060610;border:1px solid #1a1a2e;border-radius:8px;padding:11px 14px;font-family:'DM Mono',monospace;font-size:13px;color:#a5b4fc;outline:none;transition:border-color .2s}
        .csi-field input:focus{border-color:#6366f1}
        .csi-btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:12px 20px;border-radius:10px;font-family:'Syne',sans-serif;font-size:14px;font-weight:700;cursor:pointer;border:none;transition:all .2s;width:100%;margin-bottom:10px}
        .csi-btn:hover{transform:translateY(-1px)}
        .csi-btn:disabled{opacity:.4;cursor:not-allowed;transform:none}
        .btn-save{background:#1a1a2e;color:#a5b4fc;border:1px solid #2a2a4e}
        .btn-preview{background:#0f0f22;color:#818cf8;border:1px solid #2a2a4e}
        .btn-run{background:linear-gradient(135deg,#6366f1,#818cf8);color:#fff}
        .btn-danger{background:#1a0a0a;color:#f87171;border:1px solid #3a1a1a;font-size:12px;padding:8px 16px;width:auto}
        #csi-status{display:none;background:#060610;border:1px solid #1a1a2e;border-radius:10px;padding:16px;margin-top:14px;font-family:'DM Mono',monospace;font-size:13px;line-height:1.8}
        #csi-status.on{display:block}
        .spin{display:inline-block;width:13px;height:13px;border:2px solid #333;border-top-color:#6366f1;border-radius:50%;animation:sp .7s linear infinite;vertical-align:middle;margin-right:8px}
        @keyframes sp{to{transform:rotate(360deg)}}
        .stat-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:18px}
        .stat-box{background:#060610;border:1px solid #1a1a2e;border-radius:10px;padding:16px;text-align:center}
        .stat-val{font-size:28px;font-weight:800;color:#6366f1;font-family:'DM Mono',monospace}
        .stat-lbl{font-size:11px;color:#555;margin-top:4px}
        .log-list{list-style:none;max-height:260px;overflow-y:auto}
        .log-list li{padding:6px 0;border-bottom:1px solid #1a1a2e;font-family:'DM Mono',monospace;font-size:12px;color:#aaa;display:flex;gap:8px;align-items:center}
        .log-list li:last-child{border-bottom:none}
        .tag{font-size:10px;padding:2px 8px;border-radius:10px;font-weight:700;text-transform:uppercase;white-space:nowrap}
        .tg{background:#052e16;color:#4ade80}
        .tr{background:#2e0505;color:#f87171}
        .tb{background:#05142e;color:#60a5fa}
        .preview-table{width:100%;border-collapse:collapse;font-size:12px}
        .preview-table th{text-align:left;color:#6366f1;font-size:11px;text-transform:uppercase;letter-spacing:1px;padding:8px 0;border-bottom:1px solid #1a1a2e}
        .preview-table td{padding:7px 0;border-bottom:1px solid #0e0e1a;color:#bbb;font-family:'DM Mono',monospace}
        .section-title{color:#6366f1;font-size:12px;text-transform:uppercase;letter-spacing:1px;margin:18px 0 10px;font-weight:700}
        </style>

        <div id="csi-wrap">
            <span class="csi-badge">New Site</span>
            <h1 class="csi-h1">Category Sync — Importer</h1>
            <p class="csi-sub">Pull categories from old site → create them → fix all post assignments automatically</p>

            <div class="csi-layout">
                <div>
                    <div class="csi-card">
                        <h2>⚙️ Connection</h2>
                        <form method="post">
                            <?php wp_nonce_field('cat_sync_importer'); ?>
                            <div class="csi-field">
                                <label>Old Site API URL</label>
                                <input type="url" name="api_url" placeholder="https://oldsite.com/wp-json/cat-sync/v1/export" value="<?= esc_attr($settings['api_url']) ?>">
                            </div>
                            <div class="csi-field">
                                <label>Secret Key</label>
                                <input type="text" name="api_key" placeholder="cse_xxxxxxxxxxxx" value="<?= esc_attr($settings['api_key']) ?>">
                            </div>
                            <button type="submit" name="cat_sync_save_settings" class="csi-btn btn-save">💾 Save Settings</button>
                        </form>
                        <button id="btn-preview" class="csi-btn btn-preview" onclick="runPreview()">👁 Preview Changes</button>
                        <button id="btn-run" class="csi-btn btn-run" onclick="runSync()">🚀 Run Full Sync</button>
                        <div id="csi-status"></div>
                    </div>

                    <?php if ($last_log): ?>
                    <div class="csi-card">
                        <h2>🕐 Last Sync — <?= esc_html($last_log['ran_at']) ?></h2>
                        <div class="stat-grid">
                            <div class="stat-box"><div class="stat-val" style="color:#4ade80"><?= $last_log['posts_fixed'] ?></div><div class="stat-lbl">Posts Fixed</div></div>
                            <div class="stat-box"><div class="stat-val"><?= count($last_log['categories_created']) ?></div><div class="stat-lbl">Cats Created</div></div>
                            <div class="stat-box"><div class="stat-val"><?= $last_log['junk_deleted'] ?></div><div class="stat-lbl">Junk Deleted</div></div>
                            <div class="stat-box"><div class="stat-val" style="color:#f87171"><?= $last_log['posts_skipped'] ?></div><div class="stat-lbl">Skipped</div></div>
                        </div>
                        <form method="post">
                            <?php wp_nonce_field('cat_sync_importer'); ?>
                            <button type="submit" name="cat_sync_clear_log" class="csi-btn btn-danger">🗑 Clear Log</button>
                        </form>
                    </div>
                    <?php endif; ?>
                </div>

                <div>
                    <div class="csi-card" style="min-height:340px">
                        <h2>📋 Output</h2>
                        <div id="results-content" style="color:#444;font-family:'DM Mono',monospace;font-size:13px">
                            ↖ Save settings, then click Preview or Run Sync.
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <script>
        const nonce='<?= esc_js($nonce) ?>',ajaxUrl='<?= esc_js(admin_url('admin-ajax.php')) ?>';
        function setStatus(msg,loading=true){const e=document.getElementById('csi-status');e.classList.add('on');e.innerHTML=loading?`<span class="spin"></span>${msg}`:msg}
        function setResults(html){document.getElementById('results-content').innerHTML=html}
        function setBtns(disabled){['btn-preview','btn-run'].forEach(id=>document.getElementById(id).disabled=disabled)}

        async function runPreview(){
            setBtns(true);setStatus('Connecting to old site...');setResults('<span style="color:#555">Loading preview...</span>');
            const res=await fetch(ajaxUrl,{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:new URLSearchParams({action:'cat_sync_preview',nonce})});
            const json=await res.json();setBtns(false);
            if(!json.success){setStatus('❌ '+json.data,false);setResults(`<span style="color:#f87171">${json.data}</span>`);return}
            setStatus('✅ Preview ready. Click Run Sync to apply.',false);
            const d=json.data;
            let html=`<div class="stat-grid"><div class="stat-box"><div class="stat-val">${d.posts_to_reassign}</div><div class="stat-lbl">Posts to Fix</div></div><div class="stat-box"><div class="stat-val">${d.categories_to_create.length}</div><div class="stat-lbl">Cats to Create</div></div></div>`;
            if(d.categories_to_create.length){html+=`<p class="section-title">Categories to Create</p><ul class="log-list">`;d.categories_to_create.forEach(c=>{html+=`<li><span class="tag tb">new</span>${c.name}</li>`});html+=`</ul>`}
            if(d.matches.length){html+=`<p class="section-title">Post Matches (preview)</p><table class="preview-table"><thead><tr><th>Post</th><th>Will be assigned to</th></tr></thead><tbody>`;d.matches.slice(0,25).forEach(m=>{html+=`<tr><td>${m.post_title}</td><td>${m.categories.join(', ')}</td></tr>`});if(d.matches.length>25)html+=`<tr><td colspan="2" style="color:#444">...and ${d.matches.length-25} more</td></tr>`;html+=`</tbody></table>`}
            setResults(html);
        }

        async function runSync(){
            if(!confirm('This will reassign post categories on this site. Continue?'))return;
            setBtns(true);setStatus('🚀 Syncing... please wait.');setResults('<span style="color:#555">Working...</span>');
            const res=await fetch(ajaxUrl,{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:new URLSearchParams({action:'cat_sync_run',nonce})});
            const json=await res.json();setBtns(false);
            if(!json.success){setStatus('❌ '+json.data,false);setResults(`<span style="color:#f87171">${json.data}</span>`);return}
            const d=json.data;setStatus('🎉 Done! Page will reload in 3s.',false);
            let html=`<div class="stat-grid"><div class="stat-box"><div class="stat-val" style="color:#4ade80">${d.posts_fixed}</div><div class="stat-lbl">Posts Fixed</div></div><div class="stat-box"><div class="stat-val">${d.categories_created.length}</div><div class="stat-lbl">Cats Created</div></div><div class="stat-box"><div class="stat-val">${d.junk_deleted}</div><div class="stat-lbl">Junk Deleted</div></div><div class="stat-box"><div class="stat-val" style="color:#f87171">${d.posts_skipped}</div><div class="stat-lbl">Skipped</div></div></div>`;
            if(d.categories_created.length){html+=`<p class="section-title">Created</p><ul class="log-list">`;d.categories_created.forEach(c=>{html+=`<li><span class="tag tg">✓</span>${c}</li>`});html+=`</ul>`}
            if(d.errors.length){html+=`<p class="section-title">Errors</p><ul class="log-list">`;d.errors.forEach(e=>{html+=`<li><span class="tag tr">!</span>${e}</li>`});html+=`</ul>`}
            setResults(html);setTimeout(()=>location.reload(),3000);
        }
        </script>
        <?php
    }
}

new CategorySyncImporter();
