<?php
namespace BLR\Backline\Modules\Contacts;

use BLR\Backline\Core\Access;
use BLR\Backline\Core\CrudHelpers;
use BLR\Backline\Core\ListPage;
use BLR\Backline\Core\PostQueries;
use BLR\Backline\Core\Request;
use BLR\Backline\Core\Router;
use BLR\Backline\Core\Views;
use BLR\Backline\Modules\Outreach\Module as OutreachModule;

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

final class Pages {
    public static function render_list(array $ctx): string {
        $ctx['contacts_list'] = self::list_data($ctx);
        return Views::render('pages/contacts', $ctx);
    }

    public static function render_form(array $ctx): string {
        $ctx['contact_form'] = self::form_data($ctx);
        return Views::render('pages/contact-form', $ctx);
    }

    public static function render_view(array $ctx): string {
        $ctx['contact_view'] = self::view_data($ctx);
        return Views::render('pages/view-contact', $ctx);
    }

    public static function handle_delete(array $ctx): string {
        return self::handle_post_delete($ctx, 'blr_contact', 'contacts');
    }

    public static function list_data(array $ctx): array {
        $base = ListPage::base_url($ctx);
        $page_num = Views::current_page_from_query_arg('pg');
        $view_mode = ListPage::view_mode();
        $new_url = $base . 'contacts/new/';
        $search_term = Request::query_text('s');
        $contact_type_filter = Request::query_text('contact_type');
        $newsletter_filter = Request::query_key('newsletter');
        $outreach_status_filter = Request::query_text('outreach_status');
        $type_options = Contacts::type_options();

        if ($newsletter_filter !== '' && !in_array($newsletter_filter, ['subscribed', 'pending', 'not_subscribed'], true)) {
            $newsletter_filter = '';
        }

        $query_args = [
            'post_type'      => 'blr_contact',
            'post_status'    => ['publish'],
            'posts_per_page' => 25,
            'paged'          => $page_num,
            'orderby'        => 'date',
            'order'          => 'DESC',
        ];

        if ($search_term !== '') {
            $query_args['s'] = $search_term;
        }

        $meta_query = [];
        if ($contact_type_filter !== '' && in_array($contact_type_filter, $type_options, true)) {
            $meta_query[] = [
                'key'   => 'blr_contact_type',
                'value' => $contact_type_filter,
            ];
        }

        if ($newsletter_filter === 'subscribed') {
            $meta_query[] = NewsletterDoubleOptIn::subscribed_meta_query();
        } elseif ($newsletter_filter === 'pending') {
            $meta_query[] = NewsletterDoubleOptIn::pending_meta_query();
        } elseif ($newsletter_filter === 'not_subscribed') {
            $meta_query[] = NewsletterDoubleOptIn::not_subscribed_meta_query();
        }

        if ($outreach_status_filter !== '' && in_array($outreach_status_filter, OutreachModule::recipient_statuses(), true)) {
            $meta_query[] = [
                'key'   => 'blr_contact_outreach_status',
                'value' => $outreach_status_filter,
            ];
        }

        if (!empty($meta_query)) {
            // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- Contact archive intentionally filters by stored contact meta.
            $query_args['meta_query'] = PostQueries::and_meta_query($meta_query);
        }

        $contacts = new \WP_Query($query_args);
        $contacts_summary = Views::pagination_summary_data($contacts, 'pg');

        $persist_args = [];
        if ($search_term !== '') {
            $persist_args['s'] = $search_term;
        }
        if ($contact_type_filter !== '') {
            $persist_args['contact_type'] = $contact_type_filter;
        }
        if ($newsletter_filter !== '') {
            $persist_args['newsletter'] = $newsletter_filter;
        }
        if ($outreach_status_filter !== '') {
            $persist_args['outreach_status'] = $outreach_status_filter;
        }

        $contact_items = [];
        foreach ((array) $contacts->posts as $post) {
            if (!$post instanceof \WP_Post) {
                continue;
            }

            $post_id = (int) $post->ID;
            $email = (string) get_post_meta($post_id, 'blr_contact_email', true);
            $type = (string) get_post_meta($post_id, 'blr_contact_type', true);
            $company = (string) get_post_meta($post_id, 'blr_contact_company', true);
            $newsletter_status = NewsletterDoubleOptIn::get_status($post_id);
            $last_contacted = (string) get_post_meta($post_id, 'blr_contact_last_contacted', true);
            $outreach_status = (string) get_post_meta($post_id, 'blr_contact_outreach_status', true);

            $contact_items[] = [
                'id'                => $post_id,
                'title'             => get_the_title($post),
                'email'             => $email,
                'type'              => $type,
                'type_label'        => $type !== '' ? Contacts::type_label($type) : '',
                'company'           => $company,
                'newsletter_status' => $newsletter_status,
                'newsletter_label'  => NewsletterDoubleOptIn::status_label($newsletter_status),
                'last_contacted'    => $last_contacted,
                'outreach_status'   => $outreach_status,
                'outreach_label'    => $outreach_status !== '' ? OutreachModule::status_label($outreach_status) : '',
                'view_url'          => $base . 'contacts/view/' . $post_id . '/',
                'edit_url'          => $base . 'contacts/edit/' . $post_id . '/',
                'delete_url'        => $base . 'contacts/delete/' . $post_id . '/',
            ];
        }

        return array_merge(ListPage::notices(), ListPage::view_urls($base, 'contacts', $persist_args, $view_mode), [
            'base'                   => $base,
            'page_num'               => $page_num,
            'new_url'                => $new_url,
            'search_term'            => $search_term,
            'contact_type_filter'    => $contact_type_filter,
            'newsletter_filter'      => $newsletter_filter,
            'outreach_status_filter' => $outreach_status_filter,
            'view_mode'              => $view_mode,
            'type_options'           => $type_options,
            'contacts'               => $contacts,
            'contacts_summary'       => $contacts_summary,
            'contact_items'          => $contact_items,
        ]);
    }

