<?php
if (!defined('ABSPATH')) {
    exit;
}

class Novajyin_Admin
{
    private $menu_slug = 'novajyin_inquiries';

    public function hooks()
    {
        add_action('admin_menu', array($this, 'admin_menu'));
        add_action('admin_enqueue_scripts', array($this, 'enqueue_assets'));

        add_action('admin_post_novajyin_update_inquiry', array($this, 'handle_update_inquiry'));
        add_action('admin_post_novajyin_bulk_action', array($this, 'handle_bulk_action'));
        add_action('admin_post_novajyin_save_group', array($this, 'handle_save_group'));
        add_action('admin_post_novajyin_delete_group', array($this, 'handle_delete_group'));
        add_action('admin_post_novajyin_save_status', array($this, 'handle_save_status'));
        add_action('admin_post_novajyin_delete_status', array($this, 'handle_delete_status'));
        add_action('admin_post_novajyin_save_priority', array($this, 'handle_save_priority'));
        add_action('admin_post_novajyin_delete_priority', array($this, 'handle_delete_priority'));
        add_action('admin_post_novajyin_save_rule', array($this, 'handle_save_rule'));
        add_action('admin_post_novajyin_delete_rule', array($this, 'handle_delete_rule'));
        add_action('admin_post_novajyin_save_settings', array($this, 'handle_save_settings'));
        add_action('admin_post_novajyin_save_notifications', array($this, 'handle_save_notifications'));
        add_action('admin_post_novajyin_export_csv', array($this, 'handle_export_csv'));
        add_action('admin_post_novajyin_download_attachment', array($this, 'handle_download_attachment'));
    }

    public function admin_menu()
    {
        add_menu_page(
            'Nova Jyo 問い合わせ管理 for Contact Form 7',
            '問い合わせ管理',
            'novajyin_access',
            $this->menu_slug,
            array($this, 'render_inquiries_page'),
            'dashicons-email-alt2',
            26
        );

        add_submenu_page($this->menu_slug, '問い合わせ一覧', '問い合わせ一覧', 'novajyin_access', $this->menu_slug, array($this, 'render_inquiries_page'));
        add_submenu_page($this->menu_slug, '担当グループ設定', '担当グループ設定', 'novajyin_manage_groups', 'novajyin_groups', array($this, 'render_groups_page'));
        add_submenu_page($this->menu_slug, 'ステータス設定', 'ステータス設定', 'novajyin_manage_settings', 'novajyin_statuses', array($this, 'render_statuses_page'));
        add_submenu_page($this->menu_slug, '自動振り分け設定', '自動振り分け設定', 'novajyin_manage_settings', 'novajyin_rules', array($this, 'render_rules_page'));
        add_submenu_page($this->menu_slug, '通知設定', '通知設定', 'novajyin_manage_settings', 'novajyin_notifications', array($this, 'render_notifications_page'));
        add_submenu_page($this->menu_slug, 'CSV出力', 'CSV出力', 'novajyin_export_inquiries', 'novajyin_csv', array($this, 'render_csv_page'));
        add_submenu_page($this->menu_slug, '基本設定', '基本設定', 'novajyin_manage_settings', 'novajyin_settings', array($this, 'render_settings_page'));
    }

    public function enqueue_assets($hook)
    {
        if (strpos((string) $hook, 'novajyin') === false) {
            return;
        }

        wp_enqueue_style('novajyin-admin', NOVAJYIN_PLUGIN_URL . 'assets/admin.css', array(), NOVAJYIN_VERSION);
    }

    public function render_inquiries_page()
    {
        $action = $this->query_key('action');
        $id = $this->query_absint('id');

        if ($action === 'view' && $id > 0) {
            $this->render_inquiry_detail($id);
            return;
        }

        $this->render_inquiry_list();
    }

    private function get_filter_args($source)
    {
        $source = is_array($source) ? wp_unslash($source) : array();

        return array(
            'paged' => isset($source['paged']) ? max(1, absint($source['paged'])) : 1,
            'search' => isset($source['s']) ? sanitize_text_field($source['s']) : '',
            'form_id' => isset($source['form_id']) ? sanitize_text_field($source['form_id']) : '',
            'status_id' => isset($source['status_id']) ? sanitize_text_field($source['status_id']) : '',
            'assignee_user_id' => isset($source['assignee_user_id']) ? sanitize_text_field($source['assignee_user_id']) : '',
            'assignee_group_id' => isset($source['assignee_group_id']) ? sanitize_text_field($source['assignee_group_id']) : '',
            'priority_id' => isset($source['priority_id']) ? sanitize_text_field($source['priority_id']) : '',
            'shop_name' => isset($source['shop_name']) ? sanitize_text_field($source['shop_name']) : '',
            'inquiry_type' => isset($source['inquiry_type']) ? sanitize_text_field($source['inquiry_type']) : '',
            'due_filter' => isset($source['due_filter']) ? sanitize_key($source['due_filter']) : '',
            'unhandled_only' => !empty($source['unhandled_only']) ? 1 : '',
            'date_from' => isset($source['date_from']) ? sanitize_text_field($source['date_from']) : '',
            'date_to' => isset($source['date_to']) ? sanitize_text_field($source['date_to']) : '',
            'current_user_id' => get_current_user_id(),
        );
    }

    private function render_notice()
    {
        if ($this->query_key('novajyin_message') === '') {
            return;
        }

        $messages = array(
            'saved' => '保存しました。',
            'deleted' => '削除しました。',
            'updated' => '更新しました。',
            'denied' => '権限がありません。',
        );
        $key = $this->query_key('novajyin_message');
        $message = $messages[$key] ?? '';
        if ($message === '') {
            return;
        }

        printf('<div class="notice notice-success is-dismissible"><p>%s</p></div>', esc_html($message));
    }

