<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
use App\Models\Project;
use App\Models\ProjectHistory;
use App\Models\ProjectDocument;
use App\Models\ProjectMeta;
use App\Models\ProjectDocumentHistory;
use App\Models\ProjectSite;
use App\Models\Company;
use App\Models\EmpPersonalDetails;
use App\Models\Sites;
use DB;
use App\Models\User;

class ProjectController extends Controller
{
    public function __construct()
    {
        $this->middleware('Permissions:Projects Maintain')->only(['create', 'edit']);
    }

    public function index(Request $request)
    {
        $query = Project::where('is_deleted', 0)->latest('id'); // Only include non-deleted projects
        $query = $this->applyCustomerWorkspaceFilter($query);
        // Apply search filter across company name, site title, project name, and state
        if ($request->filled('search')) {
            $searchTerm = $request->search;
            $query->where(function ($q) use ($searchTerm) {
                // Search in project title
                $q->where('title', 'like', '%' . $searchTerm . '%')
                // Search in project state
                ->orWhere('state', 'like', '%' . $searchTerm . '%')
                // Search in company name
                ->orWhereHas('company', function ($subquery) use ($searchTerm) {
                    $subquery->where('name', 'like', '%' . $searchTerm . '%');
                })
                // Search in site title (through project sites)
                ->orWhereHas('site', function ($subquery) use ($searchTerm) {
                    $subquery->whereHas('siteDetails', function ($siteQuery) use ($searchTerm) {
                        $siteQuery->where('title', 'like', '%' . $searchTerm . '%');
                    });
                });
            });
        }
        // Include related data with nested site details
        if($request->has('with') && $request->with == 'site'){
            $query->with([
                'site.siteDetails' // Assuming you have a relationship to the actual Site model
            ]);
        }else{
            $query->with([
                'company', 
                'ProjectMeta',
                'site.siteDetails'
            ]);
        }
       
        $query_result = $query;
        // If you don't have direct relationship, manually fetch site details
        foreach ($query_result as $project) {
            foreach ($project->site as $siteRelation) {
                // Fetch site details based on site_id
                $siteDetails = Sites::find($siteRelation->site_id);
                $siteRelation->site_name = $siteDetails ? $siteDetails->name : 'Unknown Site';
                $siteRelation->site_details = $siteDetails;
            }
        }
        // Return the result with filters
        return $this->withCount($query, 'Get Projects List Successfully');
    }
    

    public function filter($filters, $query)
    {

        foreach ($filters as $filterName => $filterValue) {
            if ($filterValue != null ||  $filterValue != "") {
                switch ($filterName) {
                    case 'company':
                        $query->whereHas('company', function ($subquery) use ($filterValue) {
                            $subquery->where('fname', 'like', '%' . $filterValue . '%');
                        });
                        break;
                    case 'title':
                        $query->where('title', 'like', '%' . $filterValue . '%');
                        break;
                    case 'active':
                        $filterValue =   $filterValue ? 1 : 0;
                        $query->where('active', 'like', '%' . $filterValue . '%');
                        break;
                    case 'latitude':
                        $query->where('latitude', 'like', '%' . $filterValue . '%');
                        break;
                    case 'longitude':
                        $query->where('longitude', 'like', '%' . $filterValue . '%');
                        break;
                    case 'area_radius':
                        $query->where('area_radius', 'like', '%' . $filterValue . '%');
                        break;
                    case 'State':
                        $query->where('State', 'like', '%' . $filterValue . '%');
                        break;
                }
            }
        }

        return $query;
    }

