<?php

namespace App\Http\Controllers;

use DB;
use DateTime;
use App\Models\Role;
use App\Models\Tier;
use App\Models\User;
use App\Models\EmpTeam;
use Illuminate\Http\Request;
use App\General\SettingsClass;
use App\Models\LinkManagement;
use App\Models\EmpPersonalDetails;
use App\Models\EmpCompanyDetails;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;

class LinkManagementController extends Controller
{

    public function index(Request $request)
    {
        // Initialize the query
        $query = LinkManagement::query()->latest('id');
        $query = $this->applyCustomerWorkspaceFilter($query);
        $query->with(['roleId', 'tierId']);
        // Apply filters from request parameters
        $filters = $request->only(['name', 'tier_id', 'role_id', 'status', 'team_ids', 'phone', 'email', 'title', 'company_name', 'address']);
        $query = $this->filter($filters, $query);
        // Get the data (this will be a Collection or Paginator)
        $links = $query->get();
        // Add link_employee parameter to each link
        $links = $links->map(function ($link) {
            $associatedEmployees = EmpCompanyDetails::where('link_key', $link->secret_key)->count();
            $link->link_employee = $associatedEmployees > 0 ? 1 : 0;
            return $link;
        });
        return $this->withCount($links, 'link Get successfully');
    }


    public function create()
    {
        $roles = Role::get();
        $tiers = Tier::get();
        $teams = EmpTeam::get();
        return view('LinkManagement.create')->with(['roles' => $roles, 'tiers' => $tiers, 'teams' => $teams]);
    }

    public function link_edit(Request $request)
    {
        $id = $request->id;
        $userTable = $this->getUserTable();
        $link_management = LinkManagement::find($id);
        if (!$link_management) {
            // Return a JSON response with a 404 status code
            return $this->message('Link record not found.', 404);
        }

        if (
            $userTable == "customer" && ($link_management->workspace_id != auth()->user()->current_workspace_id || $link_management->customer_id != auth()->user()->id)
        ) {
            return $this->message('You do not have access to this Link', 403);
        }

        if ($userTable == "emp" && ($link_management->customer_id != auth()->user()->customer_id || $link_management->workspace_id != auth()->user()->workspace_id)) {
            return $this->message('You do not have access to this Link', 403);
        }
        $data['link_management'] = $link_management;

        return $this->success($data, 'Get link successfully');
    }

    public function store(Request $request)
    {
        $validator = Validator::make(
            $request->all(),
            [
                'title' => 'required|string|max:255',
                'paid_break' => 'required|integer|min:0',
                'color_code' => 'nullable|regex:/^#[0-9a-fA-F]{6}$/',
                'role' => 'required|integer|exists:roles,id',
                'tier' => 'required|integer|exists:tiers,id',
                'start_time' => 'required',
                'end_time' => 'required',
                'description' => 'nullable',
                'working_days' => 'required|array',
                'number_of_days' => 'required|integer|max:365',
                'teams' => 'required|exists:emp_teams,id',
                'name' => 'nullable|string|max:255',
                'email' => 'nullable|email|max:255',
                'phone' => 'nullable|string|max:255',
                'address' => 'nullable|string|max:255',
                'company_name' => 'nullable|string|max:255',
                'company_logo' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
                'required_hours' => 'nullable|numeric|max:24|min:0',
                'site_id' => 'nullable|integer|exists:sites,id',
            ],
            [
                'working_days.required' => 'Please select one or more working days'
            ]
        );
        if ($validator->fails()) {
            $error = $validator->errors()->first();
            return $this->error($error, 422);
        }
        $validatedData = $validator->validated();
        $emp_teams = implode(",", $request->teams);
        $ids = $this->getCustomerAndWorkspaceIds();
        $imagePath = null;
        if ($request->hasFile('company_logo')) {
            $imagePath = $this->handleFileImageUpload($request, 'LinkManagement')['path'] ?? null;
        }
        
        // Convert required_hours from time format (7:30) to decimal (7.5) if needed
        // Get value directly from request to preserve decimal precision
        $requiredHours = $request->input('required_hours');
        if ($requiredHours !== null && $requiredHours !== '') {
            $requiredHours = $this->convertTimeToDecimal($requiredHours);
            // Ensure it's a float to preserve decimal precision
            $requiredHours = is_numeric($requiredHours) ? (float) $requiredHours : null;
        } else {
            $requiredHours = null;
        }
        
        LinkManagement::create([
            'title' => $validatedData['title'],
            'description' => $validatedData['description'],
            'role_id' => $validatedData['role'],
            'tier_id' => $validatedData['tier'],
            'customer_id' => $ids['customer_id'],
            'workspace_id' => $ids['workspace_id'],
            'name' => $validatedData['name'],
            'email' => $validatedData['email'],
            'phone' => $validatedData['phone'],
            'address' => $validatedData['address'],
            'company_name' => $validatedData['company_name'],
            'company_logo' => $imagePath,
            'working_days' => implode(",", $validatedData['working_days']),
            'number_of_days' => $validatedData['number_of_days'],
            'start_time' => $validatedData['start_time'],
            'end_time' => $validatedData['end_time'],
            'paid_break' => $validatedData['paid_break'],
            'color_code' => $validatedData['color_code'],
            'secret_key' => $this->generateSecretKey(),
            'created_by' => auth()->user()->id,
            'status' => '1',
            'team_ids' => $emp_teams,
            'required_hours' => $requiredHours,
            'site_id' => $validatedData['site_id'] ?? null,
        ]);

        return $this->message('Link created Successfully');
    }