    private function render_inquiry_list()
    {
        $filters = $this->get_filter_args($_GET);
        $filters['per_page'] = 20;
        $inquiries = Novajyin_Repository::query_inquiries($filters);
        $total = Novajyin_Repository::count_inquiries($filters);
        $total_pages = max(1, (int) ceil($total / $filters['per_page']));

        $statuses = Novajyin_Repository::get_statuses();
        $priorities = Novajyin_Repository::get_priorities();
        $groups = Novajyin_Repository::get_groups();
        $users = get_users(array('fields' => array('ID', 'display_name')));
        $forms = Novajyin_Repository::get_contact_forms();

        echo '<div class="wrap novajyin-wrap">';
        echo '<h1 class="wp-heading-inline">問い合わせ一覧</h1>';
        $this->render_notice();
        $this->render_filters($filters, $forms, $statuses, $priorities, $groups, $users, 'novajyin_inquiries');

        echo '<form method="post" action="' . esc_url(admin_url('admin-post.php')) . '">';
        wp_nonce_field('novajyin_bulk_action');
        echo '<input type="hidden" name="action" value="novajyin_bulk_action">';
        $this->render_bulk_controls($statuses, $priorities, $groups, $users);

        echo '<table class="widefat fixed striped novajyin-table">';
        echo '<thead><tr>';
        echo '<td class="manage-column column-cb check-column"><input type="checkbox" onclick="jQuery(\'.novajyin-row-check\').prop(\'checked\', this.checked);"></td>';
        $columns = array('ID', '受付日時', 'フォーム名', '氏名', 'メールアドレス', '電話番号', '問い合わせ種別', '店舗名', 'ステータス', '担当者', '担当グループ', '優先度', '対応期限', '最終更新日時');
        foreach ($columns as $column) {
            echo '<th>' . esc_html($column) . '</th>';
        }
        echo '</tr></thead><tbody>';

        if (empty($inquiries)) {
            echo '<tr><td colspan="15">問い合わせはありません。</td></tr>';
        } else {
            foreach ($inquiries as $inquiry) {
                $detail_url = admin_url('admin.php?page=novajyin_inquiries&action=view&id=' . absint($inquiry->id));
                $overdue = $this->is_overdue($inquiry) ? ' novajyin-overdue' : '';
                echo '<tr class="' . esc_attr($overdue) . '">';
                echo '<th scope="row" class="check-column"><input class="novajyin-row-check" type="checkbox" name="ids[]" value="' . esc_attr($inquiry->id) . '"></th>';
                echo '<td><a href="' . esc_url($detail_url) . '">#' . esc_html($inquiry->id) . '</a></td>';
                echo '<td>' . esc_html(mysql2date('Y/m/d H:i', $inquiry->submitted_at)) . '</td>';
                echo '<td>' . esc_html($inquiry->form_name) . '</td>';
                echo '<td>' . esc_html($inquiry->name) . '</td>';
                echo '<td>' . esc_html($inquiry->email) . '</td>';
                echo '<td>' . esc_html($inquiry->tel) . '</td>';
                echo '<td>' . esc_html($inquiry->inquiry_type) . '</td>';
                echo '<td>' . esc_html($inquiry->shop_name) . '</td>';
                echo '<td>' . esc_html($inquiry->status_name) . '</td>';
                echo '<td>' . esc_html($inquiry->assignee_name) . '</td>';
                echo '<td>' . esc_html($inquiry->group_name) . '</td>';
                echo '<td>' . esc_html($inquiry->priority_name) . '</td>';
                echo '<td>' . esc_html($inquiry->due_date ? mysql2date('Y/m/d H:i', $inquiry->due_date) : '未設定') . '</td>';
                echo '<td>' . esc_html(mysql2date('Y/m/d H:i', $inquiry->updated_at)) . '</td>';
                echo '</tr>';
            }
        }

        echo '</tbody></table>';
        echo '</form>';

        $this->render_pagination($filters, $total_pages);
        echo '</div>';
    }

    private function render_filters($filters, $forms, $statuses, $priorities, $groups, $users, $page)
    {
        echo '<form method="get" class="novajyin-filters">';
        echo '<input type="hidden" name="page" value="' . esc_attr($page) . '">';
        echo '<input type="search" name="s" placeholder="検索" value="' . esc_attr($filters['search']) . '">';
        $this->select('form_id', $filters['form_id'], array('' => 'フォーム') + $forms);
        $this->object_select('status_id', $filters['status_id'], $statuses, 'id', 'status_name', 'ステータス');
        $this->user_select('assignee_user_id', $filters['assignee_user_id'], $users, '担当者');
        $this->object_select('assignee_group_id', $filters['assignee_group_id'], $groups, 'id', 'group_name', '担当グループ');
        $this->object_select('priority_id', $filters['priority_id'], $priorities, 'id', 'priority_name', '優先度');
        echo '<input type="text" name="shop_name" placeholder="店舗名" value="' . esc_attr($filters['shop_name']) . '">';
        echo '<input type="text" name="inquiry_type" placeholder="問い合わせ種別" value="' . esc_attr($filters['inquiry_type']) . '">';
        $this->select('due_filter', $filters['due_filter'], array('' => '期限', 'overdue' => '期限切れ', 'today' => '本日期限', 'none' => '期限未設定'));
        echo '<label class="novajyin-checkbox"><input type="checkbox" name="unhandled_only" value="1" ' . checked($filters['unhandled_only'], 1, false) . '>未対応のみ</label>';
        echo '<input type="date" name="date_from" value="' . esc_attr($filters['date_from']) . '">';
        echo '<input type="date" name="date_to" value="' . esc_attr($filters['date_to']) . '">';
        submit_button('絞り込み', 'secondary', '', false);
        echo '</form>';
    }

    private function render_bulk_controls($statuses, $priorities, $groups, $users)
    {
        echo '<div class="tablenav top"><div class="alignleft actions bulkactions">';
        $actions = array('' => '一括操作', 'status' => 'ステータス変更', 'assignee' => '担当者変更', 'group' => '担当グループ変更', 'priority' => '優先度変更');
        if (Novajyin_Plugin::can_export()) {
            $actions['csv'] = 'CSV出力';
        }
        if (Novajyin_Plugin::can_delete()) {
            $actions['delete'] = '削除';
        }
        $this->select('bulk_action', '', $actions);
        $this->object_select('bulk_status_id', '', $statuses, 'id', 'status_name', 'ステータス');
        $this->user_select('bulk_assignee_user_id', '', $users, '担当者');
        $this->object_select('bulk_assignee_group_id', '', $groups, 'id', 'group_name', '担当グループ');
        $this->object_select('bulk_priority_id', '', $priorities, 'id', 'priority_name', '優先度');
        submit_button('適用', 'secondary action', '', false);
        echo '</div></div>';
    }

    private function render_pagination($filters, $total_pages)
    {
        if ($total_pages <= 1) {
            return;
        }

        echo '<div class="tablenav"><div class="tablenav-pages">';
        for ($i = 1; $i <= $total_pages; $i++) {
            $url = add_query_arg(array_merge($this->current_query_args(), array('paged' => $i)));
            $class = (int) $filters['paged'] === $i ? ' class="page-numbers current"' : ' class="page-numbers"';
            echo '<a' . $class . ' href="' . esc_url($url) . '">' . esc_html($i) . '</a> ';
        }
        echo '</div></div>';
    }

