<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use App\Models\Product;
use App\Models\Assessment;
use App\Models\Answer;
use App\Models\Question;
use App\Models\QuestionGroup;
use App\Models\Customer;
use App\Models\Company;
use App\Models\Agency;
use App\Models\AgencyCustomer;



class ProductController extends Controller
{
    /**
     * Display a listing of products from the same company.
     */
    public function index()
    {
        $user = Auth::user();
        $filter = request()->get('filter');
        $selectedAgencyId = request()->get('agency_id');
        
        // ตัวแปรสำหรับเก็บข้อมูลที่จะส่งไป view
        $userAgencies = collect();
        $selectedAgency = null;
        
        // ตรวจสอบว่าเป็น consult level หรือไม่
        if (strtolower($user->Level) === 'consult') {
            // ดึงรายการบริษัทที่ consult user สามารถเข้าถึงได้
            $userAgencies = $this->getConsultUserAgencies($user);
            
            // ถ้าไม่มีการเลือกบริษัท ให้ใช้บริษัทแรกที่เข้าถึงได้
            if (!$selectedAgencyId && $userAgencies->isNotEmpty()) {
                $selectedAgencyId = $userAgencies->first()->Agency_ID;
            }
            
            // หาข้อมูลบริษัทที่เลือก
            $selectedAgency = $userAgencies->where('Agency_ID', $selectedAgencyId)->first();
            
            if ($selectedAgency) {
                if ($filter === 'my') {
                    // แสดงเฉพาะผลิตภัณฑ์ของตัวเองในบริษัทที่เลือก
                    $products = Product::where('user_id', $user->Customer_ID)
                        ->where('Agency_ID', $selectedAgencyId)
                        ->with('user', 'agency')
                        ->orderBy('DtmIns', 'asc')
                        ->get();
                } else {
                    // แสดงผลิตภัณฑ์ทั้งหมดในบริษัทที่เลือก
                    $products = Product::where('Agency_ID', $selectedAgencyId)
                        ->with('user', 'agency')
                        ->orderBy('DtmIns', 'asc')
                        ->get();
                }
            } else {
                $products = collect();
            }
        } else {
            // สำหรับ level อื่นๆ (ไม่เปลี่ยนแปลงการทำงานเดิม)
            if ($user->Agency_ID && $filter !== 'my') {
                $products = Product::where('Agency_ID', $user->Agency_ID)
                    ->with('user', 'agency')
                    ->orderBy('DtmIns', 'asc')
                    ->get();
            } else {
                $products = Product::where('user_id', $user->Customer_ID)
                    ->with('user', 'agency')
                    ->orderBy('DtmIns', 'asc')
                    ->get();
            }
        }
        
        return view('products.index', compact('products', 'userAgencies', 'selectedAgency', 'selectedAgencyId'));
    }

    /**
     * ดึงรายการบริษัทที่ consult user สามารถเข้าถึงได้
     */
    private function getConsultUserAgencies($user)
    {
        // ดึงจากตาราง agency_customer
        $agencyIds = AgencyCustomer::where('Customer_ID', $user->Customer_ID)
            ->pluck('Agency_ID')
            ->toArray();
            
        // เพิ่มบริษัทหลักจาก customer table ด้วย
        if ($user->Agency_ID && !in_array($user->Agency_ID, $agencyIds)) {
            $agencyIds[] = $user->Agency_ID;
        }
        
        return Agency::whereIn('Agency_ID', $agencyIds)->get();
    }

    /**
     * Show the form for creating a new product.
     */
    public function create()
    {
        $user = Auth::user();
        $selectedAgencyId = null;
        
        // สำหรับ consult level ให้ดึงข้อมูลบริษัทที่เลือก
        if (strtolower($user->Level) === 'consult') {
            $selectedAgencyId = request()->get('agency_id') ?? session('consult_company_context');
        }

        // ตรวจสอบว่ามีข้อมูลผลิตภัณฑ์ที่รอการประเมินหรือไม่
        $validated = session('pending_product');     
        if ($validated) {
            // ถ้ามีข้อมูลรอการประเมิน ให้แสดงแบบฟอร์มประเมิน
            $questionGroups = QuestionGroup::active()->with(['questions'])->get();
            
            return view('products.create', compact('validated', 'questionGroups', 'selectedAgencyId'));
        }
        
        // ถ้าไม่มีข้อมูลรอการประเมิน ให้แสดงฟอร์มเพิ่มผลิตภัณฑ์
        return view('products.create', compact('selectedAgencyId'));
    }

