<?php

namespace App\Services;

use App\Models\Artwork;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;

/**
 * @deprecated LegacyService contains helpers to render legacy pages and should be
 * migrated to new services. Keep in place until legacy controllers/views
 * are refactored. Instantiating the service will emit a deprecation log.
 */
class LegacyService
{
    public function __construct()
    {
        Log::warning('App\Services\LegacyService is deprecated. Please migrate callers to modern services.');
    }
    public function featured(): array
    {
        $featured = null;
        $memberFeatured = null;

            try {
                $featured = DB::table('featured_works as fw')
                ->leftJoin('wallz as w', 'fw.artwork_id', '=', 'w.id')
                ->leftJoin('users as u', 'w.user_id', '=', 'u.user_id')
                ->select('w.id', 'w.name', 'w.picture', 'u.uname', 'fw.post_date')
                ->orderByDesc('fw.post_date')
                ->first();

            $memberFeatured = DB::table('users_opinions as o')
                ->leftJoin('wallz as w', 'o.artwork_id', '=', 'w.id')
                ->leftJoin('users as u', 'w.user_id', '=', 'u.user_id')
                ->select(DB::raw('COUNT(*) AS votes'), 'w.id', 'w.name', 'w.picture', 'u.uname')
                ->whereRaw('o.post_date > SUBDATE(CURRENT_DATE(), INTERVAL 30 DAY)')
                ->where('o.score', 4)
                ->groupBy('o.artwork_id', 'w.id', 'w.name', 'w.picture', 'u.uname')
                ->orderByDesc('votes')
                ->limit(1)
                ->first();
        } catch (\Throwable $e) {
            // fail soft
        }

        if (!$featured) {
            $featured = (object) [
                'id' => 0,
                'name' => 'Featured Artwork',
                'picture' => 'https://files.skinbase.org/default/missing_md.webp',
                'uname' => 'Skinbase',
            ];
        }

        if (!$memberFeatured) {
            $memberFeatured = (object) [
                'id' => 0,
                'name' => 'Members Pick',
                'picture' => 'https://files.skinbase.org/default/missing_md.webp',
                'uname' => 'Skinbase',
                'votes' => 0,
            ];
        }

        return [$featured, $memberFeatured];
    }

    public function latestUploads(): array
    {
        $uploads = [];

        $cachePath = base_path('oldSite/www/cache/latest_uploads.json');
        if (File::exists($cachePath)) {
            $json = File::get($cachePath);
            $uploads = json_decode($json, true) ?: [];
        }

        if (empty($uploads)) {
            try {
                $uploads = DB::table('wallz as w')
                    ->leftJoin('users as u', 'w.user_id', '=', 'u.user_id')
                    ->leftJoin('categories as c', 'w.category', '=', 'c.id')
                    ->where('w.approved', 1)
                    ->orderByDesc('w.datum')
                    ->limit(20)
                    ->get()
                    ->map(function ($row) {
                        return [
                            'id' => $row->id,
                            'name' => $row->name,
                            'picture' => $row->picture,
                            'uname' => $row->uname,
                            'category_name' => $row->category_name ?? $row->name ?? '',
                        ];
                    })
                    ->toArray();
            } catch (\Throwable $e) {
                $uploads = [];
            }
        }

        if (empty($uploads)) {
            $uploads = [
                [
                    'id' => 1,
                    'name' => 'Sample Artwork',
                    'picture' => 'https://files.skinbase.org/default/missing_md.webp',
                    'uname' => 'Skinbase',
                    'category_name' => 'Photography',
                ],
            ];
        }

        return $uploads;
    }

    public function forumNews(): array
    {
            try {
            return DB::table('forum_threads as t1')
                ->leftJoin('users as t2', 't1.user_id', '=', 't2.id')
                ->leftJoin('forum_categories as c', 't1.category_id', '=', 'c.id')
                ->selectRaw('t1.id as topic_id, t1.title as topic, t1.views, t1.created_at as post_date, t1.content as preview, COALESCE(t2.name, ?) as uname', ['Unknown'])
                ->whereNull('t1.deleted_at')
                ->where(function ($query) {
                    $query->where('t1.category_id', 2876)
                        ->orWhereIn('c.slug', ['news', 'forum-news']);
                })
                ->orderByDesc('t1.created_at')
                ->limit(8)
                ->get()
                ->toArray();
        } catch (\Throwable $e) {
            return [];
        }
    }

