<?php

namespace App\Http\Controllers;

use App\Models\Task;
use App\Models\Company;
use App\Models\User;
use App\Models\Organization;
use App\Models\CompanyOrganizationStatus;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\StreamedResponse;

class PanelController extends Controller
{
    // Predefined lists matching the WinForms application categories and countries
    private function getPredefinedData()
    {
        return [
            'categories' => [
                "💼 FİNANS SEKTÖRÜ (Tüm Finans ve Alt Kolları)",
                "💻 BİLİŞİM & TEKNOLOJİ (Yazılım, Telekom ve Dijital)",
                "🩺 SAĞLIK & MEDİKAL (Klinikler, Hastaneler ve Depolar)",
                "🏗️ İNŞAAT & EMLAK (Yapı, Gayrimenkul ve Mimarlık)",
                "🌾 TARIM & GIDA (Üretim, Toptancılar ve Hayvancılık)",
                "🏭 SANAYİ & AĞIR İMALAT (Fabrikalar ve Atölyeler)",
                "👔 TEKSTİL, MODA & MAĞAZACILIK",
                "🚗 OTOMOTİV & LOJİSTİK (Servis, Kiralama ve Nakliyat)",
                "🍽️ HİZMET, TURİZM & ORGANİZASYON"
            ],
            'countries' => [
                'Türkiye' => ["Tüm Türkiye (81 İl - Sırayla)", "Istanbul", "Ankara", "Izmir", "Bursa", "Antalya", "Adana", "Gaziantep", "Konya", "Mersin", "Kayseri", "Diyarbakır", "Eskişehir", "Samsun", "Denizli", "Şanlıurfa"],
                'Almanya' => ["Berlin", "Münih", "Frankfurt", "Hamburg", "Stuttgart", "Köln", "Düsseldorf", "Dortmund"],
                'Amerika Birleşik Devletleri' => ["New York", "Miami", "Los Angeles", "Chicago", "Houston", "San Francisco", "Washington D.C.", "Boston", "Seattle", "Dallas"],
                'United Kingdom (İngiltere)' => ["Londra", "Manchester", "Birmingham", "Liverpool", "Leeds", "Glasgow", "Edinburgh"],
                'Birleşik Arap Emirlikleri' => ["Dubai", "Abu Dabi", "Şarika", "Acman", "Al Ain"],
                'Azerbaycan' => ["Bakü", "Gence", "Sumgayıt", "Mingeçevir", "Lankaran"],
                'Fransa' => ["Paris", "Lyon", "Marsilya", "Nice", "Toulouse", "Bordeaux"],
                'İtalya' => ["Roma", "Milano", "Napoli", "Torino", "Palermo", "Cenova"],
                'İspanya' => ["Madrid", "Barselona", "Valensiya", "Sevilla", "Malaga"],
                'Hollanda' => ["Amsterdam", "Rotterdam", "Lahey", "Utrecht", "Eindhoven"],
                'Rusya' => ["Moskova", "St. Petersburg", "Novosibirsk", "Yekaterinburg"],
                'Ukrayna' => ["Kiev", "Harkiv", "Odessa", "Dnipro", "Lviv"]
            ]
        ];
    }

    public function landing()
    {
        return view('landing');
    }

