<?php

namespace GriffinForms\Admin\Html\Pages\Lists;

class Files extends \GriffinForms\Admin\Html\Pages\Lists\Format
{   
    protected $meta;
    protected $inline_js;
    protected $order_by = 'created_at';
    protected $status_counts = [];
    
    protected function setType()
    {
        $this->type = 'file';
    }

    protected function addNewButton()
    {
    }

    protected function setStatusCounts()
    {
        $this->status_counts = $this->sql->getUniqueStatusesWithCount();
    }

    /**
     * Outputs a select dropdown for filtering by file MIME type.
     */
    protected function itemTypeFilter()
    {
        // Current selected MIME (from query string).
        $current = isset($_GET['mime']) ? sanitize_text_field( wp_unslash( $_GET['mime'] ) ) : '';

        $mime_types = is_array($this->sql->getUniqueMimeTypes()) ? $this->sql->getUniqueMimeTypes() : array();

        // Accessible label for screen readers only.
        $label_text = method_exists($this->lang, 'getText')
            ? $this->lang->getText('Filter by type', 'filters')
            : __('Filter by type', 'griffinforms-form-builder');
        $all_text = method_exists($this->lang, 'getText')
            ? $this->lang->getText('all_types', 'filters')
            : __('All types', 'griffinforms-form-builder');

        echo '<label for="gf-filter-mime" class="screen-reader-text">' . esc_html($label_text) . '</label>';
        echo '<select name="mime" id="gf-filter-mime">';
        echo '<option value="">' . esc_html($all_text) . '</option>';

        foreach ($mime_types as $mime) {
            if (!is_string($mime) || $mime === '') {
                continue;
            }
            echo '<option value="' . esc_attr($mime) . '"' . selected($current, $mime, false) . '>'
                . esc_html($mime)
                . '</option>';
        }

        echo '</select>';
    }

    /**
     * Outputs a select dropdown for filtering by storage mode.
     */
    protected function storageModeFilter()
    {
        // Current selected storage mode (from query string).
        $current = isset($_GET['storage_mode']) ? sanitize_text_field( wp_unslash( $_GET['storage_mode'] ) ) : '';

        $modes = array('private', 'media');

        // Accessible label for screen readers only.
        $label_text = method_exists($this->lang, 'getText')
            ? $this->lang->getText('Filter by storage mode', 'filter')
            : __('Filter by storage mode', 'griffinforms-form-builder');
        $all_text = method_exists($this->lang, 'getText')
            ? $this->lang->getText('all_storage_modes', 'filter')
            : __('All storage modes', 'griffinforms-form-builder');

        echo '<label for="gf-filter-storage-mode" class="screen-reader-text">' . esc_html($label_text) . '</label>';
        echo '<select name="storage_mode" id="gf-filter-storage-mode">';
        echo '<option value="">' . esc_html($all_text) . '</option>';

        foreach ($modes as $mode) {
            if (!is_string($mode) || $mode === '') {
                continue;
            }
            echo '<option value="' . esc_attr($mode) . '"' . selected($current, $mode, false) . '>'
                . esc_html($this->lang->getText($mode, 'filter'))
                . '</option>';
        }

        echo '</select>';
    }

    protected function itemFilters()
    {
        echo '<div class="alignleft actions">';
        $this->itemTypeFilter();
        $this->storageModeFilter();
        $this->sizeFilter();
        $this->dateFilter();
        echo '</div>';
    }

    /**
     * Outputs a select dropdown for filtering by minimum file size.
     */
    protected function sizeFilter()
    {
        $current = isset($_GET['size_min']) ? absint($_GET['size_min']) : 0;

        // Thresholds in bytes
        $options = array(
            0           => method_exists($this->lang, 'getText') ? $this->lang->getText('all_sizes', 'filter') : __('All sizes', 'griffinforms-form-builder'),
            512 * 1024  => '≥ 512 KB',
            1 * 1024 * 1024   => '≥ 1 MB',
            5 * 1024 * 1024   => '≥ 5 MB',
            10 * 1024 * 1024  => '≥ 10 MB',
        );

        echo '<label for="gf-filter-size" class="screen-reader-text">' . esc_html( method_exists($this->lang, 'getText') ? $this->lang->getText('Filter by size', 'filter') : __('Filter by size', 'griffinforms-form-builder') ) . '</label>';
        echo '<select name="size_min" id="gf-filter-size">';
        foreach ($options as $value => $label) {
            echo '<option value="' . esc_attr($value) . '"' . selected($current, $value, false) . '>' . esc_html($label) . '</option>';
        }
        echo '</select>';
    }

    protected function setFilterNames()
    {
        $this->filter_names = array(
            'search',
            'status',
            'mime',
            'storage_mode',
            'size_min',
            'date_from',
            'date_to',
        );
    }

    protected function setBulkActions()
    {
        $this->bulk_actions = array();
    }
    