    private function render_inquiry_detail($id)
    {
        $inquiry = Novajyin_Repository::get_inquiry($id);
        if (!Novajyin_Plugin::can_view_inquiry($inquiry)) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        $can_edit = Novajyin_Plugin::can_edit_inquiry($inquiry);
        $statuses = Novajyin_Repository::get_statuses();
        $priorities = Novajyin_Repository::get_priorities();
        $groups = Novajyin_Repository::get_groups();
        $users = get_users(array('fields' => array('ID', 'display_name')));
        $raw_data = Novajyin_Repository::decode_json($inquiry->raw_data_json);
        $attachments = Novajyin_Repository::decode_json($inquiry->attachments_json);
        $histories = Novajyin_Repository::get_histories($id);
        $memos = Novajyin_Repository::get_memos($id);

        echo '<div class="wrap novajyin-wrap">';
        echo '<h1>問い合わせ詳細 #' . esc_html($inquiry->id) . '</h1>';
        $this->render_notice();
        echo '<p><a href="' . esc_url(admin_url('admin.php?page=novajyin_inquiries')) . '">&larr; 問い合わせ一覧へ戻る</a></p>';

        echo '<div class="novajyin-detail-grid">';
        echo '<div class="novajyin-panel">';
        echo '<h2>基本情報</h2>';
        echo '<table class="form-table"><tbody>';
        $this->detail_row('受付日時', mysql2date('Y/m/d H:i', $inquiry->submitted_at));
        $this->detail_row('フォーム名', $inquiry->form_name);
        $this->detail_row('氏名', $inquiry->name);
        $this->detail_row('メールアドレス', $inquiry->email);
        $this->detail_row('電話番号', $inquiry->tel);
        $this->detail_row('問い合わせ種別', $inquiry->inquiry_type);
        $this->detail_row('店舗名', $inquiry->shop_name);
        $this->detail_row('件名', $inquiry->subject);
        $this->detail_row('問い合わせ内容', nl2br(esc_html($inquiry->message)), true);
        echo '</tbody></table>';
        echo '</div>';

        echo '<div class="novajyin-panel">';
        echo '<h2>管理情報</h2>';
        if ($can_edit) {
            echo '<form method="post" action="' . esc_url(admin_url('admin-post.php')) . '">';
            wp_nonce_field('novajyin_update_inquiry_' . $inquiry->id);
            echo '<input type="hidden" name="action" value="novajyin_update_inquiry">';
            echo '<input type="hidden" name="id" value="' . esc_attr($inquiry->id) . '">';
        }
        echo '<table class="form-table"><tbody>';
        echo '<tr><th><label for="status_id">ステータス</label></th><td>';
        $this->object_select('status_id', $inquiry->status_id, $statuses, 'id', 'status_name', '未設定', !$can_edit);
        echo '</td></tr>';
        echo '<tr><th><label for="assignee_user_id">担当者</label></th><td>';
        $this->user_select('assignee_user_id', $inquiry->assignee_user_id, $users, '未設定', !$can_edit);
        echo '</td></tr>';
        echo '<tr><th><label for="assignee_group_id">担当グループ</label></th><td>';
        $this->object_select('assignee_group_id', $inquiry->assignee_group_id, $groups, 'id', 'group_name', '未設定', !$can_edit);
        echo '</td></tr>';
        echo '<tr><th><label for="priority_id">優先度</label></th><td>';
        $this->object_select('priority_id', $inquiry->priority_id, $priorities, 'id', 'priority_name', '未設定', !$can_edit);
        echo '</td></tr>';
        echo '<tr><th><label for="due_date">対応期限</label></th><td><input type="datetime-local" name="due_date" id="due_date" value="' . esc_attr($this->datetime_local_value($inquiry->due_date)) . '"' . disabled(!$can_edit, true, false) . '></td></tr>';
        if ($can_edit) {
            echo '<tr><th><label for="memo_content">社内メモ追加</label></th><td><textarea name="memo_content" id="memo_content" rows="4" class="large-text"></textarea></td></tr>';
            echo '<tr><th><label for="history_content">対応履歴追加</label></th><td><textarea name="history_content" id="history_content" rows="4" class="large-text"></textarea></td></tr>';
        }
        echo '</tbody></table>';
        if ($can_edit) {
            submit_button('更新');
            echo '</form>';
        }
        echo '</div>';
        echo '</div>';

        echo '<div class="novajyin-detail-grid">';
        $this->render_raw_data_panel($raw_data);
        $this->render_attachments_panel($inquiry, $attachments);
        echo '</div>';

        echo '<div class="novajyin-detail-grid">';
        $this->render_memos_panel($memos);
        $this->render_histories_panel($histories);
        echo '</div>';
        echo '</div>';
    }

    private function render_raw_data_panel($raw_data)
    {
        echo '<div class="novajyin-panel"><h2>送信内容</h2>';
        echo '<table class="widefat striped"><tbody>';
        foreach ($raw_data as $key => $value) {
            if (is_array($value)) {
                $value = implode(', ', array_map('strval', $value));
            }
            echo '<tr><th>' . esc_html($key) . '</th><td>' . nl2br(esc_html((string) $value)) . '</td></tr>';
        }
        if (empty($raw_data)) {
            echo '<tr><td>送信内容はありません。</td></tr>';
        }
        echo '</tbody></table></div>';
    }

    private function render_attachments_panel($inquiry, $attachments)
    {
        echo '<div class="novajyin-panel"><h2>添付ファイル</h2>';
        if (empty($attachments)) {
            echo '<p>添付ファイルはありません。</p>';
            echo '</div>';
            return;
        }

        echo '<ul class="novajyin-attachments">';
        foreach ($attachments as $index => $attachment) {
            $name = $attachment['name'] ?? '';
            if (!empty($attachment['saved'])) {
                $download_url = wp_nonce_url(
                    admin_url('admin-post.php?action=novajyin_download_attachment&id=' . absint($inquiry->id) . '&index=' . absint($index)),
                    'novajyin_download_attachment_' . $inquiry->id
                );
                echo '<li><a href="' . esc_url($download_url) . '">' . esc_html($name) . '</a></li>';
            } else {
                echo '<li>' . esc_html($name) . '</li>';
            }
        }
        echo '</ul></div>';
    }

    private function render_memos_panel($memos)
    {
        echo '<div class="novajyin-panel"><h2>社内メモ</h2>';
        if (empty($memos)) {
            echo '<p>社内メモはありません。</p></div>';
            return;
        }

        foreach ($memos as $memo) {
            echo '<div class="novajyin-timeline-item">';
            echo '<strong>' . esc_html(mysql2date('Y/m/d H:i', $memo->created_at)) . ' ' . esc_html($memo->display_name ?: 'システム') . '</strong>';
            echo '<div>' . wp_kses_post(wpautop($memo->memo_content)) . '</div>';
            echo '</div>';
        }
        echo '</div>';
    }

    private function render_histories_panel($histories)
    {
        echo '<div class="novajyin-panel"><h2>対応履歴</h2>';
        if (empty($histories)) {
            echo '<p>対応履歴はありません。</p></div>';
            return;
        }

        foreach ($histories as $history) {
            echo '<div class="novajyin-timeline-item">';
            echo '<strong>' . esc_html(mysql2date('Y/m/d H:i', $history->created_at)) . ' ' . esc_html($history->display_name ?: 'システム') . '</strong>';
            echo '<span class="novajyin-type">' . esc_html($history->history_type) . '</span>';
            echo '<div>' . wp_kses_post(wpautop($history->content)) . '</div>';
            echo '</div>';
        }
        echo '</div>';
    }

