<?php

namespace App\Http\Controllers\SuperAdmin;

use App\Http\Controllers\Controller;
use App\Models\Addon;
use App\Models\Company;
use App\Models\OfflinePaymentMode;
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;

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)
    {
        $data = $request->validate([
            'name' => 'required|string|max:255',
            'short_name' => 'nullable|string|max:100',
            '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->update($data);
        return redirect()->route('superadmin.companies.index')->with('success', 'Company updated.');
    }

    public function changePlan(Company $company)
    {
        $plans = SubscriptionPlan::with('addons')->where('active', true)->orderBy('base_price_monthly')->get();
        $addons = Addon::orderBy('name')->get();
        $offlinePaymentModes = OfflinePaymentMode::orderBy('name')->get();
        return view('superadmin.companies.change-plan', compact('company', 'plans', 'offlinePaymentModes', 'addons'));
    }

    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' => 'required|in:monthly,yearly',
            'addon_ids' => 'nullable|array',
            'addon_ids.*' => 'integer|exists:addons,id',
            'paid_at' => 'nullable|date',
            'notes' => 'nullable|string|max:1000',
            'offline_payment_mode_id' => 'nullable|exists:offline_payment_modes,id',
        ]);

        $plan = SubscriptionPlan::findOrFail($data['subscription_plan_id']);
        $pricing = $pricingService->calculateTotal(
            $plan,
            (int) $data['employee_count'],
            $data['addon_ids'] ?? [],
            $data['billing_cycle']
        );

        $paidAt = ! empty($data['paid_at']) ? Carbon::parse($data['paid_at']) : now();

        $notes = $data['notes'] ?? '';
        $notes = trim($notes) !== '' ? trim($notes) . ' | ' : '';
        $notes .= strtoupper($pricing['billing_cycle']) . ' 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',
            'offline_payment_mode_id' => $data['offline_payment_mode_id'] ?? null,
            '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->update([
            'subscription_plan_id' => $data['subscription_plan_id'],
            'licence_expire_on' => $data['licence_expire_on'],
            'status' => 'active',
        ]);

        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,
            'login_enabled' => 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->update(['admin_id' => $adminByRole->id]);
            return $adminByRole;
        }

        return User::withoutGlobalScopes()
            ->where('company_id', $company->id)
            ->orderBy('id')
            ->first();
    }
}