    protected function registerColumns(): void
    {
        $r = $this->column_registry;

        $r->register('file', 'checkbox',       ['label' => '',                                                     'locked' => true, 'default_on' => true]);
        $r->register('file', 'url',            ['label' => $this->lang->getText('url', 'list_head'),               'locked' => true, 'default_on' => true]);

        $r->register('file', 'mime',           ['label' => $this->lang->getText('mime', 'list_head'),              'default_on' => true]);
        $r->register('file', 'size_bytes',     ['label' => $this->lang->getText('size_bytes', 'list_head'),        'default_on' => true, 'sortable' => true]);
        $r->register('file', 'storage_mode',   ['label' => $this->lang->getText('storage_mode', 'list_head'),      'default_on' => true]);
        $r->register('file', 'status',         ['label' => $this->lang->getText('status', 'list_head'),            'default_on' => true]);
        $r->register('file', 'field_id',       ['label' => $this->lang->getText('field_id', 'list_head'),          'default_on' => true]);
        $r->register('file', 'created_at',     ['label' => $this->lang->getText('created_at', 'list_head'),        'default_on' => true, 'sortable' => true]);

        $r->register('file', 'id',             ['label' => __('ID', 'griffinforms-form-builder'),                  'default_on' => false]);
        $r->register('file', 'submission_link',['label' => __('Submission', 'griffinforms-form-builder'),          'default_on' => false]);

        parent::registerColumns();
    }

    protected function setRowActions()
    {
        $this->row_actions = array(
            'view_file',
            'view_submission'
        );
    }

    protected function rowActionViewSubmission($item)
    {
        $submission_id = isset($item->submission_id) ? absint($item->submission_id) : 0;

        if ($submission_id > 0) {
            $url = admin_url('admin.php?page=griffinforms-submission&id=' . $submission_id);
            echo '<a href="' . esc_url($url) . '" target="_blank" rel="noopener noreferrer">' . esc_html($this->lang->getText('view_submission', 'row_action')) . '</a>';
        } else {
            echo $this->lang->getText('not_linked_to_submission');
        }
    }

    protected function rowActionViewFile($item)
    {
        $file_url = isset($item->url) ? $item->url : null;
        if ($file_url) {
            echo '<a href="' . esc_url($file_url) . '" target="_blank" rel="noopener noreferrer">' . esc_html($this->lang->getText('view_file', 'row_action')) . '</a>';
        }
    }

    protected function sizeBytesHeadingText()
    {
        echo esc_html($this->lang->getText('size_bytes', 'list_head'));
    }

    protected function createdAtHeadingText()
    {
        echo esc_html($this->lang->getText('created_at', 'list_head'));
    }

    protected function setFilterLinks()
    {
        $this->filter_links = ['all', 'temp', 'attached'];
    }

    protected function tempFilterLink()
    {
        $filters   = $this->getListFilters();
        $current   = isset($filters['status']) ? (string) $filters['status'] : '';
        $count     = isset($this->status_counts['temp']) ? (int) $this->status_counts['temp'] : 0;
        $link_class = ($current === 'temp') ? 'current' : '';
        $filter_url = add_query_arg(array('status' => 'temp'), $this->list_url);

        echo '<a href="' . esc_url($filter_url) . '" class="' . esc_attr($link_class) . '">';
        echo esc_html($this->lang->getText('temp_status'));
        echo ' <span class="count">(' . absint($count) . ')</span>';
        echo '</a>';
    }

    protected function attachedFilterLink()
    {
        $filters   = $this->getListFilters();
        $current   = isset($filters['status']) ? (string) $filters['status'] : '';
        $count     = isset($this->status_counts['attached']) ? (int) $this->status_counts['attached'] : 0;
        $link_class = ($current === 'attached') ? 'current' : '';
        $filter_url = add_query_arg(array('status' => 'attached'), $this->list_url);

        echo '<a href="' . esc_url($filter_url) . '" class="' . esc_attr($link_class) . '">';
        echo esc_html($this->lang->getText('attached_status'));
        echo ' <span class="count">(' . absint($count) . ')</span>';
        echo '</a>';
    }

    protected function urlCellText($list_item, $item)
    {
        $url = $item->url;
        $filename = basename(parse_url($url, PHP_URL_PATH));
        echo esc_html($filename);
    }

    protected function storageModeCellText($list_item, $item)
    {
        $storage_mode = (string) $item->storage_mode;
        $text = esc_html($this->lang->getText($storage_mode));

        // If stored in Media Library, try to resolve the attachment and link to its edit screen.
        if ($storage_mode === 'media' || $storage_mode === 'media_library') {
            $url = isset($item->url) ? $item->url : '';
            $attachment_id = 0;

            if (!empty($url)) {
                $attachment_id = attachment_url_to_postid($url);
            }

            if ($attachment_id) {
                $edit_link = get_edit_post_link($attachment_id);
                if ($edit_link) {
                    echo $text . '<br><a href="' . esc_url($edit_link) . '" target="_blank" rel="noopener noreferrer">' 
                        . esc_html($this->lang->getText('view_file')) 
                        . '</a>';
                    return;
                }
            }
        }

        echo $text;
    }