    public function render_groups_page()
    {
        if (!Novajyin_Plugin::can_manage_groups()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        $edit_id = $this->query_absint('edit');
        $group = $edit_id ? Novajyin_Repository::get_group($edit_id) : null;
        $group_user_ids = $group ? Novajyin_Repository::get_group_user_ids($group->id) : array();
        $groups = Novajyin_Repository::get_groups();
        $users = get_users(array('fields' => array('ID', 'display_name')));

        echo '<div class="wrap novajyin-wrap"><h1>担当グループ設定</h1>';
        $this->render_notice();
        echo '<div class="novajyin-detail-grid"><div class="novajyin-panel">';
        echo '<h2>' . esc_html($group ? '担当グループ編集' : '担当グループ追加') . '</h2>';
        echo '<form method="post" action="' . esc_url(admin_url('admin-post.php')) . '">';
        wp_nonce_field('novajyin_save_group');
        echo '<input type="hidden" name="action" value="novajyin_save_group">';
        echo '<input type="hidden" name="id" value="' . esc_attr($group->id ?? 0) . '">';
        echo '<table class="form-table"><tbody>';
        echo '<tr><th>グループ名</th><td><input type="text" name="group_name" class="regular-text" required value="' . esc_attr($group->group_name ?? '') . '"></td></tr>';
        echo '<tr><th>説明</th><td><textarea name="description" rows="3" class="large-text">' . esc_textarea($group->description ?? '') . '</textarea></td></tr>';
        echo '<tr><th>所属ユーザー</th><td><select name="user_ids[]" multiple size="8">';
        foreach ($users as $user) {
            echo '<option value="' . esc_attr($user->ID) . '" ' . selected(in_array((int) $user->ID, $group_user_ids, true), true, false) . '>' . esc_html($user->display_name) . '</option>';
        }
        echo '</select></td></tr>';
        echo '<tr><th>通知先メールアドレス</th><td><input type="email" name="notification_email" class="regular-text" value="' . esc_attr($group->notification_email ?? '') . '"></td></tr>';
        echo '<tr><th>表示順</th><td><input type="number" name="sort_order" value="' . esc_attr($group->sort_order ?? 0) . '"></td></tr>';
        echo '<tr><th>有効</th><td><label><input type="checkbox" name="is_active" value="1" ' . checked((int) ($group->is_active ?? 1), 1, false) . '> 有効</label></td></tr>';
        echo '</tbody></table>';
        submit_button('保存');
        echo '</form></div>';

        echo '<div class="novajyin-panel"><h2>担当グループ一覧</h2>';
        echo '<table class="widefat striped"><thead><tr><th>ID</th><th>グループ名</th><th>通知先</th><th>表示順</th><th>状態</th><th>操作</th></tr></thead><tbody>';
        foreach ($groups as $row) {
            $edit_url = admin_url('admin.php?page=novajyin_groups&edit=' . absint($row->id));
            $delete_url = wp_nonce_url(admin_url('admin-post.php?action=novajyin_delete_group&id=' . absint($row->id)), 'novajyin_delete_group_' . $row->id);
            echo '<tr><td>' . esc_html($row->id) . '</td><td>' . esc_html($row->group_name) . '</td><td>' . esc_html($row->notification_email) . '</td><td>' . esc_html($row->sort_order) . '</td><td>' . esc_html($row->is_active ? '有効' : '無効') . '</td><td><a href="' . esc_url($edit_url) . '">編集</a> | <a href="' . esc_url($delete_url) . '">削除</a></td></tr>';
        }
        if (empty($groups)) {
            echo '<tr><td colspan="6">担当グループはありません。</td></tr>';
        }
        echo '</tbody></table></div></div></div>';
    }

    public function render_statuses_page()
    {
        if (!Novajyin_Plugin::can_manage_settings()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        $edit_status = $this->query_absint('edit_status') ? Novajyin_Repository::get_status($this->query_absint('edit_status')) : null;
        $edit_priority = $this->query_absint('edit_priority') ? Novajyin_Repository::get_priority($this->query_absint('edit_priority')) : null;
        $statuses = Novajyin_Repository::get_statuses();
        $priorities = Novajyin_Repository::get_priorities();

        echo '<div class="wrap novajyin-wrap"><h1>ステータス・優先度設定</h1>';
        $this->render_notice();
        echo '<div class="novajyin-detail-grid">';
        $this->render_status_form($edit_status, $statuses);
        $this->render_priority_form($edit_priority, $priorities);
        echo '</div></div>';
    }

    private function render_status_form($edit_status, $statuses)
    {
        echo '<div class="novajyin-panel"><h2>ステータス</h2>';
        echo '<form method="post" action="' . esc_url(admin_url('admin-post.php')) . '">';
        wp_nonce_field('novajyin_save_status');
        echo '<input type="hidden" name="action" value="novajyin_save_status">';
        echo '<input type="hidden" name="id" value="' . esc_attr($edit_status->id ?? 0) . '">';
        echo '<p><input type="text" name="status_name" required placeholder="ステータス名" value="' . esc_attr($edit_status->status_name ?? '') . '"> ';
        echo '<input type="number" name="sort_order" placeholder="表示順" value="' . esc_attr($edit_status->sort_order ?? 0) . '"> ';
        echo '<label><input type="checkbox" name="is_default" value="1" ' . checked((int) ($edit_status->is_default ?? 0), 1, false) . '> 初期</label> ';
        echo '<label><input type="checkbox" name="is_closed" value="1" ' . checked((int) ($edit_status->is_closed ?? 0), 1, false) . '> 完了扱い</label> ';
        submit_button('保存', 'secondary', '', false);
        echo '</p></form>';
        echo '<table class="widefat striped"><thead><tr><th>ID</th><th>名称</th><th>表示順</th><th>初期</th><th>完了扱い</th><th>操作</th></tr></thead><tbody>';
        foreach ($statuses as $status) {
            $edit_url = admin_url('admin.php?page=novajyin_statuses&edit_status=' . absint($status->id));
            $delete_url = wp_nonce_url(admin_url('admin-post.php?action=novajyin_delete_status&id=' . absint($status->id)), 'novajyin_delete_status_' . $status->id);
            echo '<tr><td>' . esc_html($status->id) . '</td><td>' . esc_html($status->status_name) . '</td><td>' . esc_html($status->sort_order) . '</td><td>' . esc_html($status->is_default ? '○' : '') . '</td><td>' . esc_html($status->is_closed ? '○' : '') . '</td><td><a href="' . esc_url($edit_url) . '">編集</a> | <a href="' . esc_url($delete_url) . '">削除</a></td></tr>';
        }
        echo '</tbody></table></div>';
    }

    private function render_priority_form($edit_priority, $priorities)
    {
        echo '<div class="novajyin-panel"><h2>優先度</h2>';
        echo '<form method="post" action="' . esc_url(admin_url('admin-post.php')) . '">';
        wp_nonce_field('novajyin_save_priority');
        echo '<input type="hidden" name="action" value="novajyin_save_priority">';
        echo '<input type="hidden" name="id" value="' . esc_attr($edit_priority->id ?? 0) . '">';
        echo '<p><input type="text" name="priority_name" required placeholder="優先度名" value="' . esc_attr($edit_priority->priority_name ?? '') . '"> ';
        echo '<input type="number" name="sort_order" placeholder="表示順" value="' . esc_attr($edit_priority->sort_order ?? 0) . '"> ';
        submit_button('保存', 'secondary', '', false);
        echo '</p></form>';
        echo '<table class="widefat striped"><thead><tr><th>ID</th><th>名称</th><th>表示順</th><th>操作</th></tr></thead><tbody>';
        foreach ($priorities as $priority) {
            $edit_url = admin_url('admin.php?page=novajyin_statuses&edit_priority=' . absint($priority->id));
            $delete_url = wp_nonce_url(admin_url('admin-post.php?action=novajyin_delete_priority&id=' . absint($priority->id)), 'novajyin_delete_priority_' . $priority->id);
            echo '<tr><td>' . esc_html($priority->id) . '</td><td>' . esc_html($priority->priority_name) . '</td><td>' . esc_html($priority->sort_order) . '</td><td><a href="' . esc_url($edit_url) . '">編集</a> | <a href="' . esc_url($delete_url) . '">削除</a></td></tr>';
        }
        echo '</tbody></table></div>';
    }

    public function render_rules_page()
    {
        if (!Novajyin_Plugin::can_manage_settings()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        $edit_id = $this->query_absint('edit');
        $rule = $edit_id ? Novajyin_Repository::get_rule($edit_id) : null;
        $conditions = $rule ? Novajyin_Repository::decode_json($rule->conditions_json) : array();
        $actions = $rule ? Novajyin_Repository::decode_json($rule->actions_json) : array();
        $condition = $conditions[0] ?? array();
        $statuses = Novajyin_Repository::get_statuses();
        $priorities = Novajyin_Repository::get_priorities();
        $groups = Novajyin_Repository::get_groups(true);
        $users = get_users(array('fields' => array('ID', 'display_name')));
        $rules = Novajyin_Repository::get_rules();

        echo '<div class="wrap novajyin-wrap"><h1>自動振り分け設定</h1>';
        $this->render_notice();
        echo '<div class="novajyin-detail-grid"><div class="novajyin-panel">';
        echo '<h2>' . esc_html($rule ? 'ルール編集' : 'ルール追加') . '</h2>';
        echo '<form method="post" action="' . esc_url(admin_url('admin-post.php')) . '">';
        wp_nonce_field('novajyin_save_rule');
        echo '<input type="hidden" name="action" value="novajyin_save_rule">';
        echo '<input type="hidden" name="id" value="' . esc_attr($rule->id ?? 0) . '">';
        echo '<table class="form-table"><tbody>';
        echo '<tr><th>ルール名</th><td><input type="text" name="rule_name" required class="regular-text" value="' . esc_attr($rule->rule_name ?? '') . '"></td></tr>';
        echo '<tr><th>条件フィールド</th><td>';
        $this->select('condition_field', $condition['field'] ?? '', $this->condition_field_options());
        echo '<input type="text" name="condition_custom_field" placeholder="任意のContact Form 7フィールド名" value="' . esc_attr($condition['field'] ?? '') . '">';
        echo '</td></tr>';
        echo '<tr><th>条件方式</th><td>';
        $this->select('condition_operator', $condition['operator'] ?? 'equals', Novajyin_Rules_Engine::operator_options());
        echo '</td></tr>';
        echo '<tr><th>条件値</th><td><input type="text" name="condition_value" class="regular-text" value="' . esc_attr($condition['value'] ?? '') . '"></td></tr>';
        echo '<tr><th>担当者を設定</th><td>';
        $this->user_select('assignee_user_id', $actions['assignee_user_id'] ?? '', $users, '変更しない');
        echo '</td></tr>';
        echo '<tr><th>担当グループを設定</th><td>';
        $this->object_select('assignee_group_id', $actions['assignee_group_id'] ?? '', $groups, 'id', 'group_name', '変更しない');
        echo '</td></tr>';
        echo '<tr><th>ステータスを設定</th><td>';
        $this->object_select('status_id', $actions['status_id'] ?? '', $statuses, 'id', 'status_name', '変更しない');
        echo '</td></tr>';
        echo '<tr><th>優先度を設定</th><td>';
        $this->object_select('priority_id', $actions['priority_id'] ?? '', $priorities, 'id', 'priority_name', '変更しない');
        echo '</td></tr>';
        echo '<tr><th>対応期限を設定</th><td>';
        $this->select('due_type', $actions['due_type'] ?? 'none', array('none' => '変更しない', 'end_of_day' => '当日中', 'hours' => '時間後', 'days' => '日後', 'business_days' => '営業日後'));
        echo '<input type="number" min="1" name="due_value" value="' . esc_attr($actions['due_value'] ?? 1) . '"></td></tr>';
        echo '<tr><th>通知先を設定</th><td><input type="text" name="notify_emails" class="large-text" value="' . esc_attr($actions['notify_emails'] ?? '') . '"></td></tr>';
        echo '<tr><th>表示順</th><td><input type="number" name="sort_order" value="' . esc_attr($rule->sort_order ?? 0) . '"></td></tr>';
        echo '<tr><th>有効</th><td><label><input type="checkbox" name="is_active" value="1" ' . checked((int) ($rule->is_active ?? 1), 1, false) . '> 有効</label></td></tr>';
        echo '</tbody></table>';
        submit_button('保存');
        echo '</form></div>';

        echo '<div class="novajyin-panel"><h2>ルール一覧</h2>';
        echo '<table class="widefat striped"><thead><tr><th>ID</th><th>ルール名</th><th>表示順</th><th>状態</th><th>操作</th></tr></thead><tbody>';
        foreach ($rules as $row) {
            $edit_url = admin_url('admin.php?page=novajyin_rules&edit=' . absint($row->id));
            $delete_url = wp_nonce_url(admin_url('admin-post.php?action=novajyin_delete_rule&id=' . absint($row->id)), 'novajyin_delete_rule_' . $row->id);
            echo '<tr><td>' . esc_html($row->id) . '</td><td>' . esc_html($row->rule_name) . '</td><td>' . esc_html($row->sort_order) . '</td><td>' . esc_html($row->is_active ? '有効' : '無効') . '</td><td><a href="' . esc_url($edit_url) . '">編集</a> | <a href="' . esc_url($delete_url) . '">削除</a></td></tr>';
        }
        if (empty($rules)) {
            echo '<tr><td colspan="5">ルールはありません。</td></tr>';
        }
        echo '</tbody></table></div></div></div>';
    }

    public function render_notifications_page()
    {
        if (!Novajyin_Plugin::can_manage_settings()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        $settings = Novajyin_Repository::get_settings();
        echo '<div class="wrap novajyin-wrap"><h1>通知設定</h1>';
        $this->render_notice();
        echo '<form method="post" action="' . esc_url(admin_url('admin-post.php')) . '" class="novajyin-panel">';
        wp_nonce_field('novajyin_save_notifications');
        echo '<input type="hidden" name="action" value="novajyin_save_notifications">';
        echo '<table class="form-table"><tbody>';
        echo '<tr><th>新規問い合わせ通知</th><td><label><input type="checkbox" name="notify_on_new" value="1" ' . checked($settings['notify_on_new'], 1, false) . '> 有効</label></td></tr>';
        echo '<tr><th>管理者メール</th><td><label><input type="checkbox" name="notify_admin" value="1" ' . checked($settings['notify_admin'], 1, false) . '> 送信する</label></td></tr>';
        echo '<tr><th>担当者メール</th><td><label><input type="checkbox" name="notify_assignee" value="1" ' . checked($settings['notify_assignee'], 1, false) . '> 送信する</label></td></tr>';
        echo '<tr><th>担当グループ通知先メール</th><td><label><input type="checkbox" name="notify_group" value="1" ' . checked($settings['notify_group'], 1, false) . '> 送信する</label></td></tr>';
        echo '<tr><th>任意メールアドレス</th><td><textarea name="notify_emails" rows="4" class="large-text">' . esc_textarea($settings['notify_emails']) . '</textarea></td></tr>';
        echo '</tbody></table>';
        submit_button('保存');
        echo '</form></div>';
    }

    public function render_settings_page()
    {
        if (!Novajyin_Plugin::can_manage_settings()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        $settings = Novajyin_Repository::get_settings();
        $forms = Novajyin_Repository::get_contact_forms();
        $mapping_fields = $this->mapping_fields();

        echo '<div class="wrap novajyin-wrap"><h1>基本設定</h1>';
        $this->render_notice();
        echo '<form method="post" action="' . esc_url(admin_url('admin-post.php')) . '" class="novajyin-panel">';
        wp_nonce_field('novajyin_save_settings');
        echo '<input type="hidden" name="action" value="novajyin_save_settings">';
        echo '<table class="form-table"><tbody>';
        echo '<tr><th>管理対象フォーム</th><td><select name="managed_forms[]" multiple size="8">';
        foreach ($forms as $form_id => $form_name) {
            echo '<option value="' . esc_attr($form_id) . '" ' . selected(in_array((int) $form_id, array_map('absint', (array) $settings['managed_forms']), true), true, false) . '>' . esc_html($form_name) . '</option>';
        }
        echo '</select><p class="description">未選択の場合はすべての Contact Form 7 フォームを保存します。</p></td></tr>';
        echo '<tr><th>保存期間</th><td><input type="number" min="0" name="retention_days" value="' . esc_attr($settings['retention_days']) . '"> 日 <p class="description">0 の場合は自動削除しません。</p></td></tr>';
        echo '<tr><th>添付ファイル保存</th><td><label><input type="checkbox" name="save_attachments" value="1" ' . checked($settings['save_attachments'], 1, false) . '> 保存する</label></td></tr>';
        echo '<tr><th>削除時データ保持</th><td><label><input type="checkbox" name="keep_data_on_delete" value="1" ' . checked($settings['keep_data_on_delete'], 1, false) . '> プラグイン削除時もデータを保持する</label></td></tr>';
        echo '</tbody></table>';

        echo '<h2>フィールドマッピング</h2>';
        $this->render_mapping_table('default', '共通マッピング', $settings, $mapping_fields);
        foreach ($forms as $form_id => $form_name) {
            $this->render_mapping_table($form_id, $form_name, $settings, $mapping_fields);
        }

        submit_button('保存');
        echo '</form></div>';
    }

    private function render_mapping_table($form_key, $title, $settings, $mapping_fields)
    {
        $mapping = $settings['field_mapping'][$form_key] ?? array();
        echo '<h3>' . esc_html($title) . '</h3>';
        echo '<table class="widefat striped novajyin-mapping"><thead><tr><th>標準項目</th><th>Contact Form 7フィールド名</th></tr></thead><tbody>';
        foreach ($mapping_fields as $key => $label) {
            echo '<tr><th>' . esc_html($label) . '</th><td><input type="text" name="field_mapping[' . esc_attr($form_key) . '][' . esc_attr($key) . ']" value="' . esc_attr($mapping[$key] ?? '') . '" placeholder="your-name"></td></tr>';
        }
        echo '</tbody></table>';
    }

    public function render_csv_page()
    {
        if (!Novajyin_Plugin::can_export()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        $filters = $this->get_filter_args(array());
        $statuses = Novajyin_Repository::get_statuses();
        $priorities = Novajyin_Repository::get_priorities();
        $groups = Novajyin_Repository::get_groups();
        $users = get_users(array('fields' => array('ID', 'display_name')));
        $forms = Novajyin_Repository::get_contact_forms();

        echo '<div class="wrap novajyin-wrap"><h1>CSV出力</h1>';
        echo '<form method="post" action="' . esc_url(admin_url('admin-post.php')) . '" class="novajyin-panel">';
        wp_nonce_field('novajyin_export_csv');
        echo '<input type="hidden" name="action" value="novajyin_export_csv">';
        $this->render_csv_filter_fields($filters, $forms, $statuses, $priorities, $groups, $users);
        submit_button('CSVダウンロード');
        echo '</form></div>';
    }

    private function render_csv_filter_fields($filters, $forms, $statuses, $priorities, $groups, $users)
    {
        echo '<div class="novajyin-filters">';
        echo '<input type="search" name="s" placeholder="検索" value="' . esc_attr($filters['search']) . '">';
        $this->select('form_id', $filters['form_id'], array('' => 'フォーム') + $forms);
        $this->object_select('status_id', $filters['status_id'], $statuses, 'id', 'status_name', 'ステータス');
        $this->user_select('assignee_user_id', $filters['assignee_user_id'], $users, '担当者');
        $this->object_select('assignee_group_id', $filters['assignee_group_id'], $groups, 'id', 'group_name', '担当グループ');
        $this->object_select('priority_id', $filters['priority_id'], $priorities, 'id', 'priority_name', '優先度');
        echo '<input type="text" name="shop_name" placeholder="店舗名" value="' . esc_attr($filters['shop_name']) . '">';
        echo '<input type="text" name="inquiry_type" placeholder="問い合わせ種別" value="' . esc_attr($filters['inquiry_type']) . '">';
        $this->select('due_filter', $filters['due_filter'], array('' => '期限', 'overdue' => '期限切れ', 'today' => '本日期限', 'none' => '期限未設定'));
        echo '<label class="novajyin-checkbox"><input type="checkbox" name="unhandled_only" value="1" ' . checked($filters['unhandled_only'], 1, false) . '>未対応のみ</label>';
        echo '<input type="date" name="date_from" value="' . esc_attr($filters['date_from']) . '">';
        echo '<input type="date" name="date_to" value="' . esc_attr($filters['date_to']) . '">';
        echo '</div>';
    }

    public function handle_update_inquiry()
    {
        $id = $this->posted_absint('id');
        check_admin_referer('novajyin_update_inquiry_' . $id);
        $inquiry = Novajyin_Repository::get_inquiry($id);
        if (!Novajyin_Plugin::can_edit_inquiry($inquiry)) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        $changes = array(
            'status_id' => $this->posted_nullable_int('status_id'),
            'assignee_user_id' => $this->posted_nullable_int('assignee_user_id'),
            'assignee_group_id' => $this->posted_nullable_int('assignee_group_id'),
            'priority_id' => $this->posted_nullable_int('priority_id'),
            'due_date' => $this->normalize_datetime($this->posted_text('due_date')),
        );

        Novajyin_Repository::update_inquiry($id, $changes, get_current_user_id(), true);

        $memo = wp_kses_post($this->posted_value('memo_content', ''));
        if (trim(wp_strip_all_tags($memo)) !== '') {
            Novajyin_Repository::add_memo($id, $memo, get_current_user_id());
        }

        $history = wp_kses_post($this->posted_value('history_content', ''));
        if (trim(wp_strip_all_tags($history)) !== '') {
            Novajyin_Repository::add_history($id, 'manual_note', $history, get_current_user_id());
        }

        $this->redirect(admin_url('admin.php?page=novajyin_inquiries&action=view&id=' . $id . '&novajyin_message=updated'));
    }

    public function handle_bulk_action()
    {
        check_admin_referer('novajyin_bulk_action');
        $bulk_action = sanitize_key((string) $this->posted_value('bulk_action', ''));
        $ids = $this->posted_absint_array('ids');
        if (empty($ids)) {
            $this->redirect(admin_url('admin.php?page=novajyin_inquiries&novajyin_message=updated'));
        }

        if ($bulk_action === 'csv') {
            if (!Novajyin_Plugin::can_export()) {
                wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
            }
            $this->export_csv_by_ids($ids);
        }

        if ($bulk_action === 'delete') {
            if (!Novajyin_Plugin::can_delete()) {
                wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
            }
            Novajyin_Repository::delete_inquiries($ids);
            $this->redirect(admin_url('admin.php?page=novajyin_inquiries&novajyin_message=deleted'));
        }

        $field_map = array(
            'status' => array('status_id', 'bulk_status_id'),
            'assignee' => array('assignee_user_id', 'bulk_assignee_user_id'),
            'group' => array('assignee_group_id', 'bulk_assignee_group_id'),
            'priority' => array('priority_id', 'bulk_priority_id'),
        );

        if (isset($field_map[$bulk_action])) {
            list($field, $post_key) = $field_map[$bulk_action];
            $value = $this->posted_nullable_int($post_key);
            foreach ($ids as $id) {
                $inquiry = Novajyin_Repository::get_inquiry($id);
                if (Novajyin_Plugin::can_edit_inquiry($inquiry)) {
                    Novajyin_Repository::update_inquiry($id, array($field => $value), get_current_user_id(), true);
                }
            }
        }

        $this->redirect(admin_url('admin.php?page=novajyin_inquiries&novajyin_message=updated'));
    }

    public function handle_save_group()
    {
        check_admin_referer('novajyin_save_group');
        if (!Novajyin_Plugin::can_manage_groups()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        Novajyin_Repository::save_group(
            array(
                'id' => $this->posted_absint('id'),
                'group_name' => $this->posted_text('group_name'),
                'description' => $this->posted_textarea('description'),
                'notification_email' => $this->posted_email('notification_email'),
                'sort_order' => $this->posted_absint('sort_order'),
                'is_active' => $this->posted_flag('is_active'),
                'user_ids' => $this->posted_absint_array('user_ids'),
            )
        );
        $this->redirect(admin_url('admin.php?page=novajyin_groups&novajyin_message=saved'));
    }

    public function handle_delete_group()
    {
        $id = $this->query_absint('id');
        check_admin_referer('novajyin_delete_group_' . $id);
        if (!Novajyin_Plugin::can_manage_groups()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        Novajyin_Repository::delete_group($id);
        $this->redirect(admin_url('admin.php?page=novajyin_groups&novajyin_message=deleted'));
    }

    public function handle_save_status()
    {
        check_admin_referer('novajyin_save_status');
        if (!Novajyin_Plugin::can_manage_settings()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        Novajyin_Repository::save_status(
            array(
                'id' => $this->posted_absint('id'),
                'status_name' => $this->posted_text('status_name'),
                'sort_order' => $this->posted_absint('sort_order'),
                'is_default' => $this->posted_flag('is_default'),
                'is_closed' => $this->posted_flag('is_closed'),
            )
        );
        $this->redirect(admin_url('admin.php?page=novajyin_statuses&novajyin_message=saved'));
    }

    public function handle_delete_status()
    {
        $id = $this->query_absint('id');
        check_admin_referer('novajyin_delete_status_' . $id);
        if (!Novajyin_Plugin::can_manage_settings()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        Novajyin_Repository::delete_status($id);
        $this->redirect(admin_url('admin.php?page=novajyin_statuses&novajyin_message=deleted'));
    }

    public function handle_save_priority()
    {
        check_admin_referer('novajyin_save_priority');
        if (!Novajyin_Plugin::can_manage_settings()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        Novajyin_Repository::save_priority(
            array(
                'id' => $this->posted_absint('id'),
                'priority_name' => $this->posted_text('priority_name'),
                'sort_order' => $this->posted_absint('sort_order'),
            )
        );
        $this->redirect(admin_url('admin.php?page=novajyin_statuses&novajyin_message=saved'));
    }

    public function handle_delete_priority()
    {
        $id = $this->query_absint('id');
        check_admin_referer('novajyin_delete_priority_' . $id);
        if (!Novajyin_Plugin::can_manage_settings()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        Novajyin_Repository::delete_priority($id);
        $this->redirect(admin_url('admin.php?page=novajyin_statuses&novajyin_message=deleted'));
    }

    public function handle_save_rule()
    {
        check_admin_referer('novajyin_save_rule');
        if (!Novajyin_Plugin::can_manage_settings()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        $condition_field = $this->posted_text('condition_field');
        $custom_field = $this->posted_text('condition_custom_field');
        if ($condition_field === 'custom' && $custom_field !== '') {
            $condition_field = $custom_field;
        }

        $data = array(
            'id' => $this->posted_absint('id'),
            'rule_name' => $this->posted_text('rule_name'),
            'sort_order' => $this->posted_absint('sort_order'),
            'is_active' => $this->posted_flag('is_active'),
            'conditions' => array(
                array(
                    'field' => $condition_field,
                    'operator' => sanitize_key((string) $this->posted_value('condition_operator', 'equals')),
                    'value' => $this->posted_text('condition_value'),
                ),
            ),
            'actions' => array(
                'assignee_user_id' => $this->posted_nullable_int('assignee_user_id'),
                'assignee_group_id' => $this->posted_nullable_int('assignee_group_id'),
                'status_id' => $this->posted_nullable_int('status_id'),
                'priority_id' => $this->posted_nullable_int('priority_id'),
                'due_type' => sanitize_key((string) $this->posted_value('due_type', 'none')),
                'due_value' => $this->posted_absint('due_value', 1),
                'notify_emails' => $this->posted_text('notify_emails'),
            ),
        );

        Novajyin_Repository::save_rule($data);
        $this->redirect(admin_url('admin.php?page=novajyin_rules&novajyin_message=saved'));
    }

    public function handle_delete_rule()
    {
        $id = $this->query_absint('id');
        check_admin_referer('novajyin_delete_rule_' . $id);
        if (!Novajyin_Plugin::can_manage_settings()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        Novajyin_Repository::delete_rule($id);
        $this->redirect(admin_url('admin.php?page=novajyin_rules&novajyin_message=deleted'));
    }

    public function handle_save_settings()
    {
        check_admin_referer('novajyin_save_settings');
        if (!Novajyin_Plugin::can_manage_settings()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        $settings = Novajyin_Repository::get_settings();
        $settings['managed_forms'] = $this->posted_absint_array('managed_forms');
        $settings['save_attachments'] = $this->posted_flag('save_attachments');
        $settings['retention_days'] = $this->posted_absint('retention_days');
        $settings['keep_data_on_delete'] = $this->posted_flag('keep_data_on_delete');
        $settings['field_mapping'] = $this->sanitize_field_mapping($this->posted_value('field_mapping', array()));

        Novajyin_Repository::update_settings($settings);
        $this->redirect(admin_url('admin.php?page=novajyin_settings&novajyin_message=saved'));
    }

    public function handle_save_notifications()
    {
        check_admin_referer('novajyin_save_notifications');
        if (!Novajyin_Plugin::can_manage_settings()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        $settings = Novajyin_Repository::get_settings();
        $settings['notify_on_new'] = $this->posted_flag('notify_on_new');
        $settings['notify_admin'] = $this->posted_flag('notify_admin');
        $settings['notify_assignee'] = $this->posted_flag('notify_assignee');
        $settings['notify_group'] = $this->posted_flag('notify_group');
        $settings['notify_emails'] = $this->posted_textarea('notify_emails');

        Novajyin_Repository::update_settings($settings);
        $this->redirect(admin_url('admin.php?page=novajyin_notifications&novajyin_message=saved'));
    }

    public function handle_export_csv()
    {
        check_admin_referer('novajyin_export_csv');
        if (!Novajyin_Plugin::can_export()) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        $filters = $this->get_filter_args($_POST);
        $filters['per_page'] = 0;
        $rows = Novajyin_Repository::query_inquiries($filters);
        $this->send_csv($rows);
    }

    public function handle_download_attachment()
    {
        $id = $this->query_absint('id');
        $index = $this->query_absint('index');
        check_admin_referer('novajyin_download_attachment_' . $id);

        $inquiry = Novajyin_Repository::get_inquiry($id);
        if (!Novajyin_Plugin::can_view_inquiry($inquiry)) {
            wp_die(esc_html__('You do not have permission to access this page.', 'nova-jyo-inquiry'));
        }

        $attachments = Novajyin_Repository::decode_json($inquiry->attachments_json);
        if (!isset($attachments[$index]['path'])) {
            wp_die(esc_html__('File not found.', 'nova-jyo-inquiry'));
        }

        $path = wp_normalize_path($attachments[$index]['path']);
        $upload_dir = wp_upload_dir();
        $base_dir = wp_normalize_path(trailingslashit($upload_dir['basedir']) . 'nova-jyo-inquiries');
        if (strpos($path, $base_dir) !== 0 || !is_readable($path)) {
            wp_die(esc_html__('File not found.', 'nova-jyo-inquiry'));
        }

        nocache_headers();
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="' . basename($path) . '"');
        header('Content-Length: ' . filesize($path));
        readfile($path);
        exit;
    }

    private function export_csv_by_ids($ids)
    {
        $rows = array();
        foreach ($ids as $id) {
            $inquiry = Novajyin_Repository::get_inquiry($id);
            if ($inquiry && Novajyin_Plugin::can_view_inquiry($inquiry)) {
                $rows[] = $inquiry;
            }
        }
        $this->send_csv($rows);
    }

    private function send_csv($rows)
    {
        $filename = 'nova-jyo-inquiries-' . wp_date('Ymd-His') . '.csv';
        nocache_headers();
        header('Content-Type: text/csv; charset=UTF-8');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        echo "\xEF\xBB\xBF";

        $out = fopen('php://output', 'w');
        fputcsv($out, array('問い合わせID', '受付日時', 'フォーム名', '氏名', 'メールアドレス', '電話番号', '問い合わせ種別', '店舗名', '件名', '問い合わせ内容', 'ステータス', '担当者', '担当グループ', '優先度', '対応期限', '最終更新日時'));
        foreach ($rows as $row) {
            fputcsv(
                $out,
                array(
                    $row->id,
                    $row->submitted_at,
                    $row->form_name,
                    $row->name,
                    $row->email,
                    $row->tel,
                    $row->inquiry_type,
                    $row->shop_name,
                    $row->subject,
                    $row->message,
                    $row->status_name,
                    $row->assignee_name,
                    $row->group_name,
                    $row->priority_name,
                    $row->due_date,
                    $row->updated_at,
                )
            );
        }
        fclose($out);
        exit;
    }

    private function sanitize_field_mapping($mapping)
    {
        $mapping = is_array($mapping) ? wp_unslash($mapping) : array();
        $clean = array();
        foreach ($mapping as $form_key => $fields) {
            $form_key = $form_key === 'default' ? 'default' : absint($form_key);
            foreach ((array) $fields as $key => $value) {
                if (!isset($this->mapping_fields()[$key])) {
                    continue;
                }
                $clean[$form_key][$key] = sanitize_text_field($value);
            }
        }
        return $clean;
    }

    private function detail_row($label, $value, $html = false)
    {
        if ($html) {
            echo '<tr><th>' . esc_html($label) . '</th><td>' . wp_kses_post($value) . '</td></tr>';
            return;
        }

        echo '<tr><th>' . esc_html($label) . '</th><td>' . esc_html($value) . '</td></tr>';
    }

    private function is_overdue($inquiry)
    {
        if (empty($inquiry->due_date) || !empty($inquiry->is_closed)) {
            return false;
        }

        return strtotime($inquiry->due_date) < current_time('timestamp');
    }

    private function datetime_local_value($value)
    {
        if (!$value) {
            return '';
        }

        return mysql2date('Y-m-d\TH:i', $value);
    }

    private function normalize_datetime($value)
    {
        $value = sanitize_text_field((string) $value);
        if ($value === '') {
            return null;
        }

        $value = str_replace('T', ' ', $value);
        if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/', $value)) {
            $value .= ':00';
        }

        return $value;
    }

    private function nullable_int($value)
    {
        if ($value === null || $value === '' || (string) $value === '0') {
            return null;
        }

        return absint($value);
    }

    private function posted_value($key, $default = '')
    {
        if (!isset($_POST[$key])) {
            return $default;
        }

        return wp_unslash($_POST[$key]);
    }

    private function query_value($key, $default = '')
    {
        if (!isset($_GET[$key])) {
            return $default;
        }

        return wp_unslash($_GET[$key]);
    }

    private function query_key($key, $default = '')
    {
        return sanitize_key((string) $this->query_value($key, $default));
    }

    private function query_absint($key, $default = 0)
    {
        return absint($this->query_value($key, $default));
    }

    private function current_query_args()
    {
        $args = wp_unslash($_GET);
        if (!is_array($args)) {
            return array();
        }

        foreach ($args as $key => $value) {
            if (is_array($value)) {
                $args[$key] = array_map('sanitize_text_field', $value);
                continue;
            }

            $args[$key] = sanitize_text_field((string) $value);
        }

        return $args;
    }

    private function posted_text($key, $default = '')
    {
        return sanitize_text_field((string) $this->posted_value($key, $default));
    }

    private function posted_textarea($key, $default = '')
    {
        return sanitize_textarea_field((string) $this->posted_value($key, $default));
    }

    private function posted_email($key, $default = '')
    {
        return sanitize_email((string) $this->posted_value($key, $default));
    }

    private function posted_absint($key, $default = 0)
    {
        return absint($this->posted_value($key, $default));
    }

    private function posted_nullable_int($key)
    {
        return $this->nullable_int($this->posted_value($key, null));
    }

    private function posted_absint_array($key)
    {
        $values = $this->posted_value($key, array());
        return array_filter(array_map('absint', (array) $values));
    }

    private function posted_flag($key)
    {
        return isset($_POST[$key]) ? 1 : 0;
    }

    private function select($name, $selected, $options, $disabled = false)
    {
        echo '<select name="' . esc_attr($name) . '" id="' . esc_attr($name) . '"' . disabled($disabled, true, false) . '>';
        foreach ($options as $value => $label) {
            echo '<option value="' . esc_attr($value) . '" ' . selected((string) $selected, (string) $value, false) . '>' . esc_html($label) . '</option>';
        }
        echo '</select>';
    }

    private function object_select($name, $selected, $objects, $value_key, $label_key, $empty_label, $disabled = false)
    {
        echo '<select name="' . esc_attr($name) . '" id="' . esc_attr($name) . '"' . disabled($disabled, true, false) . '>';
        echo '<option value="">' . esc_html($empty_label) . '</option>';
        foreach ($objects as $object) {
            echo '<option value="' . esc_attr($object->$value_key) . '" ' . selected((string) $selected, (string) $object->$value_key, false) . '>' . esc_html($object->$label_key) . '</option>';
        }
        echo '</select>';
    }

    private function user_select($name, $selected, $users, $empty_label, $disabled = false)
    {
        echo '<select name="' . esc_attr($name) . '" id="' . esc_attr($name) . '"' . disabled($disabled, true, false) . '>';
        echo '<option value="">' . esc_html($empty_label) . '</option>';
        foreach ($users as $user) {
            echo '<option value="' . esc_attr($user->ID) . '" ' . selected((string) $selected, (string) $user->ID, false) . '>' . esc_html($user->display_name) . '</option>';
        }
        echo '</select>';
    }

    private function mapping_fields()
    {
        return array(
            'name' => '氏名',
            'email' => 'メールアドレス',
            'tel' => '電話番号',
            'inquiry_type' => '問い合わせ種別',
            'shop_name' => '店舗名',
            'subject' => '件名',
            'message' => '問い合わせ内容',
        );
    }

    private function condition_field_options()
    {
        return array(
            'form_name' => 'フォーム名',
            'form_id' => 'フォームID',
            'inquiry_type' => '問い合わせ種別',
            'shop_name' => '店舗名',
            'region' => '地域',
            'email' => 'メールアドレス',
            'subject' => '件名',
            'message' => '問い合わせ内容',
            'custom' => '任意のContact Form 7フィールド',
        );
    }

    private function redirect($url)
    {
        wp_safe_redirect($url);
        exit;
    }
}







