<?php
// Silence may be golden, but sometimes words paint the canvas of understanding.

namespace Plugli\Linksy\SearchAndReplace\Admin\Partials\SearchAndReplace\Helpers;

use Linksy\SearchAndReplace\Plugli\Standard\Helpers\Database\Database;

use Plugli\Linksy\SearchAndReplace\Helpers\Post\Post;

class BrokenLinks extends Helpers
{
    public function get($search_mode, $filter_query, $options = [])
    {
        $broken_links = Database::table("linksy_broken_links");
        $data = [];

        if ($this->search) {
            $broken_links = $broken_links->whereLike('url', $this->search);
        }

        if (!empty($this->filters['status_code'])) {
            $broken_links = $broken_links->whereIn('http_code', $this->filters['status_code']);
        }

        $total_links = 0;
        $total_broken = $this->getCountByCondition($broken_links, 'is_broken', 1);
        $total_warning = $this->getCountByCondition($broken_links, 'is_warning', 1);
        $total_timeout = $this->getCountByCondition($broken_links, 'is_timeout', 1);
        $total_ignored = $this->getCountByCondition($broken_links, 'is_dismissed', 1);
        $total_redirects = 0;

        
        foreach ((clone $broken_links)->get() as $link) {
            $status_code = (int) $link->status_code;
            $post = new Post($link->post_id);

            if ($status_code >= 200 && $status_code < 300 && $link->url === $link->final_url) {
                continue;
            }

            $data[] = [
                'id' => (int) $link->id,
                'post_id' => (int) $link->post_id,
                'source' => $post->get_title(),
                'edit_url' => $post->get_edit_link(),
                'view_url' => $post->get_link(),
                'anchor' => $link->anchor,
                'url' => $link->url,
                'last_checked' => $link->last_checked,
                'final_url' => $link->final_url,
                'status_code' => $status_code,
                'response_time' => $link->response_time,
                'check_count' => $link->check_count,
                'log' => $link->log,
                'is_broken' => (int) $link->is_broken,
                'is_warning' => (int) $link->is_warning,
                'is_timeout' => (int) $link->is_timeout,
                'is_dismissed' => (int) $link->is_dismissed
            ];

            switch (true) {
                case (!empty($link->final_url) && $link->url != $link->final_url && !$link->is_timeout && !$link->is_dismissed && $status_code === 200):
                    $total_redirects++;
                    break;
            }

            $total_links++;
        }

        if ($search_mode) {
            $data = $this->filter($search_mode, $data);
        }

        return [
            'data' => $data,
            'total_links' => $total_links,
            'total_redirects' => $total_redirects,
            'total_warning' => $total_warning,
            'total_broken' => $total_broken,
            'total_timeout' => $total_timeout,
            'total_ignored' => $total_ignored
        ];
    }

    public function filter($search_mode, $data = []) {
        return array_filter($data, function($item) use ($search_mode) {
            if (!in_array($search_mode, ['IGNORED', 'ALL']) && !empty($item['is_dismissed'])) {
                return false;
            }

            switch ($search_mode) {
                case 'BROKEN':
                    return !empty($item['is_broken']);
                case 'REDIRECTS':
                    return !empty($item['final_url']) 
                        && empty($item['is_timeout']) 
                        && $item['status_code'] === 200 
                        && $item['url'] !== $item['final_url'];
                case 'WARNING':
                    return !empty($item['is_warning']);
                case 'IGNORED':
                    return !empty($item['is_dismissed']);
                case 'TIMEOUT':
                    return !empty($item['is_timeout']);
                default:
                    return !($item['status_code'] === 200 && $item['url'] === $item['final_url']);
            }
        });
    }

    protected function filterByMode($item, $query) {}

    private function getCountByCondition($queryBuilder, $condition, $value) {
        if ($condition === 'is_dismissed') {
            return (clone $queryBuilder)
                ->where($condition, $value)
                ->selectCount('id')
                ->getVar();
        }

        return (clone $queryBuilder)
            ->where('is_dismissed', 0)
            ->where($condition, $value)
            ->selectCount('id')
            ->getVar();
    }
}