    public function show($id)
    {
        $userTable = $this->getUserTable();
        $get_project = Project::find($id);
        if (
            $userTable == "customer" && ($get_project->workspace_id != auth()->user()->current_workspace_id || $get_project->customer_id != auth()->user()->id)
        ) {
            return $this->message('You do not have access to this project', 403);
        }

        if ($userTable == "emp" && ($get_project->customer_id != auth()->user()->customer_id || $get_project->workspace_id != auth()->user()->workspace_id)) {
            return $this->message('You do not have access to this project', 403);
        }
        $meta_project = ProjectMeta::where('project_id', $id)->orderBy('id', 'DESC')->get();
        $pro_histories = ProjectHistory::where('project_id', $id)->orderBy('id', 'DESC')->get();
        $pro_documents = ProjectDocument::where('project_id', $id)->orderBy('id', 'DESC')->get();
        $get_client =  Company::where('id', $get_project->client_id)->where('del', 0)->orderBy('id', 'DESC')->first();
        $get_pro_sites = ProjectSite::where('project_id', $id)->get();
        $siteIds = [];
        foreach ($get_pro_sites as $pro_site) {
            $siteIds[] = $pro_site->site_id;
        }
        $get_sites = Sites::whereIn('id', $siteIds)->where('active',1)->where('del',0)->orderBy('id', 'DESC')->get();



        if ($get_project->created_by == 0) {
            $created_by = User::where('id', $get_project->customer_id)->select('name as first_name')->first();
        }else {
             $created_by = EmpPersonalDetails::where('id', $get_project->created_by)->first();
        }

        $response = array_merge(
            $get_project->toArray(),
            [
                'meta' => $meta_project,
                'history' => $pro_histories,
                'documents' => $pro_documents,
                'client' => $get_client,
                'sites' => $get_sites,
                'created_by' => $created_by,
            ]
        );
        return $this->success($response, 'Project retrieved successfully');
    }

    // public function create(Request $request)
    // {
    //     $get_clients =  Company::where('del',0)->where('active',1)->orderBy('id', 'DESC')->get();
    //     $get_sites =  Sites::where('del',0)->where('active',1)->orderBy('id', 'DESC')->get();

    //     return view('Project.create',compact('get_clients','get_sites'));
    // }

    // public function edit(Project $project)
    // {
    //     $project->load('projectMeta');
    //     $projectDocuments = $project->projectDocuments;
    //     $meta_project = ProjectMeta::where('project_id', $project->id)->get();
    //     $get_clients =  Company::where('del',0)->orderBy('id', 'DESC')->get();
    //     $get_sites =  Sites::where('del',0)->where('active',1)->orderBy('id', 'DESC')->get();
    //     $get_pro_sites = ProjectSite::where('project_id',$project->id)->get();
    //     return view('Project.edit', compact('project', 'projectDocuments','meta_project','get_clients','get_sites','get_pro_sites'));
    // }

    public function store(Request $request)
    {
        // dd($request->all());
        $validator = Validator::make($request->all(), [
            'title' => 'required|string',
            'client_id' => 'required|integer',
            'thumbnail' => 'nullable|image|mimes:jpeg,png,jpg,gif',
            'start_date' => 'required|date|after_or_equal:today',
            'end_date' => 'required|date|after_or_equal:start_date',
            'description' => 'nullable|string',
            'address' => 'required|string',
            'longitude' => 'required|string',
            'latitude' => 'required|string',
            'area_radius' => 'required|string',
            'state' => 'required|string',
            'site_id' => 'nullable|array',
            'site_id.*' => 'nullable|integer',

        ]);
        if ($validator->fails()) {
            $error = $validator->errors()->first();
            return $this->message($error, 422);
        }
        $validatedData = $validator->validated();
        $userTable = $this->getUserTable(); // Get the user type (customer or emp)
    
        // Prepare the project data
        $projectData = [
            'title' => $validatedData['title'],
            'client_id' => $validatedData['client_id'],
            'description' => $validatedData['description'],
            'address' => $validatedData['address'],
            'longitude' => $validatedData['longitude'],
            'latitude' => $validatedData['latitude'],
            'area_radius' => $validatedData['area_radius'],
            'state' => $validatedData['state'],
            'thumbnail' => $this->handleFileImageUpload($request, 'Projects')['path'] ?? null,
        ];
       
        // Add customer and workspace IDs dynamically
        if ($userTable == "customer") {
            $projectData['customer_id'] = auth()->id();
            $projectData['workspace_id'] = auth()->user()->current_workspace_id;
            $projectData['created_by'] = 0;
        } elseif ($userTable == "emp") {
            $projectData['customer_id'] = auth()->user()->customer_id;
            $projectData['workspace_id'] = auth()->user()->workspace_id;
            $projectData['created_by'] = auth()->user()->id;
        }
        // Save the project
        $project = Project::create($projectData);
        $siteIds = $validatedData['site_id'] ?? [];
        foreach ($siteIds as $siteId) {
            ProjectSite::create([
                'project_id' => $project->id,
                'site_id' => $siteId,
                'user_id' => Auth::user()->id,
            ]);
        }
        $metaDescriptions = $request->only([
            'revenue',
            'start_date',
            'end_date',
        ]);
        $projectMeta = [];
        foreach ($metaDescriptions as $option => $value) {
            if ($value !== null) {
                $projectMeta[] = [
                    'project_id' => $project->id,
                    'option' => $option,
                    'value' => $value,
                ];
            }
        }
        DB::table('projects_meta')->insert($projectMeta);
        return $this->success($project, 'Project Saved Successfully');
    }