    public function link_update(Request $request)
    {
        // Validation
        $validator = Validator::make($request->all(), [
            'id' => 'required',
            'title' => 'required|string|max:255',
            'paid_break' => 'required|integer|min:0',
            'color_code' => [
                'nullable',
                'regex:/^#[0-9a-fA-F]{6}$/'
            ],
            'role' => 'required|integer|exists:roles,id',
            'tier' => 'required|integer|exists:tiers,id',
            'start_time' => 'required',
            'end_time' => 'required',
            'description' => 'nullable|string',
            'working_days' => 'required|array',
            'number_of_days' => 'required|integer|max:365',
            'teams' => 'required|array|exists:emp_teams,id',
            'name' => 'nullable|string|max:255',
            'email' => 'nullable|email|max:255',
            'phone' => 'nullable|string|max:255',
            'address' => 'nullable|string|max:255',
            'company_name' => 'nullable|string|max:255',
            'company_logo' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
            'required_hours' => 'nullable|numeric|max:24',
            'site_id' => 'nullable|integer|exists:sites,id',
        ], [
            'working_days.required' => 'Please select one or more working days',
        ]);

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

        // Validate LinkManagement existence
        $link_management = LinkManagement::find($id);
        if (!$link_management) {
            return $this->message('Link not found', 404);
        }
        // Authorisation checks
        $userTable = $this->getUserTable();
        if (
            ($userTable == "customer" &&
                ($link_management->workspace_id != auth()->user()->current_workspace_id || $link_management->customer_id != auth()->user()->id))
            ||
            ($userTable == "emp" &&
                ($link_management->customer_id != auth()->user()->customer_id || $link_management->workspace_id != auth()->user()->workspace_id))
        ) {
            return $this->message('You do not have access to this Link', 403);
        }
        $imagePath = null;
        if ($request->hasFile('company_logo')) {
            $imagePath = $this->handleFileImageUpload($request, 'LinkManagement', $link_management->company_logo)['path'] ?? null;
        }
        
        // Convert required_hours from time format (7:30) to decimal (7.5) if needed
        // Get value directly from request to preserve decimal precision
        $requiredHours = $request->input('required_hours');
        if ($requiredHours !== null && $requiredHours !== '') {
            $requiredHours = $this->convertTimeToDecimal($requiredHours);
            // Ensure it's a float to preserve decimal precision
            $requiredHours = is_numeric($requiredHours) ? (float) $requiredHours : null;
        } else {
            $requiredHours = null;
        }
        
        // Update the record
        $link_management->update([
            'title' => $validator->validated()['title'],
            'description' => $validator->validated()['description'],
            'role_id' => $validator->validated()['role'],
            'tier_id' => $validator->validated()['tier'],
            'name' => $validator->validated()['name'],
            'email' => $validator->validated()['email'],
            'phone' => $validator->validated()['phone'],
            'address' => $validator->validated()['address'],
            'company_name' => $validator->validated()['company_name'],
            'company_logo' => $imagePath,
            'working_days' => implode(",", $validator->validated()['working_days']),
            'number_of_days' => $validator->validated()['number_of_days'],
            'start_time' => $validator->validated()['start_time'],
            'end_time' => $validator->validated()['end_time'],
            'paid_break' => $validator->validated()['paid_break'],
            'color_code' => $validator->validated()['color_code'],
            'team_ids' => implode(",", $validator->validated()['teams']),
            'status' => '1',
            'required_hours' => $requiredHours,
            'site_id' => $validator->validated()['site_id'] ?? null,
        ]);

        return $this->message('Link Updated Successfully');
    }


