<?php
declare(strict_types=1);

namespace App\Controllers;

use App\Core\Auth;
use App\Core\Request;
use App\Industry\Catalog;
use App\Models\AuditLog;
use App\Models\CustomerUser;
use App\Models\Integration;
use App\Models\MarketingConnection;
use App\Services\CommerceService;
use App\Services\IndustryService;
use App\Services\SmartTipsService;
use App\Services\TimezoneService;

final class SettingsController extends BaseController
{
    public function index(Request $request): void
    {
        $this->requireModule('settings');
        $uid = (int) Auth::instance()->id();
        $rows = Integration::forUser($uid);
        $map = [];
        foreach ($rows as $r) {
            $map[$r['provider'] . '_' . $r['kind']] = $r;
        }
        view('settings/index', [
            'title' => 'Settings',
            'integrations' => $map,
            'marketingConnections' => has_role('admin') ? MarketingConnection::allForTenant() : [],
            'industries' => Catalog::all(),
            'currentIndustry' => Catalog::currentCode(),
            'isAdmin' => has_role('admin'),
            'commerce' => has_role('admin') ? CommerceService::settings() : null,
            'portalPages' => has_role('admin') ? CommerceService::tenantPages() : [],
            'customerUsers' => has_role('admin') ? CustomerUser::allForTenant() : [],
            'accounts' => has_role('admin') ? \App\Models\Account::allForSelect() : [],
            'smartTipsOn' => SmartTipsService::enabled(),
            'timezone' => has_role('admin') ? TimezoneService::current() : null,
            'timezoneOptions' => has_role('admin') ? TimezoneService::options(TimezoneService::current()) : [],
            'notifications' => $this->notifications(),
        ]);
    }

    public function connect(Request $request): void
    {
        $this->requireModule('settings');
        $this->verifyCsrf($request);
        $provider = (string) $request->input('provider');
        $kind = (string) $request->input('kind');
        $status = (string) $request->input('status', 'connected');
        if (!in_array($provider, ['outlook', 'gmail'], true) || !in_array($kind, ['email', 'calendar'], true)) {
            json_out(['ok' => false, 'error' => 'Invalid connection.'], 422);
        }
        if ($status !== 'disconnected' && !has_role('admin')) {
            json_out(['ok' => false, 'error' => 'Ask an admin to turn this on.'], 403);
        }
        Integration::upsert((int) Auth::instance()->id(), $provider, $kind, $status === 'disconnected' ? 'disconnected' : 'connected');
        AuditLog::write('integration.' . $status, 'integration', null, compact('provider', 'kind'));
        json_out(['ok' => true]);
    }

    public function industry(Request $request): void
    {
        $this->requireModule('industry');
        $this->verifyCsrf($request);
        $code = (string) $request->input('industry_code');
        if (!Catalog::isValid($code)) {
            json_out(['ok' => false, 'error' => 'Pick setup A, B, C, or D.'], 422);
        }
        IndustryService::apply($code);
        json_out(['ok' => true, 'message' => 'Industry setup saved. Deal stages now match that business.']);
    }

    public function timezone(Request $request): void
    {
        $this->requireModule('settings');
        if (!has_role('admin')) {
            json_out(['ok' => false, 'error' => 'Only an admin can set company time.'], 403);
        }
        $this->verifyCsrf($request);
        $tz = (string) $request->input('timezone');
        if (!TimezoneService::isValid($tz)) {
            json_out(['ok' => false, 'error' => 'Pick a valid time zone.'], 422);
        }
        TimezoneService::save($tz);
        AuditLog::write('tenant.timezone', 'tenant', Auth::instance()->tenantId(), ['timezone' => $tz]);
        json_out(['ok' => true, 'message' => 'Company time saved. Home and due dates now use this zone.']);
    }

    public function tips(Request $request): void
    {
        $this->requireModule('settings');
        if (!has_role('admin')) {
            json_out(['ok' => false, 'error' => 'Only an admin can turn smart tips on or off.'], 403);
        }
        $this->verifyCsrf($request);
        $on = (string) $request->input('status') === 'on';
        SmartTipsService::setEnabled($on);
        AuditLog::write('smart_tips.' . ($on ? 'on' : 'off'), 'tenant', Auth::instance()->tenantId());
        json_out(['ok' => true, 'message' => $on ? 'Smart tips are on.' : 'Smart tips are off.']);
    }

