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

use BLR\Backline\Core\Access;
use BLR\Backline\Core\SettingsPage;
use BLR\Backline\Modules\Events\Module as EventsModule;
use BLR\Backline\Modules\Finances\Module as FinancesModule;
use BLR\Backline\Modules\Notifications\Module as NotificationsModule;
use BLR\Backline\Modules\Outreach\Module as OutreachModule;
use BLR\Backline\Modules\Tasks\Module as TasksModule;
use WP_Query;
use WP_User;

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

final class Pages {
    public static function render(array $ctx): string {
        $ctx['dashboard'] = self::data($ctx);
        return \BLR\Backline\Core\Views::render('pages/dashboard', $ctx);
    }

    public static function data(array $ctx): array {
        $base          = rtrim((string) ($ctx['base_url'] ?? ''), '/') . '/';
        $post_statuses = ['publish', 'draft'];
        $timezone      = wp_timezone();
        $is_admin_user = current_user_can('manage_options');

        $count_posts_by_meta = static function (string $post_type, array $meta_query, array $post_status = ['publish', 'draft']): int {
            $query = new WP_Query([
                'post_type'      => $post_type,
                'post_status'    => $post_status,
                'posts_per_page' => 1,
                'fields'         => 'ids',
                'meta_query'     => $meta_query,
            ]);

            return (int) $query->found_posts;
        };

        $format_date = static function (string $value) use ($timezone): string {
            if ($value === '') {
                return __('—', 'blr-backline');
            }

            $timestamp = strtotime($value);
            if ($timestamp === false) {
                return $value;
            }

            return wp_date(get_option('date_format'), $timestamp, $timezone);
        };

        $format_datetime = static function (string $value) use ($timezone): string {
            if ($value === '') {
                return __('—', 'blr-backline');
            }

            $timestamp = strtotime($value);
            if ($timestamp === false) {
                return $value;
            }

            return wp_date(get_option('date_format') . ' ' . get_option('time_format'), $timestamp, $timezone);
        };

        $get_user_label = static function (int $user_id): string {
            $user = $user_id > 0 ? get_userdata($user_id) : null;

            return $user instanceof WP_User ? $user->display_name : __('Unassigned', 'blr-backline');
        };

        $get_event_location = static function (int $event_id): string {
            $parts = [];
            $venue = trim((string) get_post_meta($event_id, 'blr_venue_name', true));
            $city  = trim((string) get_post_meta($event_id, 'blr_venue_city', true));
            $state = trim((string) get_post_meta($event_id, 'blr_venue_state', true));

            if ($venue !== '') {
                $parts[] = $venue;
            }

            $city_state = trim(implode(', ', array_filter([$city, $state])));
            if ($city_state !== '') {
                $parts[] = $city_state;
            }

            return !empty($parts) ? implode(' • ', $parts) : __('Location not set', 'blr-backline');
        };

        $module_enabled = static function (string $module): bool {
            return SettingsPage::is_module_enabled($module);
        };

        $module_accessible = static function (string $module) use ($is_admin_user): bool {
            return $is_admin_user || Access::module_is_accessible($module);
        };

        $module_available = static function (string $module) use ($module_enabled, $module_accessible): bool {
            return $module_enabled($module) && $module_accessible($module);
        };

        $discography_enabled    = $module_enabled('discography');
        $discography_accessible = $module_accessible('discography');
        $discography_available  = $module_available('discography');

        $contacts_enabled    = $module_enabled('contacts');
        $contacts_accessible = $module_accessible('contacts');
        $contacts_available  = $module_available('contacts');

        $events_enabled    = $module_enabled('events');
        $events_accessible = $module_accessible('events');
        $events_available  = $module_available('events');

        $outreach_enabled    = $module_enabled('outreach');
        $outreach_accessible = $module_accessible('outreach');
        $outreach_available  = $module_available('outreach');

        $tasks_enabled    = $module_enabled('tasks');
        $tasks_accessible = $module_accessible('tasks');
        $tasks_available  = $module_available('tasks');

        $finances_enabled    = $module_enabled('finances');
        $finances_accessible = $module_accessible('finances');
        $finances_available  = $module_available('finances');

        $notifications_enabled    = $module_enabled('notifications');
        $notifications_accessible = $module_accessible('notifications');
        $notifications_available  = $module_available('notifications');

        $quick_actions = [];

        $release_count  = wp_count_posts('blr_release');
        $track_count    = wp_count_posts('blr_track');
        $event_count         = wp_count_posts('blr_event');
        $outreach_count      = wp_count_posts('blr_outreach');
        $contact_count       = wp_count_posts('blr_contact');
        $task_count          = wp_count_posts('blr_task');
        $finance_record_count = wp_count_posts(FinancesModule::POST_TYPE);

        $r  = (int) (($release_count->publish ?? 0) + ($release_count->draft ?? 0));
        $t  = (int) (($track_count->publish ?? 0) + ($track_count->draft ?? 0));
        $e  = (int) (($event_count->publish ?? 0) + ($event_count->draft ?? 0));
        $o  = (int) (($outreach_count->publish ?? 0) + ($outreach_count->draft ?? 0));
        $c  = (int) (($contact_count->publish ?? 0) + ($contact_count->draft ?? 0));
        $ta = (int) (($task_count->publish ?? 0) + ($task_count->draft ?? 0));
        $f  = (int) (($finance_record_count->publish ?? 0) + ($finance_record_count->draft ?? 0));

        $today          = current_time('Y-m-d');
        $today_datetime = current_time('Y-m-d H:i');
        $week_end       = wp_date('Y-m-d', strtotime('+7 days', current_time('timestamp')), $timezone);

        $upcoming = $events_available ? get_posts([
            'post_type'      => 'blr_event',
            'post_status'    => $post_statuses,
            'numberposts'    => 5,
            'meta_key'       => 'blr_event_start',
            'orderby'        => ['meta_value' => 'ASC', 'date' => 'ASC'],
            'meta_type'      => 'CHAR',
            'meta_query'     => [[
                'key'     => 'blr_event_start',
                'value'   => $today_datetime,
                'compare' => '>=',
                'type'    => 'CHAR',
            ]],
        ]) : [];

        $latest_outreach = $outreach_available ? get_posts([
            'post_type'   => 'blr_outreach',
            'post_status' => $post_statuses,
            'numberposts' => 5,
            'orderby'     => 'modified',
            'order'       => 'DESC',
        ]) : [];

        $due_tasks = $tasks_available ? get_posts([
            'post_type'      => 'blr_task',
            'post_status'    => $post_statuses,
            'numberposts'    => 6,
            'meta_key'       => 'blr_task_due_date',
            'orderby'        => ['meta_value' => 'ASC', 'date' => 'DESC'],
            'meta_type'      => 'DATE',
            'meta_query'     => [
                'relation' => 'AND',
                [
                    'key'     => 'blr_task_due_date',
                    'compare' => 'EXISTS',
                ],
                [
                    'key'     => 'blr_task_due_date',
                    'value'   => '',
                    'compare' => '!=',
                ],
                [
                    'key'     => 'blr_task_status',
                    'value'   => 'Done',
                    'compare' => '!=',
                ],
            ],
        ]) : [];

        $done_tasks = $tasks_available ? $count_posts_by_meta(
            'blr_task',
            [[
                'key'   => 'blr_task_status',
                'value' => 'Done',
            ]],
            $post_statuses
        ) : 0;

        $overdue_tasks = $tasks_available ? $count_posts_by_meta(
            'blr_task',
            [
                [
                    'key'     => 'blr_task_due_date',
                    'value'   => $today,
                    'compare' => '<',
                    'type'    => 'DATE',
                ],
                [
                    'key'     => 'blr_task_status',
                    'value'   => 'Done',
                    'compare' => '!=',
                ],
            ],
            $post_statuses
        ) : 0;

        $due_this_week = $tasks_available ? $count_posts_by_meta(
            'blr_task',
            [
                [
                    'key'     => 'blr_task_due_date',
                    'value'   => [$today, $week_end],
                    'compare' => 'BETWEEN',
                    'type'    => 'DATE',
                ],
                [
                    'key'     => 'blr_task_status',
                    'value'   => 'Done',
                    'compare' => '!=',
                ],
            ],
            $post_statuses
        ) : 0;

        $upcoming_events_total = $events_available ? $count_posts_by_meta(
            'blr_event',
            [[
                'key'     => 'blr_event_start',
                'value'   => $today_datetime,
                'compare' => '>=',
                'type'    => 'CHAR',
            ]],
            $post_statuses
        ) : 0;

        $outreach_draft_count = $outreach_available ? $count_posts_by_meta(
            'blr_outreach',
            [[
                'key'   => 'blr_outreach_status',
                'value' => 'Draft',
            ]],
            $post_statuses
        ) : 0;

        $outreach_follow_up_count = $outreach_available ? $count_posts_by_meta(
            'blr_outreach',
            [[
                'key'   => 'blr_outreach_workflow_status',
                'value' => 'Follow-up Needed',
            ]],
            $post_statuses
        ) : 0;

        $outreach_active_count = $outreach_available ? $count_posts_by_meta(
            'blr_outreach',
            [[
                'key'     => 'blr_outreach_status',
                'value'   => ['Queued', 'Sending'],
                'compare' => 'IN',
            ]],
            $post_statuses
        ) : 0;

        $open_tasks = max(0, $ta - $done_tasks);
        $unread_notifications_count = $notifications_available ? NotificationsModule::unread_count(get_current_user_id()) : 0;

        if ($tasks_available) {
            $quick_actions[] = [
                'label' => __('New Task', 'blr-backline'),
                'url'   => $base . 'tasks/new/',
                'class' => 'btn btn-sm btn-outline-secondary',
            ];
        }

        if ($events_available) {
            $quick_actions[] = [
                'label' => __('New Event', 'blr-backline'),
                'url'   => $base . 'events/new/',
                'class' => 'btn btn-sm btn-outline-secondary',
            ];
        }

        if ($outreach_available) {
            $quick_actions[] = [
                'label' => __('New Outreach', 'blr-backline'),
                'url'   => $base . 'outreach/new/',
                'class' => 'btn btn-sm btn-primary',
            ];
        }

        $overview_rows = [];

        if ($tasks_available) {
            $overview_rows[] = [
                'label' => __('Overdue Tasks', 'blr-backline'),
                'value' => $overdue_tasks,
                'meta'  => $overdue_tasks > 0 ? __('Needs attention now', 'blr-backline') : __('All caught up', 'blr-backline'),
                'url'   => $base . 'tasks/',
            ];

            $overview_rows[] = [
                'label' => __('Due This Week', 'blr-backline'),
                'value' => $due_this_week,
                'meta'  => __('Next 7 days', 'blr-backline'),
                'url'   => $base . 'tasks/',
            ];
        }

        if ($events_available) {
            $overview_rows[] = [
                'label' => __('Upcoming Events', 'blr-backline'),
                'value' => $upcoming_events_total,
                'meta'  => __('Scheduled ahead', 'blr-backline'),
                'url'   => $base . 'events/',
            ];
        }

        if ($outreach_available) {
            $overview_rows[] = [
                'label' => __('Follow-Ups Needed', 'blr-backline'),
                'value' => $outreach_follow_up_count,
                'meta'  => $outreach_draft_count > 0
                    ? sprintf(
                        /* translators: %s: number of draft outreach items. */
                        __('%s drafts waiting too', 'blr-backline'),
                        number_format_i18n($outreach_draft_count)
                    )
                    : __('No draft backlog', 'blr-backline'),
                'url'   => $base . 'outreach/',
            ];
        }

        $all_modules = [
            [
                'slug'        => 'discography',
                'title'       => __('Discography', 'blr-backline'),
                'description' => __('Manage albums and tracks.', 'blr-backline'),
                'enabled'     => $discography_enabled,
                'accessible'  => $discography_accessible,
                'active'      => $discography_available,
                'url'         => $base . 'albums/',
                'count'       => $r + $t,
                'meta'        => sprintf(
                    /* translators: 1: album count, 2: line break, 3: track count. */
                    __('%1$s albums%2$s%3$s tracks', 'blr-backline'),
                    number_format_i18n($r),
                    '<br />',
                    number_format_i18n($t)
                ),
            ],
            [
                'slug'        => 'contacts',
                'title'       => __('Contacts', 'blr-backline'),
                'description' => __('Organize promoters, venues, and people.', 'blr-backline'),
                'enabled'     => $contacts_enabled,
                'accessible'  => $contacts_accessible,
                'active'      => $contacts_available,
                'url'         => $base . 'contacts/',
                'count'       => $c,
                'meta'        => sprintf(
                    /* translators: %s: contact count. */
                    __('%s contacts', 'blr-backline'),
                    number_format_i18n($c)
                ),
            ],
            [
                'slug'        => 'events',
                'title'       => __('Events', 'blr-backline'),
                'description' => __('Track shows, dates, and venue details.', 'blr-backline'),
                'enabled'     => $events_enabled,
                'accessible'  => $events_accessible,
                'active'      => $events_available,
                'url'         => $base . 'events/',
                'count'       => $e,
                'meta'        => sprintf(
                    /* translators: 1: event count, 2: line break, 3: upcoming event count. */
                    __('%1$s events%2$s%3$s upcoming', 'blr-backline'),
                    number_format_i18n($e),
                    '<br />',
                    number_format_i18n($upcoming_events_total)
                ),
            ],
            [
                'slug'        => 'outreach',
                'title'       => __('Outreach', 'blr-backline'),
                'description' => __('Write, send, and track outreach campaigns.', 'blr-backline'),
                'enabled'     => $outreach_enabled,
                'accessible'  => $outreach_accessible,
                'active'      => $outreach_available,
                'url'         => $base . 'outreach/',
                'count'       => $o,
                'meta'        => sprintf(
                    /* translators: 1: outreach campaign count, 2: line break, 3: follow-up count. */
                    __('%1$s campaigns%2$s%3$s follow-ups', 'blr-backline'),
                    number_format_i18n($o),
                    '<br />',
                    number_format_i18n($outreach_follow_up_count)
                ),
            ],
            [
                'slug'        => 'tasks',
                'title'       => __('Tasks', 'blr-backline'),
                'description' => __('Stay on top of work and due dates.', 'blr-backline'),
                'enabled'     => $tasks_enabled,
                'accessible'  => $tasks_accessible,
                'active'      => $tasks_available,
                'url'         => $base . 'tasks/',
                'count'       => $ta,
                'meta'        => sprintf(
                    /* translators: 1: open task count, 2: line break, 3: overdue task count. */
                    __('%1$s open%2$s%3$s overdue', 'blr-backline'),
                    number_format_i18n($open_tasks),
                    '<br />',
                    number_format_i18n($overdue_tasks)
                ),
            ],
            [
                'slug'        => 'finances',
                'title'       => __('Finances', 'blr-backline'),
                'description' => __('Track money in, money out, and what is due.', 'blr-backline'),
                'enabled'     => $finances_enabled,
                'accessible'  => $finances_accessible,
                'active'      => $finances_available,
                'url'         => $base . 'finances/',
                'count'       => $f,
                'meta'        => sprintf(
                    /* translators: %s: finance record count. */
                    __('%s records', 'blr-backline'),
                    number_format_i18n($f)
                ),
            ],
            [
                'slug'        => 'notifications',
                'title'       => __('Notifications', 'blr-backline'),
                'description' => __('See reminders and updates that need your attention.', 'blr-backline'),
                'enabled'     => $notifications_enabled,
                'accessible'  => $notifications_accessible,
                'active'      => $notifications_available,
                'url'         => $base . 'notifications/',
                'count'       => $unread_notifications_count,
                'meta'        => sprintf(
                    /* translators: %s: unread notification count. */
                    __('%s unread', 'blr-backline'),
                    number_format_i18n($unread_notifications_count)
                ),
            ],
        ];

        $active_modules   = [];
        $inactive_modules = [];

        foreach ($all_modules as $module_card) {
            if ($module_card['active']) {
                $active_modules[] = $module_card;
            } elseif ($is_admin_user && !$module_card['enabled']) {
                $inactive_modules[] = $module_card;
            }
        }

        $active_modules_count = count($active_modules);
        $inactive_modules_count = count($inactive_modules);
        $active_item_total = 0;

        foreach ($active_modules as $module_card) {
            $active_item_total += (int) $module_card['count'];
        }

        $dashboard_data = [
            'base_url'                 => $base,
            'counts'                   => [
                'albums'   => $r,
                'tracks'   => $t,
                'events'   => $e,
                'contacts' => $c,
                'outreach' => $o,
                'tasks'         => $ta,
                'finances'      => $f,
                'notifications' => $unread_notifications_count,
            ],
            'overview_rows'            => $overview_rows,
            'active_modules'           => $active_modules,
            'inactive_modules'         => $inactive_modules,
            'open_tasks'               => $open_tasks,
            'done_tasks'               => $done_tasks,
            'overdue_tasks'            => $overdue_tasks,
            'due_this_week'            => $due_this_week,
            'upcoming_events_total'    => $upcoming_events_total,
            'outreach_draft_count'     => $outreach_draft_count,
            'outreach_active_count'    => $outreach_active_count,
            'outreach_follow_up_count' => $outreach_follow_up_count,
            'today'                    => $today,
            'today_datetime'           => $today_datetime,
            'upcoming'                 => $upcoming,
            'due_tasks'                => $due_tasks,
            'latest_outreach'          => $latest_outreach,
        ];
        $__blr_ba_dashboard_data = get_defined_vars();
        unset($__blr_ba_dashboard_data['ctx'], $__blr_ba_dashboard_data['__blr_ba_dashboard_data']);

        return $__blr_ba_dashboard_data;
    }
}