<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\Models\Company;
use App\Models\CompanyDocument;
use App\Models\CompanyContactPerson;
use Illuminate\Database\QueryException;

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

    public function index(Request $request)
    {
        $query = Company::with('contactPersons');
        $query = $this->applyCustomerWorkspaceFilter($query);
        // Apply search filter
        if ($request->filled('search')) {
            $searchTerm = $request->search;
            $query->where(function ($q) use ($searchTerm) {
                $q->where('name', 'like', '%' . $searchTerm . '%')
                  ->orWhere('email', 'like', '%' . $searchTerm . '%')
                  ->orWhere('phone', 'like', '%' . $searchTerm . '%')
                  ->orWhereHas('contactPersons', function ($subquery) use ($searchTerm) {
                      $subquery->where('name', 'like', '%' . $searchTerm . '%');
                  });
            });
        }
        $data = $query->get();
        return $this->withCount($data, 'Get Client List Successfully');
    }


    public function show($id)
    {
        $company = Company::query();
        $company  = $this->applyCustomerWorkspaceFilter($company);
        $company = $company->with('contactPersons','documents')->find($id);
        if (!$company) {
            return $this->message('Client not found', 404);
        }
        return $this->success($company, 'Get Company Details Successfully');
    }

    public function store(Request $request)
    {
        $validator = $this->companyStoreValidationRequest($request);
    
        if ($validator->fails()) {
            return $this->handleValidationFailure($validator);
        }
        try {
            $validatedData = $validator->validated();
            // Handle image upload if provided
            $imagePath = $this->handleFileImageUpload($request, 'company')['path'] ?? null;
            
            // Initialize client data
            $clientData = [
                'name' => $validatedData['name'],
                'phone' => $validatedData['phone'],
                'email' => $validatedData['email'],
                'address' => $validatedData['address'],
                'abn_number' => $validatedData['abn_number'],
                'logo_img' => $imagePath,
            ];
            
            // Determine user type and assign workspace_id and customer_id
            $userTable = $this->getUserTable();
            if ($userTable == "customer") {
                $clientData['customer_id'] = auth()->id();
                $clientData['created_by'] = auth()->id();
                $clientData['workspace_id'] = auth()->user()->current_workspace_id;
            } elseif ($userTable == "emp") {
                $clientData['created_by'] = auth()->id();
                $clientData['customer_id'] = auth()->user()->customer_id;
                $clientData['workspace_id'] = auth()->user()->workspace_id;
            } else {
                return $this->message('Unauthorized access.', 403);
            }
            
            // Create the client record
            $client = Company::create($clientData);
            
            if (!$client) {
                return $this->message('Failed to create client.', 500);
            }

            // Save contact persons if provided
            if (isset($validatedData['contact_persons']) && is_array($validatedData['contact_persons'])) {
                foreach ($validatedData['contact_persons'] as $contactPerson) {
                    CompanyContactPerson::create([
                        'company_id' => $client->id,
                        'name' => $contactPerson['name'],
                        'email' => $contactPerson['email'],
                        'phone' => $contactPerson['phone'],
                        'role' => $contactPerson['role'] ?? null,
                    ]);
                }
            }

            // Load contact persons for response
            $client->load('contactPersons');
            
            return $this->success($client, 'Company Client Created Successfully');
        } catch (QueryException $exception) {
            preg_match("/'([^']+)'/", $exception->getMessage(), $matches);
            $errorField = $matches[1] ?? 'unknown';
            return $this->message('The ' . $errorField . ' field is required.', 400);
        }
    }

    public function update(Request $request)
    {
        $userTable = $this->getUserTable();
    
        $validator = $this->companyStoreValidationRequest($request);
        if ($validator->fails()) {
            return $this->handleValidationFailure($validator);
        }
        try {
            $validatedData = $validator->validated();
            $client = Company::findOrFail($request->id);
    
            // Check access based on user type
            if (
                $userTable == "customer" &&
                ($client->workspace_id != auth()->user()->current_workspace_id || $client->customer_id != auth()->id())
            ) {
                return $this->message('You do not have access to this Company', 403);
            }
            if (
                $userTable == "emp" &&
                ($client->customer_id != auth()->user()->customer_id || $client->workspace_id != auth()->user()->workspace_id)
            ) {
                return $this->message('You do not have access to this Company', 403);
            }
            
            // Handle image upload and retain the existing image if not updated
            $currentLogo = $client->logo_img;
            $imagePath = $this->handleFileImageUpload($request, 'company', $currentLogo)['path'] ?? $currentLogo;
            
            // Prepare updated data
            $updateData = [
                'name' => $validatedData['name'],
                'phone' => $validatedData['phone'],
                'email' => $validatedData['email'],
                'address' => $validatedData['address'],
                'abn_number' => $validatedData['abn_number'],
                'logo_img' => $imagePath,
            ];
            
            // Update specific fields based on user type
            if ($userTable == "emp") {
                $updateData['customer_id'] = auth()->user()->customer_id;
                $updateData['workspace_id'] = auth()->user()->workspace_id;
                $updateData['created_by'] = auth()->id();
            } elseif ($userTable == "customer") {
                $updateData['customer_id'] = auth()->id();
                $updateData['workspace_id'] = auth()->user()->current_workspace_id;
                $updateData['created_by'] = auth()->id();
            }
            
            // Update the client record
            $client->update($updateData);

            // Update contact persons if provided
            if (isset($validatedData['contact_persons']) && is_array($validatedData['contact_persons'])) {
                // Delete existing contact persons
                $client->contactPersons()->delete();
                
                // Create new contact persons
                foreach ($validatedData['contact_persons'] as $contactPerson) {
                    CompanyContactPerson::create([
                        'company_id' => $client->id,
                        'name' => $contactPerson['name'],
                        'email' => $contactPerson['email'],
                        'phone' => $contactPerson['phone'],
                        'role' => $contactPerson['role'] ?? null,
                    ]);
                }
            }

            // Load contact persons for response
            $client->load('contactPersons');
            
            return $this->success($client, 'Client details updated successfully');
        } catch (QueryException $exception) {
            preg_match("/'([^']+)'/", $exception->getMessage(), $matches);
            $errorField = $matches[1] ?? 'unknown';
            return $this->message('The ' . $errorField . ' field is required.', 400);
        }
    }
    

    public function destroy($id)
    {
        $company = Company::query();
        if (!$company) {
            return $this->message('Client not found', 404);
        }
        $company = $this->applyCustomerWorkspaceFilter($company);
        $company = $company->find($id);
        if ($company->del == 1) {
            return $this->message('Client Already Deleted', 400);
        }
        // Update the `del` status to 1
        $company->del = 1;
        if ($company->save()) {
            return $this->message('Client Deleted Successfully', 200);
        }
        return $this->message('Failed to Delete Client', 500);
    }

    public function destroyCompanyPerson($id)
    {
        $person = CompanyContactPerson::find($id);
        if (!$person) {
            return $this->message('Person not found', 404);
        }
        $person->delete();
        return $this->message('Person deleted successfully');
    }

    public function updateStatus(Request $request)
    {
        $company = Company::find($request->id);
        if (!$company) {
            return $this->message('Failed to Find Company client', 404);
        }
        $userTable = $this->getUserTable();
        if ($userTable == "customer" && ($company->workspace_id != auth()->user()->current_workspace_id || $company->customer_id != auth()->id())) {
            return $this->message('Unauthorized: You cannot update the status of this company client.', 403);
        }
        if ($userTable == "emp" && ($company->customer_id != auth()->user()->customer_id || $company->workspace_id != auth()->user()->workspace_id)) {
            return $this->message('Unauthorized: You cannot update the status of this company client.', 403); 
        }
       
        $company->active = $company->active == 1 ? 0 : 1;
        $company->save();
        return $this->success($company, 'Status Updated Successfully');
    }



    public function showClinetDocument($id)
    {
        try {
            $userTable = $this->getUserTable();
            $client = Company::with('contactPersons')->find($id);
            if (!$client) {
                return $this->message('Client not found', 404);
            }

            if ($userTable == "customer") {
                if ($client->customer_id !== auth()->id() || $client->workspace_id !== auth()->user()->current_workspace_id) {
                    return $this->message('Unauthorized access', 403);
                }
            }
            if ($userTable == "emp") {
                if ($client->customer_id !== auth()->user()->customer_id || $client->workspace_id !== auth()->user()->workspace_id) {
                    return $this->message('Unauthorized access', 403);
                }
            }
            $clientdocuments = CompanyDocument::where('c_id', $id)->get();
            $data = $client->toArray();
            $data['documents'] = $clientdocuments;
            return $this->withCount($data, 'Client data retrieved successfully.');
        } catch (\Exception $e) {
            return $this->error('Error retrieving client data. ' . $e->getMessage());
        }
    }


    public function clientdocument(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'title' => 'required|string|max:255',
                'c_id' => 'required|exists:companies,id'
            ]);
            if ($validator->fails()) {
                return $this->message($validator->errors()->first(), 422);
            }
            $userTable = $this->getUserTable();
            $client = Company::find($request->c_id);
            if (!$client) {
                return $this->message('Client not found.', 404);
            }
            // Access control for customer and emp
            if ($userTable == "customer" &&
                ($client->customer_id !== auth()->id() || $client->workspace_id !== auth()->user()->current_workspace_id)) {
                    return $this->message('Unauthorized access.', 403);
                }
                if ($userTable == "emp" &&
                ($client->customer_id !== auth()->user()->customer_id || $client->workspace_id !== auth()->user()->workspace_id)) {
                return $this->message('Unauthorized access.', 403);
            }
            // Save document
            $clientDocument = new CompanyDocument();
            $clientDocument->title = $request->title;
            $clientDocument->c_id = $request->c_id;
            $clientDocument->uploaded_by = auth()->user()->id;
    
            if ($request->hasFile('document')) {
                $document = $this->handleFileImageUpload($request, 'CompanyDocuments');
                $clientDocument->document = $document['path'] ?? null;
            }
    
            $clientDocument->save();
            return $this->message('Document saved successfully', 200);
        } catch (\Exception $e) {
            return $this->message('Error While Saving Document: ' . $e->getMessage(), 500);
        }
    }
    

    public function deletedocument($id)
    {
       
            $document = CompanyDocument::find($id);
            if (!$document) {
                return response()->json(['error' => 'Document not found.'], 404);
            }
            $userTable = $this->getUserTable();
            $client = Company::find($document->c_id);
            if (!$client) {
                return $this->message(['error' => 'Client not found for the document.'], 404);
            }
            if ($userTable == "customer") {
                if ($client->customer_id !== auth()->id() || $client->workspace_id !== auth()->user()->current_workspace_id) {
                    return $this->message('Unauthorized access.', 403);
                }
            }
            if ($userTable == "emp") {
                if ($client->customer_id !== auth()->user()->customer_id || $client->workspace_id !== auth()->user()->workspace_id) {
                    return $this->message('Unauthorized access.', 403);
                }
            }
            // Delete the file if it exists
            $filePath = public_path($document->document);
            if (!empty($document->document) && file_exists($filePath)) {
                unlink($filePath); // Delete the file from the directory
            }
            $document->delete();
            return $this->message('Document deleted successfully.');
    
    }


}
