<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Models\StudentType;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Password;
use App\Models\StudentProfile;
use App\Models\BillingAccount;
use App\Models\ParentProfile;

class StudentController extends Controller
{

	
	
    public function index()
    {
        $students = StudentProfile::with(['user', 'billingAccount'])->get();

        return view('admin.students.index', compact('students'));
    }
		
	public function create()
	{
		$parents = ParentProfile::with('user')->get();
		$studentTypes = StudentType::all();

		return view('admin.students.create', compact('parents', 'studentTypes'));
	}
	
	public function edit(StudentProfile $student)
	{
		$student->load(['user', 'billingAccount', 'billingAccount.primaryParent']);

		$parents = ParentProfile::with('user')->get();
		$studentTypes = StudentType::all();

		return view('admin.students.edit', compact('student', 'parents', 'studentTypes'));
	}
	
	public function update(Request $request, StudentProfile $student)
	{
		$validated = $request->validate([
			// Student
			'student_first_name' => 'required|string|max:255',
			'student_last_name'  => 'required|string|max:255',
			'student_phone'      => 'nullable|string|max:255',
			// If you allow changing student email:
			// 'student_email'   => ['required','email', Rule::unique('users','email')->ignore($student->user_id)],

			'date_of_birth' => 'nullable|date',
			'student_type_id' => 'required|exists:student_types,id',

			// Parent selection
			'parent_option'      => 'required|in:none,existing,new',
			'existing_parent_id' => 'required_if:parent_option,existing|nullable|exists:parent_profiles,id',

			// New parent (only used if parent_option=new)
			'parent_first_name' => 'required_if:parent_option,new|nullable|string|max:255',
			'parent_last_name'  => 'required_if:parent_option,new|nullable|string|max:255',
			'parent_email'      => 'required_if:parent_option,new|nullable|email|unique:users,email',
			'parent_phone'       => 'nullable|string|max:255',

			// Billing (match your edit form; keep minimal initially)
			'billing_account_id' => 'sometimes|nullable|exists:billing_accounts,id',
			'billing_name'       => 'required|string|max:255',
			'invoice_email'      => 'required|email',
			'billing_phone'      => 'nullable|string|max:255',
			'contact_name'       => 'nullable|string|max:255',
			'address_line1'      => 'required|string|max:255',
			'address_line2'      => 'nullable|string|max:255',
			'town'               => 'required|string|max:255',
			'postcode'           => 'required|string|max:50',
			'country'            => 'required|string|max:255',
		]);
		


		DB::beginTransaction();

		try {
			// Load student user
			$student->load('user');

			// 1) Update STUDENT USER
			$student->user->update([
				'first_name' => $validated['student_first_name'],
				'last_name'  => $validated['student_last_name'],
				'phone'      => $validated['student_phone'] ?? null,
				// 'email'   => $validated['student_email'],
			]);

			// 2) Update STUDENT PROFILE
			$student->update([
				'date_of_birth'   => $validated['date_of_birth'] ?? null,
				'student_type_id' => $validated['student_type_id'],
				// billing_account_id handled below
			]);

			// 3) Resolve parent user based on parent_option
			$parentProfile = null;

			if ($validated['parent_option'] === 'existing') {
				$parentProfile = ParentProfile::with('user')->find($validated['existing_parent_id']);
			}

			if ($validated['parent_option'] === 'new') {
				$parentUser = User::create([
					'first_name' => $validated['parent_first_name'],
					'last_name'  => $validated['parent_last_name'],
					'email'      => $validated['parent_email'],
					'phone'      => $validated['parent_phone'],
					'password'   => Hash::make(str()->random(16)),
				]);

				$parentUser->assignRole('parent');

				$parentProfile = ParentProfile::firstOrCreate(
					['user_id' => $parentUser->id],
					['phone' => $parentUser->phone]
				);

				// ensure $parentProfile has user loaded for later
				$parentProfile->load('user');
			}

			if ($parentProfile && $parentProfile->user) {
				// ensure role even for the "existing" case
				$parentProfile->user->assignRole('parent');
			}

			// 4) Billing account: update existing or create new (same logic as store)
			if (!empty($validated['billing_account_id'])) {
				$billingAccount = BillingAccount::findOrFail($validated['billing_account_id']);
				$billingAccount->update([
					'name'          => $validated['billing_name'],
					'contact_name'  => $validated['contact_name'],
					'invoice_email' => $validated['invoice_email'],
					'phone'         => $validated['billing_phone'],
					'address_line1' => $validated['address_line1'],
					'address_line2' => $validated['address_line2'],
					'town'          => $validated['town'],
					'postcode'      => $validated['postcode'],
					'country'       => $validated['country'],
					'primary_parent_user_id' => $parentProfile?->user_id,
				]);
			} else {
				$billingAccount = BillingAccount::create([
					'name'          => $validated['billing_name'],
					'contact_name'  => $validated['contact_name'],
					'invoice_email' => $validated['invoice_email'],
					'phone'         => $validated['billing_phone'],
					'address_line1' => $validated['address_line1'],
					'address_line2' => $validated['address_line2'],
					'town'          => $validated['town'],
					'postcode'      => $validated['postcode'],
					'country'       => $validated['country'],
					'primary_parent_user_id' => $parentProfile?->user_id,
				]);
			}

			if ($validated['parent_option'] === 'none') {
				$billingAccount->update(['primary_parent_user_id' => null]);
			}

			// Ensure student profile points at the billing account we just resolved
			$student->billing_account_id = $billingAccount->id;
			$student->save();

			// 5) Parent pivot handling
			if ($validated['parent_option'] === 'none') {
				$student->parents()->detach();
			} else {
				if ($parentProfile) {
					// ONE parent only:
					$student->parents()->sync([
						$parentProfile->id => [
							'relationship' => null,
							'notes' => null,
						],
					]);
				}
			}

			DB::commit();

			return redirect()
				->route('admin.students.edit', $student->id)
				->with('success', 'Student updated successfully.');

		} catch (\Exception $e) {
			DB::rollBack();
			throw $e;
		}
	}
	