    public function dashboard()
    {
        $user = auth()->user();

        if ($user->role === 'admin') {
            $stats = [
                'total_tasks' => Task::count(),
                'total_companies' => Company::count(),
                'pending_tasks' => Task::where('status', 'pending')->count(),
                'active_tasks' => Task::where('status', 'processing')->count(),
                'completed_tasks' => Task::where('status', 'completed')->count(),
            ];

            $recentTasks = Task::orderBy('created_at', 'desc')->take(10)->get();
            $recentCompanies = Company::with('organizationStatuses')->orderBy('created_at', 'desc')->take(10)->get();
        } else {
            $orgId = $user->organization_id;
            
            if ($orgId) {
                $taskQuery = Task::whereHas('user', function($q) use ($orgId) {
                    $q->where('organization_id', $orgId);
                });
                
                $companyQuery = Company::whereHas('tasks.user', function($q) use ($orgId) {
                    $q->where('organization_id', $orgId);
                });
            } else {
                $taskQuery = Task::where('user_id', $user->id);
                $companyQuery = Company::whereHas('tasks', function($q) use ($user) {
                    $q->where('user_id', $user->id);
                });
            }

            $stats = [
                'total_tasks' => (clone $taskQuery)->count(),
                'total_companies' => (clone $companyQuery)->count(),
                'pending_tasks' => (clone $taskQuery)->where('status', 'pending')->count(),
                'active_tasks' => (clone $taskQuery)->where('status', 'processing')->count(),
                'completed_tasks' => (clone $taskQuery)->where('status', 'completed')->count(),
            ];

            $recentTasks = (clone $taskQuery)->orderBy('created_at', 'desc')->take(10)->get();
            $recentCompanies = (clone $companyQuery)->with(['organizationStatuses' => function($q) use ($orgId) {
                $q->where('organization_id', $orgId);
            }])->orderBy('created_at', 'desc')->take(10)->get();
        }

        $data = $this->getPredefinedData();

        return view('dashboard', compact('stats', 'recentTasks', 'recentCompanies', 'data'));
    }

    public function createTask(Request $request)
    {
        $request->validate([
            'country' => 'required|string',
            'city' => 'required|string',
            'category' => 'required|string',
            'total_target' => 'required|integer|min:0|max:2147483647',
        ]);

        $city = $request->input('city');

        if ($city === "Tüm Türkiye (81 İl - Sırayla)") {
            $turkeyCities = [
                "Adana", "Adıyaman", "Afyonkarahisar", "Ağrı", "Amasya", "Ankara", "Antalya", "Artvin",
                "Aydın", "Balıkesir", "Bilecik", "Bingöl", "Bitlis", "Bolu", "Burdur", "Bursa",
                "Çanakkale", "Çankırı", "Çorum", "Denizli", "Diyarbakır", "Edirne", "Elazığ", "Erzincan",
                "Erzurum", "Eskişehir", "Gaziantep", "Giresun", "Gümüşhane", "Hakkari", "Hatay", "Isparta",
                "Mersin", "İstanbul", "İzmir", "Kars", "Kastamonu", "Kayseri", "Kırklareli", "Kırşehir",
                "Kocaeli", "Konya", "Kütahya", "Malatya", "Manisa", "Kahramanmaraş", "Mardin", "Muğla",
                "Muş", "Nevşehir", "Niğde", "Ordu", "Rize", "Sakarya", "Samsun", "Siirt",
                "Sinop", "Sivas", "Tekirdağ", "Tokat", "Trabzon", "Tunceli", "Şanlıurfa", "Uşak",
                "Van", "Yozgat", "Zonguldak", "Aksaray", "Bayburt", "Karaman", "Kırıkkale", "Batman",
                "Şırnak", "Bartın", "Ardahan", "Iğdır", "Yalova", "Karabük", "Kilis", "Osmaniye",
                "Düzce"
            ];

            foreach ($turkeyCities as $cityName) {
                Task::create([
                    'user_id' => auth()->id(),
                    'country' => 'Türkiye',
                    'city' => $cityName,
                    'category' => $request->input('category'),
                    'total_target' => $request->input('total_target'),
                    'status' => 'pending',
                ]);
            }

            return redirect()->route('dashboard')->with('success', '81 il için tarama görevleri başarıyla sıraya eklendi. Sırayla taranacaktır.');
        }

        Task::create([
            'user_id' => auth()->id(),
            'country' => $request->input('country'),
            'city' => $city,
            'category' => $request->input('category'),
            'total_target' => $request->input('total_target'),
            'status' => 'pending',
        ]);

        return redirect()->route('dashboard')->with('success', 'Görev başarıyla sıraya eklendi.');
    }

