<?php

namespace App\Controllers\Admin;

use App\Models\Control\InvoiceModel;
use App\Models\Control\SubscriptionModel;
use App\Models\Control\TenantRecordModel;
use App\Models\Control\TransactionModel;

/**
 * Hotels (tenants) management — the "Hotels" screen from the mockup.
 * Creating a new hotel here reuses App\Libraries\TenantProvisioner (the
 * same code `php spark tenant:create` uses): provisions the DB, runs
 * every tenant migration, seeds the manager login. No duplicate
 * provisioning logic — this is a UI on top of the existing service.
 */
class TenantController extends BaseAdminController
{
    public function index()
    {
        $tenants = new TenantRecordModel();
        $subs    = new SubscriptionModel();

        $rows = $tenants->orderBy('created_at', 'desc')->findAll();

        foreach ($rows as $row) {
            $row->subscription = $subs->currentWithPlanFor($row->id);
        }

        return view('admin/tenants/index', [
            'pageTitle' => 'Hotels',
            'activeNav' => 'tenants',
            'tenants'   => $rows,
        ]);
    }

    public function show(int $id)
    {
        $tenants = new TenantRecordModel();
        $tenant  = $tenants->find($id);

        if ($tenant === null) {
            return redirect()->to('/admin/tenants')->with('error', 'Hotel not found.');
        }

        $subscription = (new SubscriptionModel())->currentWithPlanFor($id);

        return view('admin/tenants/show', [
            'pageTitle'    => $tenant->hotel_name,
            'activeNav'    => 'tenants',
            'tenant'       => $tenant,
            'subscription' => $subscription,
            'invoices'     => (new InvoiceModel())->forTenant($id),
            'transactions' => (new TransactionModel())->forTenant($id),
            'plans'        => (new \App\Models\Control\PlanModel())->active(),
        ]);
    }

    public function new()
    {
        $tenancy = config(\Config\Tenancy::class);

        return view('admin/tenants/new', [
            'pageTitle'          => 'Onboard Hotel',
            'activeNav'          => 'tenants',
            // See Config\Tenancy::$autoCreateDatabase's doc comment — on
            // shared cPanel hosting the admin must create the database
            // by hand first, so the form needs to show them exactly what
            // name to use (dbNamePrefix + whatever slug they type).
            'autoCreateDatabase' => $tenancy->autoCreateDatabase,
            'dbNamePrefix'       => $tenancy->dbNamePrefix,
        ]);
    }

    public function create()
    {
        $rules = [
            'hotel_name'     => 'required|max_length[150]',
            'slug'           => 'required|alpha_dash|max_length[63]|is_unique[tenants.slug]',
            'contact_email'  => 'permit_empty|valid_email',
            'contact_phone'  => 'permit_empty|max_length[20]',
            'admin_name'     => 'required|max_length[150]',
            'admin_email'    => 'required|valid_email',
            'admin_password' => 'required|min_length[8]',
        ];

        if (! $this->validate($rules)) {
            return redirect()->back()->withInput()->with('validation', $this->validator);
        }

        $provisioner = service('tenantProvisioner');

        try {
            $tenant = $provisioner->provision(
                $this->request->getPost('hotel_name'),
                $this->request->getPost('slug'),
                $this->request->getPost('admin_name'),
                $this->request->getPost('admin_email'),
                $this->request->getPost('admin_password'),
            );
        } catch (\Throwable $e) {
            log_message('error', 'Admin tenant provisioning failed: ' . $e->getMessage());

            return redirect()->back()->withInput()->with('error', 'Could not provision this hotel: ' . $e->getMessage());
        }

        // Provisioner doesn't set contact fields (Phase 1's spark command
        // predates them) — fill those in as a follow-up update rather than
        // widening provision()'s signature for a UI-only addition.
        (new TenantRecordModel())->update($tenant->id, [
            'contact_email' => $this->request->getPost('contact_email') ?: null,
            'contact_phone' => $this->request->getPost('contact_phone') ?: null,
        ]);

        $this->logAdminActivity('tenants', "Onboarded hotel \"{$tenant->hotel_name}\" ({$tenant->slug}).");

        return redirect()->to('/admin/tenants/' . $tenant->id)->with('success', 'Hotel onboarded. Database provisioned and manager login created.');
    }

    public function updateStatus(int $id)
    {
        $status  = $this->request->getPost('status');
        $tenants = new TenantRecordModel();
        $tenant  = $tenants->find($id);

        if ($tenant === null) {
            return redirect()->to('/admin/tenants')->with('error', 'Hotel not found.');
        }

        if (! in_array($status, ['active', 'suspended'], true)) {
            return redirect()->back()->with('error', 'Invalid status.');
        }

        $tenants->update($id, ['status' => $status]);

        $this->logAdminActivity('tenants', ucfirst($status) . " hotel \"{$tenant->hotel_name}\".");

        return redirect()->back()->with('success', "Hotel {$status}.");
    }
}