    public function ourNews(): array
    {
        try {
            return DB::table('news as t1')
                ->join('news_categories as t2', 't1.category_id', '=', 't2.category_id')
                ->join('users as t3', 't1.user_id', '=', 't3.user_id')
                ->select(
                    't1.news_id',
                    't1.headline',
                    't1.picture',
                    't1.preview',
                    't1.create_date',
                    't1.views',
                    't2.category_name',
                    't3.uname',
                    DB::raw('(SELECT COUNT(*) FROM news_comment WHERE news_id = t1.news_id) AS num_comments')
                )
                ->orderByDesc('t1.create_date')
                ->limit(5)
                ->get()
                ->toArray();
        } catch (\Throwable $e) {
            return [];
        }
    }

    public function latestForumActivity(): array
    {
        try {
            return DB::table('forum_threads as t1')
                ->leftJoin('forum_categories as c', 't1.category_id', '=', 'c.id')
                ->leftJoin('forum_posts as p', function ($join) {
                    $join->on('p.thread_id', '=', 't1.id')
                        ->whereNull('p.deleted_at');
                })
                ->selectRaw('t1.id as topic_id, t1.title as topic, COUNT(p.id) AS numPosts')
                ->whereNull('t1.deleted_at')
                ->where(function ($query) {
                    $query->where('t1.category_id', '<>', 2876)
                        ->orWhereNull('t1.category_id');
                })
                ->where(function ($query) {
                    $query->whereNull('c.slug')
                        ->orWhereNotIn('c.slug', ['news', 'forum-news']);
                })
                ->groupBy('t1.id', 't1.title')
                ->orderByDesc('t1.last_post_at')
                ->orderByDesc('t1.created_at')
                ->limit(10)
                ->get()
                ->toArray();
        } catch (\Throwable $e) {
            return [];
        }
    }

    public function browseGallery(int $perPage = 50)
    {
            try {
            return DB::table('wallz as w')
                ->leftJoin('categories as c', 'w.category', '=', 'c.id')
                ->leftJoin('users as u', 'w.user_id', '=', 'u.user_id')
                ->select('w.id', 'w.name', 'w.picture', 'w.category', 'w.datum', DB::raw('c.name as category_name'), 'u.uname')
                ->where('w.approved', 1)
                ->where('w.public', 'Y')
                ->orderByDesc('w.datum')
                ->paginate($perPage)
                ->withQueryString();
        } catch (\Throwable $e) {
            return null;
        }
    }