    public function deleteTask($id)
    {
        $task = Task::findOrFail($id);
        
        // Policy check
        if (auth()->user()->role !== 'admin' && $task->user_id !== auth()->id()) {
            abort(403, 'Bu görevi silme yetkiniz yok.');
        }

        $task->delete();

        return redirect()->route('dashboard')->with('success', 'Görev başarıyla silindi.');
    }

    public function restartTask($id)
    {
        $task = Task::findOrFail($id);

        // Policy check
        if (auth()->user()->role !== 'admin' && $task->user_id !== auth()->id()) {
            abort(403, 'Bu görevi yeniden başlatma yetkiniz yok.');
        }

        $task->update(['status' => 'pending']);

        return redirect()->route('dashboard')->with('success', 'Görev yeniden başlatıldı ve sıraya alındı.');
    }

    public function simulateTask($id)
    {
        $task = Task::findOrFail($id);

        // Policy check
        if (auth()->user()->role !== 'admin' && $task->user_id !== auth()->id()) {
            abort(403, 'Bu görevi simüle etme yetkiniz yok.');
        }

        // Reset to initial processing simulation state with limitless target
        $task->update([
            'status' => 'processing',
            'progress' => 0,
            'scraped_count' => 0,
            'total_target' => 9999, // Represent limitless scraping
        ]);

        return redirect()->route('dashboard')->with('success', 'Sınırsız tarama simülasyonu başlatıldı! İstediğiniz zaman Durdur butonuna basabilirsiniz.');
    }

    public function stopTask($id)
    {
        $task = Task::findOrFail($id);

        // Policy check
        if (auth()->user()->role !== 'admin' && $task->user_id !== auth()->id()) {
            abort(403, 'Bu görevi durdurma yetkiniz yok.');
        }

        // Mark task as completed
        $task->update([
            'status' => 'completed',
            'progress' => 100
        ]);

        return redirect()->route('dashboard')->with('success', 'Tarama başarıyla durduruldu. Toplanan tüm veriler kaydedildi!');
    }

    public function getTaskStatuses(Request $request)
    {
        $user = auth()->user();
        if ($user->role === 'admin') {
            $tasks = Task::orderBy('created_at', 'desc')->get();
        } else {
            $orgId = $user->organization_id;
            if ($orgId) {
                $tasks = Task::whereHas('user', function($q) use ($orgId) {
                    $q->where('organization_id', $orgId);
                })->orderBy('created_at', 'desc')->get();
            } else {
                $tasks = Task::where('user_id', $user->id)->orderBy('created_at', 'desc')->get();
            }
        }

        return response()->json([
            'status' => 'success',
            'tasks' => $tasks
        ]);
    }

