<?php

namespace App\Http\Controllers\PhoneBook;

use App\Http\Controllers\Controller;
use App\Models\Group;
use App\Models\Number;
use App\Helpers\Helper;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class GroupController extends Controller
{
    use Helper;

    public function __construct()
    {
        $this->model = new Group();
    }

    public function index()
    {
        if (!can('group_list_view')) {
            return $this->notPermitted();
        }

        try {
            $user = auth()->user();
            $userId = $user->id;
            $keyword = request()->input('group_name') ?: request()->input('name') ?: request()->input('keyword');

            $data = $this->model
                ->where(function ($q) use ($userId) {
                    $q->where('user_id', $userId)->orWhere('user_id', 0);
                })
                ->withCount('numbers')
                ->when($keyword, function ($query) use ($keyword) {
                    $query->where(function ($q) use ($keyword) {
                        $q->where('name', 'LIKE', "%{$keyword}%")
                          ->orWhere('description', 'LIKE', "%{$keyword}%");
                    });
                })
                ->orderBy('id', 'desc')
                ->paginate(request()->input('perPage', 20));

            return returnData(2000, $data);
        } catch (\Exception $exception) {
            return returnData(5000, $exception->getMessage(), $exception->getMessage());
        }
    }

    public function create()
    {
        //
    }

    public function store(Request $request)
    {
        if (!can('group_list_add')) {
            return $this->notPermitted();
        }

        try {
            $name = trim((string) ($request->input('name') ?: $request->input('group_name')));

            if (empty($name)) {
                return returnData(3000, ['name' => ['The group name is required.']], 'Validation Failed');
            }

            DB::beginTransaction();

            $group = new Group();
            $group->user_id = auth()->user()->id;
            $group->name = $name;
            $group->description = $request->input('description');
            $group->color = $request->input('color') ?: '#246bfd';
            $group->save();

            // Handle initial numbers addition if provided
            $numberType = (int) $request->input('number_type', 0);

            // Copy/Paste numbers
            if ($numberType === 1 && $request->filled('total_number')) {
                $rawNumbers = (string) $request->input('total_number');
                $numberLines = preg_split('/[\r\n,]+/', $rawNumbers);
                $insertedNumbers = [];

                foreach ($numberLines as $numStr) {
                    $cleaned = preg_replace('/[^\d+]/', '', trim($numStr));
                    if (!empty($cleaned)) {
                        $insertedNumbers[] = [
                            'user_id' => auth()->user()->id,
                            'group_id' => $group->id,
                            'name' => null,
                            'number' => $cleaned,
                            'notes' => null,
                            'created_at' => now(),
                            'updated_at' => now(),
                        ];
                    }
                }

                if (!empty($insertedNumbers)) {
                    Number::insert($insertedNumbers);
                }
            }

            // Excel uploaded numbers
            if ($numberType === 2 && $request->has('numbers')) {
                $excelData = $request->input('numbers');
                if (is_array($excelData)) {
                    $randomKey = $excelData['random_number'] ?? null;
                    if ($randomKey) {
                        Number::where('notes', 'LIKE', "%{$randomKey}%")
                            ->orWhere('group_id', 0)
                            ->where('user_id', auth()->user()->id)
                            ->update(['group_id' => $group->id]);
                    }
                }
            }

            DB::commit();

            return returnData(2000, $group, 'Group Created Successfully');
        } catch (\Exception $exception) {
            DB::rollBack();
            return returnData(5000, $exception->getMessage(), $exception->getMessage());
        }
    }

    public function show($id)
    {
        try {
            $perPage = (int) request()->input('perPage', 30);
            $keyword = request()->input('number') ?: request()->input('keyword') ?: request()->input('phone');
            $userId = auth()->user()->id;

            $data = Number::where('group_id', $id)
                ->where(function ($q) use ($userId) {
                    $q->where('user_id', $userId)->orWhere('user_id', 0);
                })
                ->when($keyword, function ($query) use ($keyword) {
                    $query->where(function ($q) use ($keyword) {
                        $q->where('number', 'LIKE', "%{$keyword}%")
                          ->orWhere('name', 'LIKE', "%{$keyword}%")
                          ->orWhere('notes', 'LIKE', "%{$keyword}%");
                    });
                })
                ->orderBy('id', 'DESC')
                ->paginate($perPage);

            return returnData(2000, $data);
        } catch (\Exception $exception) {
            return returnData(5000, $exception->getMessage(), $exception->getMessage());
        }
    }

    public function edit($id)
    {
        //
    }

    public function update(Request $request, $id)
    {
        if (!can('group_list_update')) {
            return $this->notPermitted();
        }

        try {
            $userId = auth()->user()->id;
            $group = Group::where('id', $id)
                ->where(function ($q) use ($userId) {
                    $q->where('user_id', $userId)->orWhere('user_id', 0);
                })->first();

            if (!$group) {
                return returnData(5000, null, 'Group not found');
            }

            $op = $request->input('operation');

            // Add number to existing group
            if ($op === 'add_number') {
                $rawPhone = $request->input('phone') ?: $request->input('number');
                $cleanPhone = preg_replace('/[^\d+]/', '', trim((string) $rawPhone));

                if (empty($cleanPhone)) {
                    return returnData(3000, ['number' => ['Phone number is invalid or empty.']], 'Invalid Phone Number');
                }

                $contactName = $request->input('name');
                $notes = $request->input('notes');

                $number = Number::create([
                    'user_id' => $userId,
                    'group_id' => $group->id,
                    'name' => $contactName ? trim((string) $contactName) : null,
                    'number' => $cleanPhone,
                    'notes' => $notes ? trim((string) $notes) : null,
                ]);

                return returnData(2000, $number, 'Number Successfully Added to Group');
            }

            // Update Group details
            $name = trim((string) ($request->input('name') ?: $request->input('group_name')));
            if (empty($name)) {
                return returnData(3000, ['name' => ['The group name is required.']], 'Validation Failed');
            }

            DB::beginTransaction();

            $group->name = $name;
            if ($request->has('description')) {
                $group->description = $request->input('description');
            }
            if ($request->has('color')) {
                $group->color = $request->input('color') ?: '#246bfd';
            }
            $group->save();

            DB::commit();

            return returnData(2000, $group, 'Group Successfully Updated');
        } catch (\Exception $exception) {
            DB::rollBack();
            return returnData(5000, $exception->getMessage(), $exception->getMessage());
        }
    }

    public function destroy($id)
    {
        if (!can('group_list_delete')) {
            return $this->notPermitted();
        }

        try {
            $userId = auth()->user()->id;
            $group = Group::where('id', $id)
                ->where(function ($q) use ($userId) {
                    $q->where('user_id', $userId)->orWhere('user_id', 0);
                })->first();

            if (!$group) {
                return returnData(5000, null, 'Group not found');
            }

            DB::beginTransaction();

            $deleteNumbers = request()->has('delete_numbers')
                ? filter_var(request()->input('delete_numbers'), FILTER_VALIDATE_BOOLEAN)
                : true;

            if ($deleteNumbers) {
                // Delete numbers associated with this group
                Number::where('group_id', $group->id)->delete();
            } else {
                // Unlink numbers associated with this group
                Number::where('group_id', $group->id)->update(['group_id' => null]);
            }

            $group->delete();

            DB::commit();

            return returnData(2000, $group, 'Group successfully deleted');
        } catch (\Exception $exception) {
            DB::rollBack();
            return returnData(5000, $exception->getMessage(), 'Whoops, Something Went Wrong..!!');
        }
    }

    public function delete_single_number($id)
    {
        try {
            $userId = auth()->user()->id;
            $number = Number::where('id', $id)
                ->where(function ($q) use ($userId) {
                    $q->where('user_id', $userId)->orWhere('user_id', 0);
                })->first();

            if (!$number) {
                return returnData(5000, null, 'Number not found');
            }

            $number->delete();

            return returnData(2000, null, 'Successfully Deleted');
        } catch (\Exception $exception) {
            return returnData(5000, $exception->getMessage(), 'Whoops, Something Went Wrong..!!');
        }
    }
}