	public function store(Request $request)
	{
		// -----------------------------
		// Validation
		// -----------------------------
		$validated = $request->validate([
			// Student
			'student_first_name' => 'required|string|max:255',
			'student_last_name'  => 'required|string|max:255',
			'student_email'      => 'required|email|unique:users,email',
			'student_phone'      => 'nullable|string|max:255',
			'date_of_birth' => 'nullable|date',
			'student_type_id'    => 'required|exists:student_types,id',

			// Parent selection
			'parent_option'      => 'required|in:none,existing,new',
			'existing_parent_id' => 'required_if:parent_option,existing|nullable|exists:parent_profiles,id',

			// New parent
			'parent_first_name'  => 'nullable|string|max:255',
			'parent_last_name'   => 'nullable|string|max:255',
			'parent_email'       => 'nullable|email|unique:users,email',
			'parent_phone'       => 'nullable|string|max:255',

			// Billing
			'billing_account_id' => 'sometimes|nullable|exists:billing_accounts,id',
			'billing_name'       => 'required|string|max:255',
			'invoice_email'      => 'required|email',
			'billing_phone'      => 'nullable|string|max:255',
			'contact_name'       => 'nullable|string|max:255',
			'address_line1'      => 'required|string|max:255',
			'address_line2'      => 'nullable|string|max:255',
			'town'               => 'required|string|max:255',
			'postcode'           => 'required|string|max:50',
			'country'            => 'required|string|max:255',
		]);

		DB::beginTransaction();

		try {

			// ===============================================================
			// 1) Create STUDENT USER
			// ===============================================================
			$studentUser = User::create([
				'first_name' => $validated['student_first_name'],
				'last_name'  => $validated['student_last_name'],
				'email'      => $validated['student_email'],
				'phone'      => $validated['student_phone'],
				'password'   => Hash::make(str()->random(16)), // Temporary password
			]);

			$studentUser->assignRole('student');


			// ===============================================================
			// 2) Handle PARENT selection
			// ===============================================================

			$parentProfile = null;

			if ($validated['parent_option'] === 'existing') {
				$parentProfile = ParentProfile::find($validated['existing_parent_id']);
			}

			if ($validated['parent_option'] === 'new') {
				create([
					'first_name' => $validated['parent_first_name'],
					'last_name'  => $validated['parent_last_name'],
					'email'      => $validated['parent_email'],
					'phone'      => $validated['parent_phone'],
					'password'   => Hash::make(str()->random(16)),
				]);
				$parentUser->assignRole('parent');

				$parentProfile = ParentProfile::firstOrCreate(
					['user_id' => $parentUser->id],
					['phone' => $parentUser->phone]
				);
			}

			if ($parentProfile) {
				$parentProfile->user?->assignRole('parent');
			}

			// Note: If parent_option == 'none', $parentUser remains null.


			// ===============================================================
			// 3) Create BILLING ACCOUNT
			// ===============================================================
			if (!empty($validated['billing_account_id'])) {
				// Use existing billing account
				$billingAccount = BillingAccount::find($validated['billing_account_id']);
			} else {
				$billingAccount = BillingAccount::create([
					'name'                   => $validated['billing_name'],
					'contact_name'           => $validated['contact_name'],
					'invoice_email'          => $validated['invoice_email'],
					'phone'                  => $validated['billing_phone'],
					'address_line1'          => $validated['address_line1'],
					'address_line2'          => $validated['address_line2'],
					'town'                   => $validated['town'],
					'postcode'               => $validated['postcode'],
					'country'                => $validated['country'],
					'primary_parent_user_id' => $parentProfile?->user_id,
				]);
			}

			// ===============================================================
			// 4) Create STUDENT PROFILE
			// ===============================================================
			$studentProfile = StudentProfile::create([
				'user_id'            => $studentUser->id,
				'date_of_birth'                => $validated['date_of_birth'] ?? null,
				'billing_account_id' => $billingAccount->id,
				'student_type_id'    => $validated['student_type_id'],
			]);

			// ===============================================================
			// 4B) Create/link PARENT PROFILE + pivot relationship
			// ===============================================================
			if ($parentUser) {

				// Ensure parent has role (covers "existing parent" case)
				$parentUser->assignRole('parent');

				// Ensure parent profile exists
				$parentProfile = ParentProfile::firstOrCreate(
					['user_id' => $parentUser->id],
					['phone' => $parentUser->phone] // optional default
				);

				// Link parent profile to student profile via pivot
				$studentProfile->parents()->syncWithoutDetaching([
					$parentProfile->id => [
						'relationship' => null,
						'notes' => null,
					],
				]);
			}

			// ===============================================================
			// 5) Send password setup email to student user
			// ===============================================================
			Password::sendResetLink(['email' => $studentUser->email]);


			DB::commit();

			return redirect()
				->route('admin.students.index')
				->with('success', 'Student created successfully.');

		} catch (\Exception $e) {
			DB::rollBack();
			throw $e; // (You can customise error messages later)
		}
	}	
}