    public function update(Request $request)
    {
        // dd($request->all());
        $userTable = $this->getUserTable();
        $validator = Validator::make($request->all(), [
            'title' => 'required|string',
            'client_id' => 'required|integer',
            'thumbnail' => 'nullable|image|mimes:jpeg,png,jpg,gif',
            'start_date' => 'required|date',
            'description' => 'nullable|string',
            'address' => 'required|string',
            'longitude' => 'required|string',
            'latitude' => 'required|string',
            'area_radius' => 'required|string',
            'state' => 'required|string',
            'site_id' => 'nullable|array',
            'site_id.*' => 'integer'
        ]);

        if ($validator->fails()) {
            $error = $validator->errors()->first();
            return $this->message($error, 422);
        }

        $validatedData = $validator->validated();
        $project = Project::findOrFail($request->id);
        if (
            $userTable == "customer" && ($project->workspace_id != auth()->user()->current_workspace_id || $project->customer_id != auth()->user()->id)
        ) {
            return $this->message('You do not have access to this project', 403);
        }
        if ($userTable == "emp" && ($project->customer_id != auth()->user()->customer_id || $project->workspace_id != auth()->user()->workspace_id)) {
            return $this->message('You do not have access to this project', 403);
        }
        if ($request->hasFile('thumbnail')) {
            $project->thumbnail = $this->handleFileImageUpload($request, 'Projects', $project->thumbnail)['path'] ?? $project->thumbnail;
        }
        if ($userTable == "customer") {
            $validatedData['customer_id'] = auth()->id();
            $validatedData['created_by'] = 0;
            $validatedData['workspace_id'] = auth()->user()->current_workspace_id;
        } elseif ($userTable == "emp") {
            $validatedData['customer_id'] = auth()->user()->customer_id;
            $validatedData['workspace_id'] = auth()->user()->workspace_id;
            $validatedData['created_by'] = auth()->user()->id;
        }
        $project->update($validatedData);
        if ($userTable === 'emp') {
            $added_by = EmpPersonalDetails::where('emp_id', Auth::user()->id)->select('first_name', 'middle_name', 'last_name')->first();
            $fullName = trim($added_by->first_name . " " . $added_by->middle_name . " " . $added_by->last_name);
        } else {
            $added_by = User::where('id', Auth::user()->id)->select('name')->first();
            $fullName = $added_by->name;
        }
        $description = "<a href='" . url('/') . "/user-profile/" . Auth::user()->id . "' style='text-transform: capitalize;' role='button' class='primary text-decoration-none'> {$fullName}  </a>  changed the project details: '{$project->title}'.";
        $history = [
            'project_id' => $project->id,
            'history_type' => 'project_change',
            'description' => $description,
            'user_id' => auth()->user()->id,
        ];
        ProjectHistory::create($history);
        ProjectSite::where('project_id', $request->id)->delete();
        $siteIds = $validatedData['site_id'] ?? [];
        foreach ($siteIds as $siteId) {
            ProjectSite::create([
                'project_id' => $request->id,
                'site_id' => $siteId,
                'user_id' => Auth::user()->id,
            ]);
        }

        $metaDescriptions = $request->only([
            'revenue',
            'start_date',
            'end_date',
        ]);

        $projectMeta = [];
        foreach ($metaDescriptions as $option => $value) {
            if ($value !== null) {
                $projectMeta[] = [
                    'project_id' => $request->id,
                    'option' => $option,
                    'value' => $value,
                ];
            }
        }
        // Insert product meta descriptions in bulk
        DB::table('projects_meta')->where('project_id', $request->id)->delete();
        DB::table('projects_meta')->insert($projectMeta);
        return $this->success($project, 'Project Updated Successfully');
    }