    public function categoryPage(string $group, ?string $slug = null, ?int $id = null)
    {
        $group = \Illuminate\Support\Str::title($group);
        $defaults = [
            'Skins' => 1,
            'Wallpapers' => 2,
            'Photography' => 3,
            'Other' => 4,
        ];

        if (!$id && $slug && ctype_digit($slug)) {
            $id = (int) $slug;
        }

        $id = $id ?: ($defaults[$group] ?? null);
        if (!$id || $id < 1) {
            return null;
        }

        try {
            $category = DB::table('categories')
                ->select(DB::raw('id as category_id'), DB::raw('name as category_name'), 'description', DB::raw('parent_id as rootid'), DB::raw('content_type_id as section_id'))
                ->where('id', $id)
                ->first();
        } catch (\Throwable $e) {
            $category = null;
        }

        if (! $category) {
            return null;
        }

        $perPage = 40;

            try {
            $base = DB::table('wallz as t1')
                ->select('t1.id', 't1.name', 't1.picture', 't3.uname', 't1.category', DB::raw('t2.name as category_name'))
                ->join('categories as t2', 't1.category', '=', 't2.id')
                ->leftJoin('users as t3', 't1.user_id', '=', 't3.user_id')
                ->where('t1.approved', 1)
                ->where(function ($q) use ($id, $category) {
                    $q->where('t1.category', (int) $id);
                    if ($category->rootid > 0) {
                        $q->orWhere('t1.rootid', (int) $id);
                    }
                })
                ->orderByDesc('t1.datum');

            $artworks = $base->paginate($perPage)->withQueryString();

            if ($artworks && method_exists($artworks, 'getCollection')) {
                $artworks->getCollection()->transform(function ($row) {
                    $row->gid_num = ((int) ($row->category ?? 0) % 5) * 5;
                    if (!empty($row->picture)) {
                        $ext = self::fileExtension($row->picture);
                        $encoded = self::encode($row->id);
                        $row->ext = $ext;
                        $row->encoded = $encoded;
                        // Prefer new files.skinbase.org when possible
                        try {
                            $art = Artwork::find($row->id);
                            $present = \App\Services\ThumbnailPresenter::present($art ?: (array) $row, 'md');
                            $row->thumb_url = $present['url'];
                            $row->thumb_srcset = $present['srcset'];
                        } catch (\Throwable $e) {
                            $present = \App\Services\ThumbnailPresenter::present((array) $row, 'md');
                            $row->thumb_url = $present['url'];
                            $row->thumb_srcset = $present['srcset'];
                        }
                    } else {
                        $row->ext = null;
                        $row->encoded = null;
                        $row->thumb_url = 'https://files.skinbase.org/default/missing_md.webp';
                        $row->thumb_srcset = null;
                    }

                    return $row;
                });
            }
        } catch (\Throwable $e) {
            $artworks = null;
        }

            try {
                $subcategories = DB::table('categories')
                ->select(DB::raw('id as category_id'), DB::raw('name as category_name'))
                ->where('parent_id', $id)
                ->orderBy('category_name')
                ->get();

                if ($subcategories->isEmpty() && $category->rootid) {
                $subcategories = DB::table('categories')
                    ->select(DB::raw('id as category_id'), DB::raw('name as category_name'))
                    ->where('parent_id', $category->rootid)
                    ->orderBy('category_name')
                    ->get();
            }

                if ($subcategories->isEmpty()) {
                $subcategories = DB::table('skupine')
                    ->select('category_id', 'category_name')
                    ->where('rootid', $id)
                    ->orderBy('category_name')
                    ->get();
            }
        } catch (\Throwable $e) {
            try {
                $subcategories = DB::table('skupine')
                    ->select('category_id', 'category_name')
                    ->where('rootid', $id)
                    ->orderBy('category_name')
                    ->get();
            } catch (\Throwable $e2) {
                $subcategories = collect();
            }
        }

        $page_title = $group;
        $page_meta_description = $group . ' artworks on Skinbase';
        $page_meta_keywords = strtolower($group) . ', skinbase, artworks, wallpapers, skins';

        return [
            'group' => $group,
            'category' => $category,
            'artworks' => $artworks,
            'subcategories' => $subcategories,
            'page_title' => $page_title,
            'page_meta_description' => $page_meta_description,
            'page_meta_keywords' => $page_meta_keywords,
        ];
    }

    public function browseCategories()
    {
        try {
            $categories = DB::table('categories')
                ->select(DB::raw('id as category_id'), DB::raw('name as category_name'), 'description')
                ->where('content_type_id', 0)
                ->where(DB::raw('parent_id'), 0)
                ->orderBy('id')
                ->get();

            if ($categories->isEmpty()) {
                $categories = DB::table('skupine')
                    ->select('category_id', 'category_name', 'description')
                    ->where('section_id', 0)
                    ->where('rootid', 0)
                    ->orderBy('category_id')
                    ->get();
            }
        } catch (\Throwable $e) {
            try {
                $categories = DB::table('skupine')
                    ->select('category_id', 'category_name', 'description')
                    ->where('section_id', 0)
                    ->where('rootid', 0)
                    ->orderBy('category_id')
                    ->get();
            } catch (\Throwable $e2) {
                $categories = collect();
            }
        }

        $subgroups = collect();
        if ($categories->isNotEmpty()) {
            $ids = $categories->pluck('category_id')->unique()->values()->all();
            try {
                $subs = DB::table('categories')
                    ->select(DB::raw('id as category_id'), DB::raw('name as category_name'), 'image as picture', DB::raw('content_type_id as section_id'))
                    ->whereIn('content_type_id', $ids)
                    ->orderBy('category_name')
                    ->get();

                if ($subs->isEmpty()) {
                    $subs = DB::table('skupine')
                        ->select('category_id', 'category_name', 'picture', 'section_id')
                        ->whereIn('section_id', $ids)
                        ->orderBy('category_name')
                        ->get();
                }

                $subgroups = $subs->groupBy('section_id');
            } catch (\Throwable $e) {
                $subgroups = collect();
            }
        }

        return [
            'categories' => $categories,
            'subgroups' => $subgroups,
            'page_title' => 'Browse Categories',
            'page_meta_description' => 'Browse categories across Photography, Wallpapers, Skins and more on Skinbase.',
            'page_meta_keywords' => 'categories, photography, wallpapers, skins, browse',
        ];
    }

