<?php

namespace App\Http\Controllers;

use App\Models\UserDetail;
use Illuminate\Http\Request;
use Inertia\Inertia;

class CompanyController extends Controller
{
    public function index(Request $request)
    {
        $search = $request->input('search');
        $minEmployees = $request->input('min_employees');
        $maxEmployees = $request->input('max_employees');
        $minRating = $request->input('min_rating');
        $establishedYearFrom = $request->input('established_year_from');
        $establishedYearTo = $request->input('established_year_to');
        $technologies = $request->input('technologies', []);
        $tags = $request->input('tags', []);
        $hasN1Japanese = $request->input('has_n1_japanese');
        $perPage = $request->input('per_page', 12);

        // Build base query for approved companies only
        $query = UserDetail::query()
            ->where('status', UserDetail::STATUS_APPROVED)
            ->whereNotNull('company_short_name');

        // Apply search filter
        if ($search) {
            $query->where(function ($q) use ($search) {
                $q->where('company_short_name', 'like', "%{$search}%")
                    ->orWhere('company_full_name', 'like', "%{$search}%")
                    ->orWhere('company_description', 'like', "%{$search}%");
            });
        }

        // Apply filters
        if ($minEmployees) {
            $query->where('employee_count', '>=', $minEmployees);
        }
        if ($maxEmployees) {
            $query->where('employee_count', '<=', $maxEmployees);
        }
        if ($minRating) {
            $query->where('rating', '>=', $minRating);
        }
        if ($establishedYearFrom) {
            $query->where('established_year', '>=', $establishedYearFrom);
        }
        if ($establishedYearTo) {
            $query->where('established_year', '<=', $establishedYearTo);
        }
        if ($hasN1Japanese) {
            $query->where('n1_japanese_count', '>', 0);
        }

        // Get all companies first, then filter in PHP for better control
        $companies = $query->orderBy('rating', 'desc')
            ->orderBy('created_at', 'desc')
            ->get();

        // Apply technology and tag filters in PHP
        if (! empty($technologies) || ! empty($tags)) {
            \Log::info('Filter: Applying PHP filters', [
                'technologies' => $technologies,
                'tags'         => $tags,
            ]);

            $companies = $companies->filter(function ($company) use ($technologies, $tags) {
                $matchesTech = empty($technologies);
                $matchesTags = empty($tags);

                // Check technologies
                if (! empty($technologies) && $company->key_technologies) {
                    $companyTechs = is_array($company->key_technologies)
                        ? $company->key_technologies
                        : json_decode($company->key_technologies, true) ?? [];

                    foreach ($technologies as $tech) {
                        if (in_array($tech, $companyTechs)) {
                            $matchesTech = true;
                            break;
                        }
                    }
                }

                // Check tags
                if (! empty($tags) && $company->tags) {
                    $companyTags = is_array($company->tags)
                        ? $company->tags
                        : json_decode($company->tags, true) ?? [];

                    foreach ($tags as $tag) {
                        if (in_array($tag, $companyTags)) {
                            $matchesTags = true;
                            break;
                        }
                    }
                }

                return $matchesTech && $matchesTags;
            });
        }

        // Paginate the filtered results
        $currentPage = request()->get('page', 1);
        $perPage = $perPage;
        $total = $companies->count();
        $offset = ($currentPage - 1) * $perPage;
        $paginatedCompanies = $companies->slice($offset, $perPage)->values();

        // Create manual paginator
        $companies = new \Illuminate\Pagination\LengthAwarePaginator(
            $paginatedCompanies,
            $total,
            $perPage,
            $currentPage,
            ['path' => request()->url(), 'pageName' => 'page']
        );

        // Preserve query parameters in pagination links
        $companies->appends(request()->query());

        \Log::info('Filter: Query result count', ['total' => $companies->total()]);

        // Get filter options dynamically from current results
        $allCompanies = UserDetail::where('status', UserDetail::STATUS_APPROVED)
            ->whereNotNull('company_short_name')
            ->get();

        // Extract unique values for filters with counts
        $technologyCounts = collect();
        $tagCounts = collect();
        $employeeRanges = [];
        $establishedYears = [];

        foreach ($allCompanies as $company) {
            // Parse JSON strings for technologies
            if ($company->key_technologies) {
                $companyTechnologies = is_array($company->key_technologies)
                    ? $company->key_technologies
                    : json_decode($company->key_technologies, true) ?? [];

                foreach ($companyTechnologies as $tech) {
                    $technologyCounts[$tech] = ($technologyCounts[$tech] ?? 0) + 1;
                }
            }

            // Parse JSON strings for tags
            if ($company->tags) {
                $companyTags = is_array($company->tags)
                    ? $company->tags
                    : json_decode($company->tags, true) ?? [];

                foreach ($companyTags as $tag) {
                    $tagCounts[$tag] = ($tagCounts[$tag] ?? 0) + 1;
                }
            }

            if ($company->employee_count) {
                $employeeRanges[] = $company->employee_count;
            }
            if ($company->established_year) {
                $establishedYears[] = $company->established_year;
            }
        }

        $filterOptions = [
            'technologies' => $technologyCounts->map(function ($count, $tech) {
                return ['name' => $tech, 'count' => $count];
            })->values()->toArray(),
            'tags' => $tagCounts->map(function ($count, $tag) {
                return ['name' => $tag, 'count' => $count];
            })->values()->toArray(),
            'employee_count_range' => [
                'min' => ! empty($employeeRanges) ? min($employeeRanges) : 0,
                'max' => ! empty($employeeRanges) ? max($employeeRanges) : 1000,
            ],
            'established_year_range' => [
                'min' => ! empty($establishedYears) ? min($establishedYears) : 2000,
                'max' => ! empty($establishedYears) ? max($establishedYears) : date('Y'),
            ],
        ];

        $appliedFilters = [
            'search'                => $search ?: '',
            'min_employees'         => $minEmployees ?: null,
            'max_employees'         => $maxEmployees ?: null,
            'min_rating'            => $minRating ?: null,
            'established_year_from' => $establishedYearFrom ?: null,
            'established_year_to'   => $establishedYearTo ?: null,
            'technologies'          => $technologies, // Only pass actual filter values, not empty array
            'tags'                  => $tags, // Only pass actual filter values, not empty array
            'has_n1_japanese'       => $hasN1Japanese ?: false,
            'per_page'              => $perPage ?: 12,
        ];

        return Inertia::render('mattock/Company', [
            'companies'      => $companies,
            'filterOptions'  => $filterOptions,
            'appliedFilters' => $appliedFilters,
        ]);
    }