    public function updateTaskProgress(Request $request, $id)
    {
        $task = Task::findOrFail($id);

        // Policy check
        if (auth()->user()->role !== 'admin' && $task->user_id !== auth()->id()) {
            return response()->json(['status' => 'error', 'message' => 'Unauthorized'], 403);
        }

        $request->validate([
            'progress' => 'required|integer|min:0|max:100',
            'scraped_count' => 'required|integer|min:0',
            'total_target' => 'required|integer|min:1',
            'status' => 'nullable|string'
        ]);

        $newScraped = $request->input('scraped_count');
        $oldScraped = $task->scraped_count;

        $updates = [
            'progress' => $request->input('progress'),
            'scraped_count' => $newScraped,
            'total_target' => $request->input('total_target'),
        ];

        if ($request->filled('status')) {
            $updates['status'] = $request->input('status');
        }

        // Live incremental generation of mock companies as count increases!
        if ($newScraped > $oldScraped && $task->status === 'processing') {
            $diff = $newScraped - $oldScraped;

            // Clean category name for business naming
            $categoryClean = preg_replace('/[^\p{L}\p{N}\s]/u', '', $task->category); // Remove emojis
            $categoryClean = trim(preg_replace('/\s+/', ' ', $categoryClean));
            $words = explode(' ', $categoryClean);
            $sectorName = $words[0] ?? 'Hizmet';
            if (count($words) > 1 && (str_contains($words[0], 'SEKTÖR') || mb_strlen($words[0]) < 3)) {
                $sectorName = $words[1];
            }
            $sectorName = mb_convert_case($sectorName, MB_CASE_TITLE, "UTF-8");

            for ($i = 0; $i < $diff; $i++) {
                $companyName = $task->city . ' ' . $sectorName . ' ' . ['A.Ş.', 'Limited', 'Grup', 'Ortaklığı', 'Merkezi'][rand(0, 4)] . ' ' . rand(100, 999);
                $slugName = strtolower(preg_replace('/[^a-zA-Z0-9]/', '', $companyName));
                
                $company = Company::create([
                    'name' => $companyName,
                    'phone' => '+90 212 ' . rand(100, 999) . ' ' . rand(10, 99) . ' ' . rand(10, 99),
                    'website' => 'https://www.' . $slugName . '.com',
                    'email' => 'contact@' . $slugName . '.com',
                    'instagram' => 'https://instagram.com/' . $slugName,
                    'facebook' => 'https://facebook.com/' . $slugName,
                    'city' => $task->city,
                    'country' => $task->country,
                    'category' => $task->category,
                ]);

                $company->tasks()->attach($task->id);
            }
        }

        if ($updates['progress'] === 100) {
            $updates['status'] = 'completed';
        }

        $task->update($updates);

        return response()->json([
            'status' => 'success',
            'task' => $task
        ]);
    }