    public function projectdocument(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'title' => 'required|string|max:255',
                'project_id' => 'required|integer|exists:projects,id',
            ]);
            if ($validator->fails()) {
                return $this->message($validator->errors(), 422);
            }
            $userTable = $this->getUserTable(); // Determine the user table dynamically
            $project = Project::find($request->project_id);
            if ($userTable == "customer" && ($project->customer_id != auth()->id() || $project->workspace_id != auth()->user()->current_workspace_id)) {
                return $this->message('Unauthorized access to this project', 403);
            }
            if ($userTable == "emp" && ($project->customer_id != auth()->user()->customer_id || $project->workspace_id != auth()->user()->workspace_id)) {
                return $this->message( 'Unauthorized access to this project', 403);
            }
            $projectDocument = new ProjectDocument();
            $projectDocument->title = $request->title;
            $projectDocument->project_id = $request->project_id;
            $projectDocument->uploaded_by = auth()->user()->id;

            if ($request->hasFile('file_name')) {
                $document = $this->handleFileImageUpload($request, 'ProjectDocuments');
            }
            $projectDocument->file_name = $document['path'] ?? null;
            $projectDocument->save();
            $newlyGeneratedId = $projectDocument->id;
            $projectname = DB::table('projects')->where('id', $request->project_id)->first();

            if ($userTable === 'emp') {
                $added_by = EmpPersonalDetails::where('emp_id', Auth::user()->id)->select('first_name', 'middle_name', 'last_name')->first();
                $fullName = trim($added_by->first_name . " " . $added_by->middle_name . " " . $added_by->last_name);
            } else {
                $added_by = User::where('id', Auth::user()->id)->select('name')->first();
                $fullName = $added_by->name;
            }
            $description = "<a href='" . url('/') . "/user-profile/" . Auth::user()->id . "' style='text-transform: capitalize;' role='button' class='primary text-decoration-none'> {$fullName}  </a> Upload a new document: '{$projectDocument->title}' To this project : {$projectname->title}.";
            $history = [
                'project_id' =>  $projectDocument->project_id,
                'document_id' => $projectDocument->id,
                'description' => $description,
                'user_id' => auth()->user()->id,
            ];
            ProjectDocumentHistory::create($history);
            return $this->success($projectDocument, 'Project document saved successfully', 200);
        } catch (\Exception $e) {
            return $this->message('Error saving project document' . 'error' . $e->getMessage(), 500);
        }
    }

    public function deletedocument(Request $request)
    {
        try {
            $projectDoc = DB::table('project_documents')->where('id', $request->id)->first();
            // dd($projectDoc);
            if (!$projectDoc) {
                return $this->message('Document not found.', 404);
            }
            $project = DB::table('projects')->where('id', $projectDoc->project_id)->first();
            if (!$project) {
                return $this->message('Project not found for the document.', 404);
            }
            $userTable = $this->getUserTable();
            if ($userTable == "customer" && ($project->customer_id != auth()->id() || $project->workspace_id != auth()->user()->current_workspace_id)) {
                return $this->message('Unauthorized access to this project', 403);
            }
            if ($userTable == "emp" && ($project->customer_id != auth()->user()->customer_id || $project->workspace_id != auth()->user()->workspace_id)) {
                return $this->message('Unauthorized access to this project', 403);
            }
            if ($userTable === 'emp') {
                $added_by = EmpPersonalDetails::where('emp_id', Auth::user()->id)->select('first_name', 'middle_name', 'last_name')->first();
                $fullName = trim($added_by->first_name . " " . $added_by->middle_name . " " . $added_by->last_name);
            } else {
                $added_by = User::where('id', Auth::user()->id)->select('name')->first();
                $fullName = $added_by->name;
            }
            $description = "<a href='" . url('/') . "/user-profile/" . Auth::user()->id . "' style='text-transform: capitalize;' role='button' class='primary text-decoration-none'> {$fullName}</a> deleted the document: '{$projectDoc->title}' of project: {$project->title}.";
            $history = [
                'project_id' => $projectDoc->project_id,
                'document_id' => $projectDoc->id,
                'description' => htmlentities($description),
                'user_id' => auth()->user()->id,
            ];
            ProjectDocumentHistory::create($history);
            DB::table('project_documents')->where('id', $request->id)->delete();
            return $this->message('Document deleted successfully.', 200);
        } catch (\Exception $e) {
            return $this->message('Failed to delete document.' . 'details' . $e->getMessage(), 500);
        }
    }


    // public function editdocument($id)
    // {
    //     $document = ProjectDocument::where('id', $id)->first();
    //     return response()->json([
    //         'title' => $document->title,
    //         'id' => $document->id
    //     ]);
    // }

    public function updateprojectdocument(Request $request)
    {
        try {
            $request->validate([
                'document_id' => 'required|exists:project_documents,id',
                'title' => 'required|string',
            ]);
            $projectDocument = ProjectDocument::find($request->input('document_id'));
            if (!$projectDocument) {
                return $this->message('Project document not found.', 404);
            }
            $projectDoc = DB::table('project_documents')->where('id', $request->document_id)->first();
            $project = DB::table('projects')->where('id', $projectDoc->project_id)->first();
            if (!$project) {
                return $this->message('Project not found for the document.', 404);
            }
            // Determine user type and validate access
            $userTable = $this->getUserTable();
            if ($userTable == "customer" && ($project->customer_id != auth()->id() || $project->workspace_id != auth()->user()->current_workspace_id)) {
                return $this->message( 'Unauthorized access to this project', 403);
            }
            if ($userTable == "emp" && ($project->customer_id != auth()->user()->customer_id || $project->workspace_id != auth()->user()->workspace_id)) {
                return $this->message('Unauthorized access to this project', 403);
            }
            if ($userTable === 'emp') {
                $added_by = EmpPersonalDetails::where('emp_id', Auth::user()->id)->select('first_name', 'middle_name', 'last_name')->first();
                $fullName = trim($added_by->first_name . " " . $added_by->middle_name . " " . $added_by->last_name);
            } else {
                $added_by = User::where('id', Auth::user()->id)->select('name')->first();
                $fullName = $added_by->name;
            }
            $description = "<a href='" . url('/') . "/user-profile/" . Auth::user()->id . "' style='text-transform: capitalize;' role='button' class='primary text-decoration-none'> {$fullName} </a> updated the document title from: '{$projectDoc->title}' to: '{$request->title}'.";
            $history = [
                'project_id' => $projectDoc->project_id,
                'document_id' => $projectDoc->id,
                'history_type' => 1,
                'description' => htmlentities($description),
                'user_id' => auth()->user()->id,
            ];
            ProjectDocumentHistory::create($history);
            $projectDocument->title = $request->input('title');
            $projectDocument->save();
            return $this->message( 'Document title updated successfully.', 200);
        } catch (\Exception $e) {
            \Log::error($e->getMessage());
            return $this->message( 'Failed to update document title.'. 'details' . $e->getMessage(), 500);
        }
    }


    public function viewdocumenthistory(Request $request)
    {
        try {
            $request->validate([
                'id' => 'required|exists:project_documents,id',
            ]);
             $projectDoc = DB::table('project_documents')->where('id', $request->id)->first();
            if (!$projectDoc) {
                return $this->message( 'Document not found.', 404);
            }
            $project = DB::table('projects')->where('id', $projectDoc->project_id)->first();
            if (!$project) {
                return $this->message( 'Project not found for the document.', 404);
            }
            $userTable = $this->getUserTable();
            if ($userTable == "customer" && ($project->customer_id != auth()->id() || $project->workspace_id != auth()->user()->current_workspace_id)) {
                return $this->message('Unauthorized access to this project', 403);
            }
            if ($userTable == "emp" && ($project->customer_id != auth()->user()->customer_id || $project->workspace_id != auth()->user()->workspace_id)) {
                return $this->message( 'Unauthorized access to this project', 403);
            }
            if ($userTable === 'emp') {
                $added_by = EmpPersonalDetails::where('emp_id', Auth::user()->id)->select('first_name', 'middle_name', 'last_name')->first();
                $fullName = trim($added_by->first_name . " " . $added_by->middle_name . " " . $added_by->last_name);
            } else {
                $added_by = User::where('id', Auth::user()->id)->select('name')->first();
                $fullName = $added_by->name;
            }
            $description = "<a href='" . url('/') . "/user-profile/" . Auth::user()->id . "' style='text-transform: capitalize;' role='button' class='primary text-decoration-none'>
             {$fullName}</a> viewed the document: '{$projectDoc->title}' of this project: {$project->title}.";
            $history = [
                'project_id' => $projectDoc->project_id,
                'document_id' => $projectDoc->id,
                'history_type' => 0, // View history type
                'description' => htmlentities($description),
                'user_id' => auth()->user()->id,
            ];
            ProjectDocumentHistory::create($history);
            return $this->success($history, 'Document history logged successfully.');
        } catch (\Exception $e) {
            return $this->message( 'Failed to log document view history.' . 'details' . $e->getMessage(), 500);
        }
    }
    

    public function destroy($id)
    {
        try {
            $project = Project::find($id);
            if (!$project) {
                return $this->message('Project not found.', 404);
            }
            $userTable = $this->getUserTable();
            if ($userTable == "customer" && ($project->customer_id != auth()->id() || $project->workspace_id != auth()->user()->current_workspace_id)) {
                return $this->message('Unauthorized access to this project', 403);
            }
            if ($userTable == "emp" && ($project->customer_id != auth()->user()->customer_id || $project->workspace_id != auth()->user()->workspace_id)) {
                return $this->message( 'Unauthorized access to this project', 403);
            }
            if($project->is_deleted == 1){
                return $this->message('Project already has been deleted.');
            }
            
            // Check if project has associated sites
            $projectSites = ProjectSite::where('project_id', $id)->get();
            if ($projectSites->isNotEmpty()) {
                return $this->message('Remove all sites before deleting this project.', 422);
            }
            
            $project->is_deleted = 1;
            $project->save();
            return $this->message( 'Project Deleted Successfully');
        } catch (\Exception $e) {
            return $this->message('Failed to delete project.' . 'details' . $e->getMessage(), 500);
        }
    }
    

    public function updateStatus(Request $request)
    {
        try {
            $project = Project::find($request->id);
            if (!$project) {
               return $this->message('Project not found',404);
            }
            $userTable = $this->getUserTable();
            if ($userTable == "customer" && ($project->customer_id != auth()->id() || $project->workspace_id != auth()->user()->current_workspace_id)) {
                return $this->message('Unauthorized access to this project', 403);
            }
            if ($userTable == "emp" && ($project->customer_id != auth()->user()->customer_id || $project->workspace_id != auth()->user()->workspace_id)) {
                return $this->message( 'Unauthorized access to this project', 403);
            }
                $project->active = $project->active == 1 ? 0 : 1;
            $project->save();
            return $this->success($project , 'Status Updated Successfully');
        } catch (\Exception $e) {
            return $this->message('Failed to update status.' . 'error' . $e->getMessage(), 500);
        }
    }
    


    // public function project_list(Request $request)
    // {
    //     $projects = Project::where('is_deleted', '0')
    //         ->with('projectDocuments')
    //         ->with('company')
    //         ->with('ProjectMeta')
    //         ->get();

    //     return response()->json([
    //         'message' => 'Get Project List Successfully',
    //         'data' => $projects
    //     ], 200);
    // }
}