    public function show($id)
    {
        $company = UserDetail::with(['user'])
            ->where('id', $id)
            ->where('status', UserDetail::STATUS_APPROVED)
            ->firstOrFail();

        // Get related companies
        $relatedCompanies = $this->getRelatedCompanies($company);

        return Inertia::render('mattock/CompanyDetail', [
            'company'          => $company,
            'relatedCompanies' => $relatedCompanies,
        ]);
    }

    /**
     * Get 3 related companies based on technologies, tags, and employee count
     */
    private function getRelatedCompanies($currentCompany)
    {
        // Parse current company's technologies and tags
        $currentTechnologies = is_array($currentCompany->key_technologies)
            ? $currentCompany->key_technologies
            : json_decode($currentCompany->key_technologies, true) ?? [];

        $currentTags = is_array($currentCompany->tags)
            ? $currentCompany->tags
            : json_decode($currentCompany->tags, true) ?? [];

        // Get all other approved companies
        $companies = UserDetail::where('id', '!=', $currentCompany->id)
            ->where('status', UserDetail::STATUS_APPROVED)
            ->get();

        // Calculate similarity scores
        $scoredCompanies = $companies->map(function ($company) use ($currentTechnologies, $currentTags, $currentCompany) {
            $companyTechs = is_array($company->key_technologies)
                ? $company->key_technologies
                : json_decode($company->key_technologies, true) ?? [];

            $companyTags = is_array($company->tags)
                ? $company->tags
                : json_decode($company->tags, true) ?? [];

            $score = 0;

            // Technology similarity (highest priority) - 50 points max
            $techMatches = count(array_intersect($currentTechnologies, $companyTechs));
            if (count($currentTechnologies) > 0) {
                $score += ($techMatches / count($currentTechnologies)) * 50;
            }

            // Tag similarity (medium priority) - 30 points max
            $tagMatches = count(array_intersect($currentTags, $companyTags));
            if (count($currentTags) > 0) {
                $score += ($tagMatches / count($currentTags)) * 30;
            }

            // Employee count similarity (lower priority) - 20 points max
            if ($currentCompany->employee_count && $company->employee_count) {
                $employeeDiff = abs($currentCompany->employee_count - $company->employee_count);
                $maxEmployees = max($currentCompany->employee_count, $company->employee_count);
                $employeeSimilarity = 1 - ($employeeDiff / $maxEmployees);
                $score += $employeeSimilarity * 20;
            }

            $company->similarity_score = $score;

            return $company;
        });

        // Sort by similarity score and return top 3
        return $scoredCompanies
            ->sortByDesc('similarity_score')
            ->take(3)
            ->values()
            ->toArray();
    }
}