    public function filter($filters, $query)
    {

        foreach ($filters as $filterName => $filterValue) {
            if ($filterValue != null ||  $filterValue != "") {
                switch ($filterName) {
                    case 'title':
                        $query->where('title', 'like', '%' . $filterValue . '%');
                        break;
                    case 'tier_id':
                        $query->where('tier_id', 'like', '%' . $filterValue . '%');
                        break;
                    case 'role_id':
                        $query->where('role_id', 'like', '%' . $filterValue . '%');
                        break;
                    case 'working_days':
                        $query->where('working_days', 'like', '%' . $filterValue . '%');
                        break;
                    case 'number_of_days':
                        $query->where('number_of_days', 'like', '%' . $filterValue . '%');
                        break;
                    case 'start_time':
                        $sTime = new DateTime($filterValue);
                        $query->where('start_time', 'like', '%' .  $sTime->format('H:i:s') . '%');
                        break;
                    case 'end_time':
                        $eTime = new DateTime($filterValue);
                        $query->where('end_time', 'like', '%' . $eTime->format('H:i:s') . '%');
                        break;
                    case 'status':
                        // Handle status filter - convert string to integer
                        if ($filterValue === 'active' || $filterValue === '1') {
                            $query->where('status', '1');
                        } elseif ($filterValue === 'inactive' || $filterValue === '0') {
                            $query->where('status', '0');
                        } else {
                            $query->where('status', 'like', '%' . $filterValue . '%');
                        }
                        break;
                    case 'team_ids':
                        // Handle team_ids filter - search in comma-separated string
                        $query->where('team_ids', 'like', '%' . $filterValue . '%');
                        break;
                    case 'name':
                        $query->where('name', 'like', '%' . $filterValue . '%');
                        break;
                    case 'email':
                        $query->where('email', 'like', '%' . $filterValue . '%');
                        break;
                    case 'phone':
                        $query->where('phone', 'like', '%' . $filterValue . '%');
                        break;
                    case 'address':
                        $query->where('address', 'like', '%' . $filterValue . '%');
                        break;
                    case 'company_name':
                        $query->where('company_name', 'like', '%' . $filterValue . '%');
                        break;
                    case 'required_hours':
                        $query->where('required_hours', 'like', '%' . $filterValue . '%');
                        break;
                }
            }
        }

        return $query;
    }

    public function link_delete(Request $request)
    {
        $id = $request->id;
        $userTable = $this->getUserTable();
        $LinkManagement = LinkManagement::find($id);

        if (!$LinkManagement) {
            // Return a JSON response with a 404 status code
            return $this->message('Link record not found.', 404);
        }

        if ($userTable == "customer" && ($LinkManagement->workspace_id != auth()->user()->current_workspace_id || $LinkManagement->customer_id != auth()->user()->id)) {
            return $this->message('You do not have access to this Link', 403);
        }

        if ($userTable == "emp" && ($LinkManagement->customer_id != auth()->user()->customer_id || $LinkManagement->workspace_id != auth()->user()->workspace_id)) {
            return $this->message('You do not have access to this Link', 403);
        }
        
        // Check if any employees are associated with this link
        $associatedEmployees = EmpCompanyDetails::where('link_key', $LinkManagement->secret_key)->count();
        if ($associatedEmployees > 0) {
            return $this->message('This subcontractor has linked employees.', 422);
        }
        
        $LinkManagement->delete();
        return $this->message('Link Deleted successfully');
    }

    public function updateStatus(Request $request)
    {
        $id = $request->id;
        $userTable = $this->getUserTable();
        $link = LinkManagement::find($id);
        if ($userTable == "customer" && ($link->workspace_id != auth()->user()->current_workspace_id || $link->customer_id != auth()->user()->id)) {
            return $this->message('You do not have access to this Link', 403);
        }
        if ($userTable == "emp" && ($link->customer_id != auth()->user()->customer_id || $link->workspace_id != auth()->user()->workspace_id)) {
            return $this->message('You do not have access to this Link', 403);
        }
        $status = $link->status == '1' ? '0' : '1';
        LinkManagement::where('id', $id)->update(['status' => $status]);
        $data['status'] = $status;

        return $this->success($data, 'Link status update Successfully');
    }

    public function generateSecretKey()
    {
        $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $length = 20;

        do {
            $secretKey = substr(str_shuffle(str_repeat($characters, ceil($length / strlen($characters)))), 0, $length);
        } while (LinkManagement::where('secret_key', $secretKey)->exists());

        return $secretKey;
    }

    /**
     * Convert time format (7:30) to decimal hours (7.5)
     * If already decimal, return as is
     * 
     * @param mixed $value
     * @return float|null
     */
    private function convertTimeToDecimal($value)
    {
        if ($value === null || $value === '') {
            return null;
        }

        // If it's a string in time format (H:i or H:i:s), convert it
        if (is_string($value) && strpos($value, ':') !== false) {
            $parts = explode(':', $value);
            if (count($parts) >= 2) {
                $hours = (int) $parts[0];
                $minutes = (int) $parts[1];
                // Convert minutes to decimal (30 minutes = 0.5 hours)
                return round($hours + ($minutes / 60), 2);
            }
        }

        // If it's already a numeric value (decimal or integer), convert to float
        // This handles both string "7.5" and numeric 7.5
        // Use number_format to ensure proper decimal handling
        if (is_numeric($value)) {
            $floatValue = (float) $value;
            // Round to 2 decimal places to match database precision
            return round($floatValue, 2);
        }

        // If it's a string that looks numeric (like "7.5"), try to convert
        if (is_string($value) && preg_match('/^-?\d+\.?\d*$/', trim($value))) {
            $floatValue = (float) trim($value);
            // Round to 2 decimal places to match database precision
            return round($floatValue, 2);
        }

        return null;
    }
}