    protected function statusCellText($list_item, $item)
    {
        $status = (string) $item->status;
        $label  = esc_html($this->lang->getText($status . '_status'));
        $class  = $status === 'attached' ? 'badge text-bg-success' : 'badge text-bg-secondary';
        echo '<span class="' . $class . '">' . $label . '</span>';
    }

    protected function fieldIdCellText($list_item, $item)
    {
        $id = absint($item->field_id);
        if ($id > 0) {
            $edit_url = admin_url('admin.php?page=griffinforms-field&id=' . $id . '&field-type=fileupload');
            echo '<a class="text-center" href="' . esc_url($edit_url) . '" target="_blank" rel="noopener noreferrer">' . esc_html($id) . '</a>';
        } else {
            echo esc_html__('Not available', 'griffinforms-form-builder');
        }
    }

    protected function mimeCellText($list_item, $item)
    {
        $mime = strtolower(trim((string) $item->mime));
        // Strip any parameters like "; charset=utf-8"
        $mime = explode(';', $mime)[0];

        $ext = '';

        // 1) Try WP's MIME map (case-insensitive)
        $mimes = wp_get_mime_types();
        $flipped = array_change_key_case(array_flip($mimes), CASE_LOWER);
        if (isset($flipped[$mime])) {
            // Handle multi-ext strings like "jpg|jpeg|jpe" → take the first
            $first = explode('|', $flipped[$mime]);
            $ext = $first[0];
        }

        // 2) Fallback: check by filename → ext/type
        if (!$ext) {
            $path = parse_url((string) ($item->url ?? ''), PHP_URL_PATH);
            $filename = $path ? basename($path) : '';
            if ($filename) {
                $ft = wp_check_filetype($filename);
                if (!empty($ft['ext'])) {
                    $ext = $ft['ext'];
                }
            }
        }

        // 3) Final fallback: derive from URL path extension directly
        if (!$ext) {
            $path = isset($path) ? $path : parse_url((string) ($item->url ?? ''), PHP_URL_PATH);
            if ($path) {
                $derived = pathinfo($path, PATHINFO_EXTENSION);
                if (!empty($derived)) {
                    $ext = $derived;
                }
            }
        }

        if ($ext) {
            $file = $this->config->getRootPath() . 'frontend/images/fileicons/' . $ext . '.svg';
            $icon = $this->config->getRootUrl() . 'frontend/images/fileicons/file.svg';
            if (file_exists($file)) {
                $icon = $this->config->getRootUrl() . 'frontend/images/fileicons/' . $ext . '.svg';
            }

            echo '<span class="d-inline-flex align-items-center gap-1">';
            echo '<img src="' . esc_url($icon) . '" width="16" height="16" loading="lazy" decoding="async" alt="" aria-hidden="true" class="gf-file-icon" />';
            echo '<span class="badge text-bg-secondary" title="' . esc_attr($mime) . '">' . esc_html(strtoupper($ext)) . '</span>';
            echo '</span>';
        } else {
            echo '<span class="badge text-bg-secondary">' . esc_html($mime) . '</span>';
        }
    }

    protected function sizeBytesCellText($list_item, $item)
    {
        $units = \GriffinForms\Admin\Units::getInstance();
        $size = $units->formatBytes($item->size_bytes);
        echo '<span class="small fw-bold">' . esc_html($size) . '</span>';
    }

    protected function createdAtCellText($list_item, $item)
    {
        $item_date = strtotime($item->created_at);
        $current_date = strtotime('now');

        $date_format = get_option('date_format');
        $time_format = get_option('time_format');

        $formatted_item_date = wp_date($date_format, $item_date);
        $formatted_item_time = wp_date($time_format, $item_date);

        $is_today = wp_date('d', $item_date) === wp_date('d');
        $is_yesterday = absint(wp_date('d', $item_date)) === (absint(wp_date('d')) - 1);

        if ($is_today) {
            echo esc_html($this->lang->getText('Today', 'date'));
        } elseif ($is_yesterday) {
            echo esc_html($this->lang->getText('Yesterday', 'date'));
        } else {
            echo esc_html($formatted_item_date);
        }

        echo '<br> at ';
        echo esc_html($formatted_item_time);
    }

    protected function idCellText($list_column, $item)
    {
        echo '<span class="badge text-bg-secondary">' . absint($item->id) . '</span>';
    }

    protected function submissionlinkCellText($list_column, $item)
    {
        $sub_id = absint($item->submission_id ?? 0);
        if ($sub_id === 0) {
            echo '<span class="text-muted">—</span>';
            return;
        }
        $url = admin_url('admin.php?page=griffinforms-submissions&id=' . $sub_id);
        echo '<a href="' . esc_url($url) . '" class="badge text-bg-primary text-decoration-none">' . esc_html($sub_id) . '</a>';
    }
}
