<?php

namespace App\Http\Controllers\SuperAdmin;

use App\Http\Controllers\Controller;
use App\Models\Company;
use App\Models\SubscriptionPayment;
use App\Models\SubscriptionPlan;
use App\Models\User;
use App\Services\PlanPricingService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rule;

class CompanyController extends Controller
{
    public function index(Request $request)
    {
        $query = Company::with('subscriptionPlan');
        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }
        if ($request->filled('search')) {
            $query->where(function ($q) use ($request) {
                $q->where('name', 'like', '%' . $request->search . '%')
                    ->orWhere('email', 'like', '%' . $request->search . '%')
                    ->orWhere('short_name', 'like', '%' . $request->search . '%');
            });
        }
        $companies = $query->orderByDesc('created_at')->paginate(15)->withQueryString();
        return view('superadmin.companies', compact('companies'));
    }

    public function edit(Company $company)
    {
        $company->load('users.role');
        $plans = SubscriptionPlan::orderBy('base_price_monthly')->get();
        $adminUser = $this->resolveCompanyAdminUser($company);
        return view('superadmin.companies.edit', compact('company', 'plans', 'adminUser'));
    }

    public function update(Request $request, Company $company)
    {
        if ($request->has('short_name')) {
            $request->merge([
                'short_name' => Company::normalizeShortName($request->input('short_name')),
            ]);
        }

        $data = $request->validate([
            'name' => 'required|string|max:255',
            'short_name' => [
                'nullable',
                'string',
                'max:100',
                Rule::unique('companies', 'short_name')->ignore($company->id),
            ],
            'email' => 'nullable|email',
            'phone' => 'nullable|string|max:50',
            'website' => 'nullable|string|max:255',
            'address' => 'nullable|string',
            'status' => 'required|in:active,inactive,suspended',
            'subscription_plan_id' => 'nullable|exists:subscription_plans,id',
            'licence_expire_on' => 'nullable|date',
            'trial_ends_at' => 'nullable|date',
        ]);
        $company->fill(collect($data)->only([
            'name', 'short_name', 'email', 'phone', 'website', 'address',
        ])->all());
        $company->forceFill(collect($data)->only([
            'status', 'subscription_plan_id', 'licence_expire_on', 'trial_ends_at',
        ])->all())->save();

        return redirect()->route('superadmin.companies.index')->with('success', 'Company updated.');
    }

    public function changePlan(Company $company)
    {
        $company->loadMissing('subscriptionPlan');
        $plans = SubscriptionPlan::query()
            ->where('active', true)
            ->orderBy('base_price_yearly')
            ->orderBy('name')
            ->get();

        return view('superadmin.companies.change-plan', compact('company', 'plans'));
    }

    public function storeChangePlan(Request $request, Company $company, PlanPricingService $pricingService)
    {
        $data = $request->validate([
            'subscription_plan_id' => 'required|exists:subscription_plans,id',
            'licence_expire_on' => 'required|date',
            'employee_count' => 'required|integer|min:1',
            'billing_cycle' => 'nullable|in:yearly',
            'paid_at' => 'nullable|date',
            'notes' => 'nullable|string|max:1000',
        ]);

        $plan = SubscriptionPlan::findOrFail($data['subscription_plan_id']);
        $pricing = $pricingService->calculateTotal(
            $plan,
            (int) $data['employee_count'],
            [],
            'yearly'
        );

        $paidAt = ! empty($data['paid_at']) ? Carbon::parse($data['paid_at']) : now();

        $notes = $data['notes'] ?? '';
        $notes = trim($notes) !== '' ? trim($notes) . ' | ' : '';
        $notes .= 'YEARLY cycle';

        SubscriptionPayment::create([
            'company_id' => $company->id,
            'employee_count' => $pricing['employee_count'],
            'amount' => $pricing['total'],
            'calculated_total' => $pricing['total'],
            'currency' => config('app.currency_code', 'INR'),
            'selected_addons' => $pricing['selected_addons'],
            'payment_method' => 'offline',
            'status' => 'completed',
            'paid_at' => $paidAt,
            'notes' => $notes,
            'meta' => [
                'billing_cycle' => $pricing['billing_cycle'],
                'base_price' => $pricing['base_price'],
                'employee_cost' => $pricing['employee_cost'],
                'addons_total' => $pricing['addons_total'],
            ],
            'recorded_by' => Auth::id(),
        ]);

        $company->forceFill([
            'subscription_plan_id' => $data['subscription_plan_id'],
            'licence_expire_on' => $data['licence_expire_on'],
            'status' => 'active',
        ])->save();

        return redirect()->route('superadmin.companies.index')->with('success', 'Plan updated and payment recorded.');
    }

    public function updateAdminPassword(Request $request, Company $company)
    {
        $data = $request->validate([
            'password' => ['nullable', 'string', 'min:8', 'max:100', 'confirmed'],
            'reset' => ['nullable', 'in:1'],
        ]);

        $adminUser = $this->resolveCompanyAdminUser($company);
        if (! $adminUser) {
            return back()->with('error', 'No company admin user found for this company.');
        }

        $isReset = ($data['reset'] ?? null) === '1';
        $newPassword = $isReset ? 'Welcome@123' : ($data['password'] ?? '');

        if (! $isReset && $newPassword === '') {
            return back()->with('error', 'Please enter a new password.');
        }

        $adminUser->update([
            'password' => Hash::make($newPassword),
            'allow_login' => true,
            'status' => 'active',
        ]);

        $message = $isReset
            ? "Password reset for {$adminUser->email}. Temporary password: Welcome@123"
            : "Password updated successfully for {$adminUser->email}.";

        return back()->with('success', $message);
    }

    private function resolveCompanyAdminUser(Company $company): ?User
    {
        if ($company->admin_id) {
            $admin = User::withoutGlobalScopes()->find($company->admin_id);
            if ($admin && (int) $admin->company_id === (int) $company->id) {
                return $admin;
            }
        }

        $adminByRole = User::withoutGlobalScopes()
            ->where('company_id', $company->id)
            ->whereHas('role', fn ($query) => $query->where('name', 'admin'))
            ->orderBy('id')
            ->first();

        if ($adminByRole) {
            $company->forceFill(['admin_id' => $adminByRole->id])->save();
            return $adminByRole;
        }

        return User::withoutGlobalScopes()
            ->where('company_id', $company->id)
            ->orderBy('id')
            ->first();
    }
}