    public static function form_data(array $ctx): array {
        $base = ListPage::base_url($ctx);
        $is_edit = ($ctx['action'] ?? '') === 'edit';
        $post_id = $is_edit ? (int) ($ctx['id'] ?? 0) : 0;
        $post = $post_id ? get_post($post_id) : null;
        $errors = isset($ctx['errors']) && is_array($ctx['errors']) ? $ctx['errors'] : [];
        $submitted_nonce = isset($_POST['_wpnonce']) ? sanitize_text_field((string) wp_unslash($_POST['_wpnonce'])) : '';
        $failed_post = !empty($errors) && Request::method() === 'POST' && wp_verify_nonce($submitted_nonce, 'blr_ba_save_contact');

        $posted_values = [];
        if ($failed_post) {
            $posted_status_raw = Request::post_text('blr_contact_newsletter_status');
            $posted_status = in_array($posted_status_raw, NewsletterDoubleOptIn::status_options(), true)
                ? $posted_status_raw
                : (Request::post_absint('blr_contact_newsletter_signup') > 0 ? NewsletterDoubleOptIn::STATUS_SUBSCRIBED : NewsletterDoubleOptIn::STATUS_NOT_SUBSCRIBED);

            $posted_values = [
                'title'                         => Request::post_text('title'),
                'notes'                         => Request::post_kses('notes'),
                'blr_contact_first_name'        => Request::post_text('blr_contact_first_name'),
                'blr_contact_role'              => Request::post_text('blr_contact_role'),
                'blr_contact_type'              => Request::post_text('blr_contact_type'),
                'blr_contact_company'           => Request::post_text('blr_contact_company'),
                'blr_contact_email'             => Request::post_email('blr_contact_email'),
                'blr_contact_phone'             => Request::post_text('blr_contact_phone'),
                'blr_contact_website'           => Request::post_url('blr_contact_website'),
                'blr_contact_city'              => Request::post_text('blr_contact_city'),
                'blr_contact_state'             => Request::post_text('blr_contact_state'),
                'blr_contact_newsletter_status' => $posted_status,
                'blr_contact_notes'             => Request::post_kses('blr_contact_notes'),
            ];
        }

        return [
            'base'              => $base,
            'is_edit'           => $is_edit,
            'post_id'           => $post_id,
            'post'              => $post,
            'saved_notice'      => Request::query_absint('saved'),
            'errors'            => $errors,
            'failed_post'       => $failed_post,
            'posted_values'     => $posted_values,
            'title_v'           => $failed_post ? (string) ($posted_values['title'] ?? '') : ($post instanceof \WP_Post ? (string) $post->post_title : ''),
            'notes_v'           => $failed_post ? (string) ($posted_values['notes'] ?? '') : ($post instanceof \WP_Post ? (string) $post->post_content : ''),
            'type_options'      => Contacts::type_options(),
            'newsletter_status' => self::contact_meta_value($post_id, 'blr_contact_newsletter_status', $failed_post, $posted_values),
        ];
    }