    public function marketingConnect(Request $request): void
    {
        $this->requireModule('marketing_connect');
        $this->verifyCsrf($request);
        $provider = (string) $request->input('provider');
        $status = (string) $request->input('status', 'connected');
        if (!in_array($provider, ['mailchimp', 'constant_contact', 'outlook', 'gmail'], true)) {
            json_out(['ok' => false, 'error' => 'Unknown email tool.'], 422);
        }
        if (!in_array($status, ['connected', 'disconnected'], true)) {
            json_out(['ok' => false, 'error' => 'Invalid status.'], 422);
        }
        MarketingConnection::upsert($provider, $status);
        AuditLog::write('marketing_connection.' . $status, 'marketing_connection', null, compact('provider'));
        json_out(['ok' => true]);
    }

    public function portal(Request $request): void
    {
        $this->requireModule('customer_portal');
        $this->verifyCsrf($request);
        $pages = $request->input('pages');
        $pages = is_array($pages) ? $pages : [];
        $systems = $request->input('systems');
        $systems = is_array($systems) ? $systems : [];
        \App\Models\TenantCommerce::save(
            (string) $request->input('customer_portal_on') === '1',
            $pages,
            $systems
        );
        AuditLog::write('portal.settings', 'tenant', Auth::instance()->tenantId());
        json_out(['ok' => true, 'message' => 'Customer Portal settings saved.']);
    }

    public function system(Request $request): void
    {
        $this->requireModule('integrations');
        $this->verifyCsrf($request);
        $key = (string) $request->input('system');
        if (!isset(CommerceService::SYSTEMS[$key])) {
            json_out(['ok' => false, 'error' => 'Unknown system.'], 422);
        }
        $row = CommerceService::settings();
        $systems = $row['systems'] ?? [];
        $systems[$key] = (string) $request->input('status') === 'connected' ? 'connected' : 'disconnected';
        \App\Models\TenantCommerce::save(
            !empty($row['customer_portal_on']),
            $row['customer_pages'] ?? [],
            $systems
        );
        AuditLog::write('system.' . $systems[$key], 'integration', null, ['system' => $key]);
        json_out(['ok' => true]);
    }

    public function customerUser(Request $request): void
    {
        $this->requireModule('customer_portal');
        $this->verifyCsrf($request);
        $data = $request->all();
        $v = (new \App\Core\Validator())
            ->required($data, ['account_id' => 'Account', 'email' => 'Email', 'first_name' => 'First name', 'last_name' => 'Last name'])
            ->email($data, 'email', 'Email', false);
        if ($v->fails()) {
            $this->fail($v);
        }
        $email = strtolower((string) $data['email']);
        if (CustomerUser::emailTaken($email)) {
            json_out(['ok' => false, 'error' => 'That customer email already has a login.'], 422);
        }
        $account = \App\Models\Account::find((int) $data['account_id']);
        if (!$account) {
            json_out(['ok' => false, 'error' => 'Account not found.'], 404);
        }
        $password = (string) ($_POST['password'] ?? '');
        if (strlen($password) < (int) config('security.password_min_length', 8)) {
            json_out(['ok' => false, 'error' => 'Password must be at least 8 characters.'], 422);
        }
        $id = CustomerUser::create([
            'account_id' => (int) $account['id'],
            'email' => $email,
            'password_hash' => password_hash($password, PASSWORD_DEFAULT),
            'first_name' => $data['first_name'],
            'last_name' => $data['last_name'],
            'status' => 'active',
        ]);
        AuditLog::write('customer_user.create', 'customer_user', $id);
        json_out(['ok' => true, 'message' => 'Customer login created. They use the Customer Portal, not this website.']);
    }

    public function customerUserToggle(Request $request): void
    {
        $this->requireModule('customer_portal');
        $this->verifyCsrf($request);
        $row = CustomerUser::find((int) $request->param('id'));
        if (!$row) {
            json_out(['ok' => false, 'error' => 'Not found.'], 404);
        }
        CustomerUser::update((int) $row['id'], [
            'status' => $row['status'] === 'active' ? 'inactive' : 'active',
        ]);
        json_out(['ok' => true]);
    }
}