    /**
     * Fetch a single artwork by id with author and category
     * Returns null on failure.
     */
    public function getArtwork(int $id)
    {
        try {
            $row = DB::table('wallz as w')
                ->leftJoin('users as u', 'w.user_id', '=', 'u.user_id')
                ->leftJoin('categories as c', 'w.category', '=', 'c.id')
                ->select('w.*', 'u.uname', DB::raw('c.name as category_name'))
                ->where('w.id', $id)
                ->first();
        } catch (\Throwable $e) {
            $row = null;
        }

        if (! $row) {
            return null;
        }

        // compute thumbnail/zoom paths similar to legacy code
        $nid = (int) ($row->id / 100);
        $nid_new = (int) ($row->id / 1000);
        $encoded = self::encode($row->id);
        $ext = self::fileExtension($row->picture ?? 'jpg');

        $appUrl = rtrim(config('app.url', ''), '/');
        $shot_name = $appUrl . '/files/archive/shots/' . $nid . '/' . ($row->picture ?? '');
        $zoom_name = $appUrl . '/files/archive/zoom/' . $nid . '/' . ($row->picture ?? '');
        $thumb_600 = $appUrl . '/files/thumb/' . $nid_new . '/600_' . $row->id . '.jpg';
        // Prefer new CDN when possible
        try {
            $art = Artwork::find($row->id);
            $present = \App\Services\ThumbnailPresenter::present($art ?: (array) $row, 'md');
            $thumb_file = $present['url'];
            $thumb_file_300 = $present['srcset'] ? explode(' ', explode(',', $present['srcset'])[0])[0] : ($present['url'] ?? null);
        } catch (\Throwable $e) {
            $present = \App\Services\ThumbnailPresenter::present((array) $row, 'md');
            $thumb_file = $present['url'];
            $thumb_file_300 = $present['srcset'] ? explode(' ', explode(',', $present['srcset'])[0])[0] : ($present['url'] ?? null);
        }

        // additional stats (best-effort)
        try {
            $num_downloads = DB::table('artworks_downloads')
                ->where('date', DB::raw('CURRENT_DATE'))
                ->where('artwork_id', $row->id)
                ->count();
        } catch (\Throwable $e) {
            $num_downloads = 0;
        }

        try {
            $monthly_downloads = DB::table('monthly_downloads')
                ->where('fname', $row->id)
                ->count();
        } catch (\Throwable $e) {
            $monthly_downloads = 0;
        }

        try {
            $num_comments = DB::table('artwork_comments')
                ->where('name', $row->id)
                ->where('author', '<>', '')
                ->count();
        } catch (\Throwable $e) {
            $num_comments = 0;
        }

        try {
            $num_favourites = DB::table('favourites')
                ->where('artwork_id', $row->id)
                ->count();
        } catch (\Throwable $e) {
            $num_favourites = 0;
        }

        try {
            $featured = DB::table('featured_works')
                ->where('rootid', $row->rootid ?? 0)
                ->where('artwork_id', $row->id)
                ->orderByDesc('type')
                ->select('type', 'post_date')
                ->first();
            $featured_type = $featured->type ?? 0;
            $featured_date = $featured->post_date ?? null;
        } catch (\Throwable $e) {
            $featured_type = 0;
            $featured_date = null;
        }

        $page_title = $row->name ?? 'Artwork';
        $page_meta_description = strip_tags($row->description ?? ($row->preview ?? ''));
        $page_meta_keywords = trim(($row->category_name ?? '') . ', artwork');

        return [
            'artwork' => $row,
            'thumb_file' => $thumb_file,
            'thumb_file_300' => $thumb_file_300,
            'thumb_600' => $thumb_600,
            'shot_name' => $shot_name,
            'zoom_name' => $zoom_name,
            'num_downloads' => $num_downloads,
            'monthly_downloads' => $monthly_downloads,
            'num_comments' => $num_comments,
            'num_favourites' => $num_favourites,
            'featured_type' => $featured_type,
            'featured_date' => $featured_date,
            'page_title' => $page_title,
            'page_meta_description' => $page_meta_description,
            'page_meta_keywords' => $page_meta_keywords,
        ];
    }

    public static function encode($val, $base = 62, $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
        $str = '';
        if ($val < 0) return $str;
        do {
            $i = $val % $base;
            $str = $chars[$i] . $str;
            $val = ($val - $i) / $base;
        } while ($val > 0);
        return $str;
    }

    private static function fileExtension($filename) {
        $parts = pathinfo($filename);
        return $parts['extension'] ?? 'jpg';
    }
}