    public static function view_data(array $ctx): array {
        $base = ListPage::base_url($ctx);
        $id = (int) ($ctx['id'] ?? 0);
        $post = $id ? get_post($id) : null;
        if (!$post instanceof \WP_Post || $post->post_type !== 'blr_contact') {
            return ['not_found' => true, 'base' => $base, 'id' => $id, 'post' => null];
        }

        // Backline contacts are intentionally shared inside the allowed Backline workspace.
        // The route-level module/capability guard decides workspace access; individual contacts are not per-user private records.
        $type = (string) get_post_meta($id, 'blr_contact_type', true);
        $newsletter_status = NewsletterDoubleOptIn::get_status($id);

        return [
            'not_found'             => false,
            'base'                  => $base,
            'id'                    => $id,
            'post'                  => $post,
            'edit_url'              => $base . 'contacts/edit/' . $id . '/',
            'delete_url'            => $base . 'contacts/delete/' . $id . '/',
            'first_name'            => (string) get_post_meta($id, 'blr_contact_first_name', true),
            'email'                 => (string) get_post_meta($id, 'blr_contact_email', true),
            'phone'                 => (string) get_post_meta($id, 'blr_contact_phone', true),
            'role'                  => (string) get_post_meta($id, 'blr_contact_role', true),
            'type'                  => $type,
            'company'               => (string) get_post_meta($id, 'blr_contact_company', true),
            'city'                  => (string) get_post_meta($id, 'blr_contact_city', true),
            'state'                 => (string) get_post_meta($id, 'blr_contact_state', true),
            'website'               => (string) get_post_meta($id, 'blr_contact_website', true),
            'newsletter_status'     => $newsletter_status,
            'newsletter_requested'  => (string) get_post_meta($id, NewsletterDoubleOptIn::META_REQUESTED_GMT, true),
            'newsletter_confirmed'  => (string) get_post_meta($id, NewsletterDoubleOptIn::META_CONFIRMED_GMT, true),
            'internal_notes'        => (string) get_post_meta($id, 'blr_contact_notes', true),
            'last_contacted'        => (string) get_post_meta($id, 'blr_contact_last_contacted', true),
            'total_sent'            => (string) get_post_meta($id, 'blr_contact_total_emails_sent', true),
            'last_reply'            => (string) get_post_meta($id, 'blr_contact_last_reply', true),
            'outreach_status'       => (string) get_post_meta($id, 'blr_contact_outreach_status', true),
            'type_label'            => $type !== '' ? Contacts::type_label($type) : '—',
            'newsletter_label'      => NewsletterDoubleOptIn::status_label($newsletter_status),
        ];
    }

    public static function contact_meta_value(int $post_id, string $key, bool $failed_post, array $posted_values) {
        if ($failed_post && array_key_exists($key, $posted_values)) {
            return $posted_values[$key];
        }

        return $post_id ? (string) get_post_meta($post_id, $key, true) : '';
    }

    private static function handle_post_delete(array $ctx, string $post_type, string $section): string {
        $id = (int) ($ctx['id'] ?? 0);
        $redirect_to = rtrim((string) ($ctx['base_url'] ?? Router::base_url()), '/') . '/' . $section . '/?deleted=1';

        if ($id <= 0) {
            CrudHelpers::redirect(add_query_arg(['delete_error' => 'missing_id'], $redirect_to));
            return '';
        }

        if (Request::method() !== 'POST') {
            CrudHelpers::redirect(add_query_arg(['delete_error' => 'invalid_method'], $redirect_to));
            return '';
        }

        $nonce_action = 'blr_ba_delete_' . $post_type . '_' . $id;
        $nonce = isset($_POST['_wpnonce']) ? sanitize_text_field((string) wp_unslash($_POST['_wpnonce'])) : '';
        if ($nonce === '' || !wp_verify_nonce($nonce, $nonce_action)) {
            CrudHelpers::redirect(add_query_arg(['delete_error' => 'invalid_nonce'], $redirect_to));
            return '';
        }

        $post = get_post($id);
        if (!$post instanceof \WP_Post || $post->post_type !== $post_type) {
            return Views::render('pages/404', $ctx);
        }

        if (!Access::can_delete_post($id, $post_type)) {
            CrudHelpers::redirect(add_query_arg(['delete_error' => 'forbidden'], $redirect_to));
            return '';
        }

        if (!wp_delete_post($id, true)) {
            CrudHelpers::redirect(add_query_arg(['delete_error' => 'delete_failed'], $redirect_to));
            return '';
        }

        CrudHelpers::redirect($redirect_to);
        return '';
    }
}