    /**
     * Start new product creation (clear session)
     */
    public function createNew(Request $request)
    {
        $user = Auth::user();
        $selectedAgencyId = null;
        
        // สำหรับ consult level ให้ดึงข้อมูลบริษัทที่เลือก
        if (strtolower($user->Level) === 'consult') {
            $selectedAgencyId = $request->get('agency_id') ?? session('consult_company_context');
        }
        
        // ลบข้อมูลทั้งหมดจาก session เพื่อเริ่มต้นใหม่
        $request->session()->forget('pending_product');
        $request->session()->forget('pending_assessment');
        
        return view('products.create', compact('selectedAgencyId'));
    }

    /**
     * Add product and evaluation
     */
    // public function completeProductCreation(Request $request){
    //     $validated = $request->validate([
    //         'name' => 'required|string|max:255',
    //         'model' => 'nullable|string|max:255',
    //         'log_receive_method' => 'required|in:syslog_udp,syslog_tcp,syslog_both,other',
    //         'product_type' => 'required|in:hw_sw_log_server,sw_log_server',
    //         'description' => 'nullable|string',
    //         'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
    //     ]);
    // }

    /**
     * Store a newly created product in storage.
     */
    public function store(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255',
            'model' => 'nullable|string|max:255',
            'log_receive_method' => 'required|in:syslog_udp,syslog_tcp,syslog_both,other',
            'product_type' => 'required|in:hw_sw_log_server,sw_log_server',
            'description' => 'nullable|string',
            'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
        ], [
            'name.required' => 'กรุณากรอกชื่อผลิตภัณฑ์',
            'name.max' => 'ชื่อผลิตภัณฑ์ต้องไม่เกิน 255 ตัวอักษร',
            'model.max' => 'รุ่นผลิตภัณฑ์ต้องไม่เกิน 255 ตัวอักษร',
            'log_receive_method.required' => 'กรุณาเลือกวิธีรับข้อมูล',
            'log_receive_method.in' => 'วิธีรับข้อมูลไม่ถูกต้อง',
            'product_type.required' => 'กรุณาเลือกประเภทผลิตภัณฑ์',
            'product_type.in' => 'ประเภทผลิตภัณฑ์ไม่ถูกต้อง',
            'image.image' => 'ไฟล์ที่อัพโหลดต้องเป็นรูปภาพ',
            'image.mimes' => 'รองรับเฉพาะไฟล์ JPEG, PNG, JPG, GIF, SVG',
            'image.max' => 'ขนาดไฟล์ต้องไม่เกิน 2MB',
        ]);

        try {
            $user = Auth::user();
            $validated['user_id'] = $user->Customer_ID;
            $selectedAgencyId = null; // เพิ่มตัวแปรนี้

            // สำหรับ consult level ให้เก็บข้อมูลบริษัทที่เลือกไว้ใน session
            if (strtolower($user->Level) === 'consult') {
                $selectedAgencyId = $request->get('selected_agency_id') ?? session('selected_agency_id');
                if ($selectedAgencyId) {
                    // ตรวจสอบว่า consult user มีสิทธิ์เข้าถึงบริษัทนี้หรือไม่
                    $userAgencies = $this->getConsultUserAgencies($user);
                    if ($userAgencies->where('Agency_ID', $selectedAgencyId)->isNotEmpty()) {
                        $request->session()->put('selected_agency_id', $selectedAgencyId);
                        $request->session()->put('consult_company_context', $selectedAgencyId);
                    }
                }
            }

            // จัดการอัพโหลดรูปภาพ
            if ($request->hasFile('image')) {
                $path = $request->file('image')->store('products_images', 'public');
                $validated['image'] = $path;
            }

            // เก็บข้อมูลผลิตภัณฑ์ไว้ใน session แทนการบันทึกลงฐานข้อมูลทันที
            $request->session()->put('pending_product', $validated);
            
            // ดึงข้อมูลคำถามสำหรับการประเมิน (เฉพาะกลุ่มที่ active)
            $questionGroups = QuestionGroup::active()->with(['questions'])->get();

            // ส่งข้อมูลที่เก็บใน session ไปยัง view
            return view('products.create', compact('validated', 'questionGroups', 'selectedAgencyId'));

        } catch (\Exception $e) {
            // ลบรูปภาพที่อัพโหลดแล้วถ้าเกิดข้อผิดพลาด
            if (isset($validated['image']) && Storage::disk('public')->exists($validated['image'])) {
                Storage::disk('public')->delete($validated['image']);
            }

            return back()->withInput()
                ->with('error', 'เกิดข้อผิดพลาดในการเพิ่มผลิตภัณฑ์ กรุณาลองใหม่อีกครั้ง');
        }
    }

    /**
     * Get products for a specific company.
     */
    public function companyProducts($agencyId)//แสดง ผลิตภัณฑ์ทั้งหมด ที่สร้างโดยผู้ใช้ (user) ซึ่งอยู่ในบริษัทที่มี Agency_ID ตรงกับ $agencyId ที่รับมาจาก URL หรือ route parameter
    {
        $products = Product::whereHas('user', function($query) use ($agencyId) { // function($query) {} คือ callback function และ use ($agencyId) คือ ดึงค่า $agencyId ไปใช้ภายใน callback function
            $query->where('Agency_ID', $agencyId);//ค้นหา products โดยตรวจสอบว่า product นั้น มี user ที่ Agency_ID ตรงกับ $agencyId และ ใช้ whereHas() เพื่อกรอง product โดยอิงจากเงื่อนไขใน customer table (ความสัมพันธ์กับ product)
        })->with('user')->get();//ดึงข้อมูลผลิตภัณฑ์ทั้งหมด พร้อมกับ โหลดข้อมูลผู้ใช้งานที่สร้างผลิตภัณฑ์นั้น โดยใช้ with() เพื่อลดจำนวน query ที่เกิดขึ้น

        return view('products.index', compact('products'));
    }

    /**
     * Get products created by the authenticated user only.
     */
    public function myProducts()
    {
        $products = Product::where('user_id', Auth::user()->Customer_ID)->get();//ค้นหา products โดยตรวจสอบว่า product นั้น มี user_id ตรงกับ Customer_ID ของผู้ใช้งานที่ล็อกอิน
        return view('products.index', compact('products'));
    }

    /**
     * Back to edit product information from session
     */
    public function backToEdit(Request $request)
    {
        $user = Auth::user();
        $selectedAgencyId = null;
        
        // สำหรับ consult level ให้ดึงข้อมูลบริษัทที่เลือก
        if (strtolower($user->Level) === 'consult') {
            $selectedAgencyId = session('consult_company_context') ?? session('selected_agency_id');
        }
        
        // ลบข้อมูลการประเมินออกจาก session (ถ้ามี)
        $request->session()->forget('pending_assessment');
        
        // เก็บข้อมูลผลิตภัณฑ์ไว้ใน session เพื่อให้สามารถแก้ไขได้
        $validated = session('pending_product');
        
        if (!$validated) {
            return redirect()->route('products.create')
                ->with('error', 'ไม่พบข้อมูลผลิตภัณฑ์ที่ต้องการแก้ไข');
        }

        return view('products.create', compact('validated', 'selectedAgencyId'));
    }

    /**
     * Set company context for consult user
     */
    public function setCompanyContext(Request $request)
    {
        $user = Auth::user();
        
        if (strtolower($user->Level) !== 'consult') {
            return response()->json(['error' => 'ไม่มีสิทธิ์ในการใช้งานฟังก์ชันนี้'], 403);
        }
        
        $agencyId = $request->get('agency_id');
        
        if ($agencyId) {
            // ตรวจสอบว่า consult user มีสิทธิ์เข้าถึงบริษัทนี้หรือไม่
            $userAgencies = $this->getConsultUserAgencies($user);
            if ($userAgencies->where('Agency_ID', $agencyId)->isNotEmpty()) {
                session(['consult_company_context' => $agencyId]);
                return response()->json(['success' => true]);
            }
        }
        
        return response()->json(['error' => 'ไม่มีสิทธิ์เข้าถึงบริษัทนี้'], 403);
    }

    public function destroy(Product $product)
    {
        $user = Auth::user();
        $hasDeleteAccess = false;
        
        // เจ้าของผลิตภัณฑ์
        if($user->Customer_ID === $product->user_id) {
            $hasDeleteAccess = true;
        }
        // Admin หรือ SuperAdmin
        elseif($user->Level === 'admin' || $user->Level === 'superadmin') {
            $hasDeleteAccess = true;
        }
        // คนในบริษัทเดียวกัน
        elseif($user->Agency_ID && $product->user && $product->user->Agency_ID && $user->Agency_ID === $product->user->Agency_ID) {
            $hasDeleteAccess = true;
        }
        // สำหรับ consult level - ตรวจสอบว่าสามารถเข้าถึงบริษัทของผลิตภัณฑ์ได้หรือไม่
        elseif(strtolower($user->Level) === 'consult' && $product->Agency_ID) {
            $userAgencies = $this->getConsultUserAgencies($user);
            if ($userAgencies->where('Agency_ID', $product->Agency_ID)->isNotEmpty()) {
                $hasDeleteAccess = true;
            }
        }
        
        if(!$hasDeleteAccess) {
            return redirect()->route('products.index')->with('error', 'คุณไม่มีสิทธิในการลบผลิตภัณฑ์นี้');
        }
        try {
            $product->delete();
            return redirect()->route('products.index')->with('error', 'ผลิตภัณฑ์ถูกลบอย่างสำเร็จ');
        } catch (\Exception $e) {
            return redirect()->route('products.index')->with('error', 'เกิดข้อผิดพลาดในการลบผลิตภัณฑ์ กรุณาลองใหม่อีกครั้ง');
        }
    }

    public function report(Product $product){
        //1.ตรวจสอบสิทธิ์ - อนุญาตให้เจ้าของผลิตภัณฑ์, คนในบริษัทเดียวกัน, หรือ admin เข้าดูได้
        $user = Auth::user();
        $hasAccess = false;
        
        // เจ้าของผลิตภัณฑ์
        if($user->Customer_ID === $product->user_id) {
            $hasAccess = true;
        }
        // Admin
        elseif($user->Level === 'admin') {
            $hasAccess = true;
        }
        // คนในบริษัทเดียวกัน
        elseif($user->Agency_ID && $product->user && $product->user->Agency_ID && $user->Agency_ID === $product->user->Agency_ID) {
            $hasAccess = true;
        }
        // สำหรับ consult level - ตรวจสอบว่าสามารถเข้าถึงบริษัทของผลิตภัณฑ์ได้หรือไม่
        elseif(strtolower($user->Level) === 'consult' && $product->Agency_ID) {
            $userAgencies = $this->getConsultUserAgencies($user);
            if ($userAgencies->where('Agency_ID', $product->Agency_ID)->isNotEmpty()) {
                $hasAccess = true;
            }
        }
        
        if(!$hasAccess) {
            abort(403, 'ไม่มีสิทธิ์เข้าถึงข้อมูลนี้');
        }

        //2.ดึงข้อมูลการประเมิณของผลิตภัณฑ์ พร้อมคำตอบและคำถาม
        $assessment = $product->assessments()
        ->with(['answers.question'])
        ->latest()
        ->first();

        if(!$assessment){
            return view('products.report',[
                'product'=>$product,
                'assessment' => null,
            ]);
        }
        
        //3.เรียงลำดับคำตอบตามเลขข้อที่ถูกต้อง และดึงเฉพาะคำถามที่มีคำตอบ
        $answeredQuestions = collect();
        
        foreach ($assessment->answers as $answer) {
            $question = $answer->question;
            if ($question) {
                // เพิ่มข้อมูลคำตอบเข้าไปในคำถาม
                $question->answer = $answer;
                $answeredQuestions->push($question);
            }
        }
        
        // เรียงลำดับตามเลขข้อที่ถูกต้อง
        $answeredQuestions = $answeredQuestions->sortBy(function($question) {
            // ใช้ question_number_sort_key ถ้ามี หรือ fallback ไปใช้ sort_order
            return $question->question_number_sort_key ?? $question->sort_order ?? 0;
        });
        
        return view('products.report', compact('product','assessment', 'answeredQuestions'));
    }


}