    public function companies(Request $request)
    {
        $user = auth()->user();
        $orgId = $user->organization_id;
        
        if ($user->role === 'admin') {
            $query = Company::query();
        } else {
            if ($orgId) {
                $query = Company::whereHas('tasks.user', function($q) use ($orgId) {
                    $q->where('organization_id', $orgId);
                });
            } else {
                $query = Company::whereHas('tasks', function($q) use ($user) {
                    $q->where('user_id', $user->id);
                });
            }
        }

        // Eager load organization status for the current user's organization scope
        $query->with(['organizationStatuses' => function($q) use ($orgId) {
            $q->where('organization_id', $orgId);
        }]);

        // Scoped Stats based on call status (before search/filters)
        $totalCompanies = (clone $query)->count();
        
        $calledCount = (clone $query)->whereHas('organizationStatuses', function($q) use ($orgId) {
            if ($orgId) {
                $q->where('organization_id', $orgId);
            }
            $q->where('status', 'Arandı');
        })->count();

        $processedCount = (clone $query)->whereHas('organizationStatuses', function($q) use ($orgId) {
            if ($orgId) {
                $q->where('organization_id', $orgId);
            }
            $q->where('status', 'İşlem Yapıldı');
        })->count();

        $pendingCount = $totalCompanies - $calledCount - $processedCount;

        // Filters
        if ($request->filled('search')) {
            $search = $request->input('search');
            $query->where(function($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('phone', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%")
                  ->orWhere('website', 'like', "%{$search}%");
            });
        }

        if ($request->filled('country')) {
            $query->where('country', $request->input('country'));
        }

        if ($request->filled('city')) {
            $query->where('city', $request->input('city'));
        }

        if ($request->filled('category')) {
            $query->where('category', $request->input('category'));
        }

        $companies = $query->orderBy('created_at', 'desc')->paginate(30)->withQueryString();

        // Get filter selections based on scope
        if ($user->role === 'admin') {
            $countries = Company::distinct()->pluck('country')->filter()->toArray();
            $cities = Company::distinct()->pluck('city')->filter()->toArray();
            $categories = Company::distinct()->pluck('category')->filter()->toArray();
        } else {
            if ($orgId) {
                $countries = Company::whereHas('tasks.user', function($q) use ($orgId) {
                    $q->where('organization_id', $orgId);
                })->distinct()->pluck('country')->filter()->toArray();

                $cities = Company::whereHas('tasks.user', function($q) use ($orgId) {
                    $q->where('organization_id', $orgId);
                })->distinct()->pluck('city')->filter()->toArray();

                $categories = Company::whereHas('tasks.user', function($q) use ($orgId) {
                    $q->where('organization_id', $orgId);
                })->distinct()->pluck('category')->filter()->toArray();
            } else {
                $countries = Company::whereHas('tasks', function($q) use ($user) {
                    $q->where('user_id', $user->id);
                })->distinct()->pluck('country')->filter()->toArray();

                $cities = Company::whereHas('tasks', function($q) use ($user) {
                    $q->where('user_id', $user->id);
                })->distinct()->pluck('city')->filter()->toArray();

                $categories = Company::whereHas('tasks', function($q) use ($user) {
                    $q->where('user_id', $user->id);
                })->distinct()->pluck('category')->filter()->toArray();
            }
        }

        return view('companies', compact('companies', 'countries', 'cities', 'categories', 'totalCompanies', 'calledCount', 'processedCount', 'pendingCount'));
    }

    public function exportCompanies(Request $request)
    {
        $user = auth()->user();
        
        if ($user->role === 'admin') {
            $query = Company::query();
        } else {
            $query = Company::whereHas('tasks', function($q) use ($user) {
                $q->where('user_id', $user->id);
            });
        }

        if ($request->filled('search')) {
            $search = $request->input('search');
            $query->where(function($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('phone', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%")
                  ->orWhere('website', 'like', "%{$search}%");
            });
        }

        if ($request->filled('country')) {
            $query->where('country', $request->input('country'));
        }

        if ($request->filled('city')) {
            $query->where('city', $request->input('city'));
        }

        if ($request->filled('category')) {
            $query->where('category', $request->input('category'));
        }

        $companies = $query->orderBy('created_at', 'desc')->get();

        $headers = [
            'Content-type'        => 'text/csv',
            'Content-Disposition' => 'attachment; filename=companies_export_' . date('Y-m-d_H-i-s') . '.csv',
            'Pragma'              => 'no-cache',
            'Cache-Control'       => 'must-revalidate, post-check=0, pre-check=0',
            'Expires'             => '0'
        ];

        $callback = function() use ($companies) {
            $file = fopen('php://output', 'w');
            fprintf($file, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($file, ['ID', 'Name', 'Phone', 'Website', 'Email', 'Instagram', 'Facebook', 'City', 'Country', 'Category', 'Created At']);

            foreach ($companies as $c) {
                fputcsv($file, [
                    $c->id,
                    $c->name,
                    $c->phone,
                    $c->website,
                    $c->email,
                    $c->instagram,
                    $c->facebook,
                    $c->city,
                    $c->country,
                    $c->category,
                    $c->created_at->format('Y-m-d H:i:s'),
                ]);
            }

            fclose($file);
        };

        return new StreamedResponse($callback, 200, $headers);
    }



    // Authenticated users: update company call status
    public function updateCompanyStatus($id, Request $request)
    {
        $request->validate([
            'status' => 'required|string|in:Bekliyor,Arandı,İşlem Yapıldı',
            'notes' => 'nullable|string',
        ]);

        $company = Company::findOrFail($id);
        $user = auth()->user();
        $orgId = $user->organization_id;

        // Save status associated with the user's organization (nullable for personal fallbacks)
        CompanyOrganizationStatus::updateOrCreate(
            ['company_id' => $company->id, 'organization_id' => $orgId],
            [
                'status' => $request->input('status'),
                'notes' => $request->input('notes'),
                'updated_by' => $user->id
            ]
        );

        return response()->json([
            'status' => 'success',
            'message' => 'Arama durumu başarıyla güncellendi.'
        ]);
    }

}