//->with('user') คือ laravel จะยิง 2 query คือ 1.ดึง products 2.ดึง user ที่เกี่ยวข้องทั้งหมด แต่ถ้าไม่ใช้ with ระบบจะยิง 1 query หลัก + N query ย่อย (N = จำนวน products) เรียกว่า N+1 problem
//Auth:id คือ ดึง id ของผู้ใช้งานที่ล็อกอิน
//Auth:user คือ ดึงข้อมูลผู้ใช้งานที่ล็อกอิน (คืนค่า user model ของผู้ใช้งานที่ล็อกอิน)
//create(...) คือ เมธอดของ Eloquent ที่ใช้สร้างเรคคอร์ดใหม่ โดยรับ array ของ key/value ที่ตรงกับชื่อคอลัมภ์
//$validated เป็น array ข้อมูลที่ผ่านการตรวจสอบแล้ว
//Eager Loading คือกระบวนการที่ Laravel ทำการ โหลดความสัมพันธ์ (relationships) ของ Model ล่วงหน้าในคำสั่งเดียวกับที่โหลดข้อมูลหลัก เพื่อลดจำนวน query ที่เกิดขึ้นระหว่างการใช้งานฐานข้อมูล (ช่วยแก้ปัญหา N+1 Query Problem)
//catch (\Exception $e) { คือ จับข้อผิดพลาดทั่วไป (generic exception) ที่เกิดขึ้นใน try block ก่อนหน้านี้
//isset() คือฟังก์ชันของ PHP ที่ใช้ตรวจสอบว่า ตัวแปรถูกกำหนด (defined) และ ไม่ใช่ค่า null หรือไม่
//exists() ใน Laravel หรือ PHP โดยทั่วไป หมายถึงการ ตรวจสอบว่า "มีอยู่หรือไม่" (เช่น มี record ในฐานข้อมูล หรือมี key ใน array)
//back() คือ ฟังก์ชันของ Laravel ที่ใช้ส่งกลับไปยังหน้าที่ผ่านมา (previous page) โดยส่งค่า error message ด้วย
//whereHas() ใน Laravel Eloquent ใช้เพื่อ กรอง (filter) ข้อมูลจาก model แม่ โดยอิงตามเงื่อนไขของ ความสัมพันธ์ (relationship) กับ model ลูก
//function () use () {} ใน PHP และ Laravel รูปแบบ function () use (...) {} คือการ ประกาศ Anonymous Function (Closure) และใช้ use เพื่อ ดึงตัวแปรจากภายนอกฟังก์ชันเข้ามาใช้ภายใน

/*
Model::where('column', 'operator', 'value')->get();
// หาก operator เป็น '=' สามารถละได้:
Model::where('column', 'value')->get();
*/

/*
return view('view_name', ['key' => $value]);
*/

//Session คือ "ที่เก็บข้อมูลชั่วคราวฝั่งเซิร์ฟเวอร์" สำหรับ ผู้ใช้แต่ละคน ที่เข้ามาใช้เว็บแอปพลิเคชัน โดย Laravel จะเก็บข้อมูลนี้ไว้ใน Storage หลายแบบได้
//เก็บข้อมูลไว้ใน session ด้วย session()->put('key', val)
//ดึงข้อมูลจาก session ด้วย session()->get('key') หรือ session('key')
//ลบข้อมูลจาก session ด้วย session()->forget('key') หรือ session()->pull('key')
//ลบข้อมูลทั้งหมดจาก session ด้วย session()->flush()
//ตรวจสอบว่า session มีข้อมูลหรือไม่ด้วย session()->has('key')



