<?php

namespace Modules\Sale\Controllers;

use App\Controllers\BaseController;
use App\Models\LeadModel;
use App\Models\LeadSourceModel;
use Modules\Auth\Models\UserModel;
use Modules\Sale\Services\LeadService;

class LeadController extends BaseController
{
    protected LeadModel $leads;
    protected LeadSourceModel $sources;
    protected UserModel $users;
    protected LeadService $service;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->leads   = new LeadModel();
        $this->sources = new LeadSourceModel();
        $this->users   = new UserModel();
        $this->service = new LeadService();
    }

    public function index()
    {
        $search     = trim((string) $this->request->getGet('q'));
        $status     = $this->request->getGet('status') ?: null;
        $sourceId   = $this->request->getGet('source_id') ?: null;
        $assignedTo = $this->request->getGet('assigned_to') ?: null;
        $priority   = $this->request->getGet('priority') ?: null;

        $leads = $this->leads
            ->scopeForList(
                $search ?: null,
                $status,
                $sourceId ? (int) $sourceId : null,
                $assignedTo ? (int) $assignedTo : null,
                $priority,
                true
            )
            ->orderBy('created_at', 'DESC')
            ->paginate(20);

        return view('Modules\Sale\Views\leads\index', array_merge($this->baseViewData(), [
            'title'      => 'New Leads',
            'leads'      => $leads,
            'pager'      => $this->leads->pager,
            'sources'    => $this->sources->getActive(),
            'users'      => $this->getActiveUsers(),
            'sourceMap'  => $this->buildSourceMap(),
            'userMap'    => $this->buildUserMap(),
            'filters'    => compact('search', 'status', 'sourceId', 'assignedTo', 'priority'),
        ]));
    }

    public function createForm()
    {
        return view('Modules\Sale\Views\leads\create', array_merge($this->baseViewData(), [
            'title'   => 'Add Lead',
            'sources' => $this->sources->getActive(),
            'users'   => $this->getActiveUsers(),
        ]));
    }

    public function store()
    {
        if (! $this->validate([
            'first_name' => 'required|min_length[1]|max_length[100]',
            'last_name'  => 'required|min_length[1]|max_length[100]',
            'email'      => 'permit_empty|valid_email',
        ])) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $result = $this->service->create($this->request->getPost(), (int) $this->session->get('user_id'));
        if (! $result['success']) {
            return redirect()->back()->withInput()->with('errors', $result['errors']);
        }

        return redirect()->to('/sale/leads/' . $result['id'])->with('success', 'Lead created.');
    }

    public function show(int $id)
    {
        $lead = $this->leads->find($id);
        if (! $lead) {
            return redirect()->to('/sale/leads')->with('error', 'Lead not found.');
        }

        $source = $lead['lead_source_id'] ? $this->sources->find($lead['lead_source_id']) : null;
        $assignee = $lead['assigned_to'] ? $this->users->find($lead['assigned_to']) : null;

        return view('Modules\Sale\Views\leads\show', array_merge($this->baseViewData(), [
            'title'    => 'Lead #' . $id,
            'lead'     => $lead,
            'source'   => $source,
            'assignee' => $assignee,
        ]));
    }

    public function editForm(int $id)
    {
        $lead = $this->leads->find($id);
        if (! $lead) {
            return redirect()->to('/sale/leads')->with('error', 'Lead not found.');
        }

        if ($lead['status'] === 'converted') {
            return redirect()->to('/sale/leads/' . $id)->with('error', 'Converted leads cannot be edited.');
        }

        return view('Modules\Sale\Views\leads\edit', array_merge($this->baseViewData(), [
            'title'   => 'Edit Lead',
            'lead'    => $lead,
            'sources' => $this->sources->getActive(),
            'users'   => $this->getActiveUsers(),
        ]));
    }

    public function update(int $id)
    {
        if (! $this->validate([
            'first_name' => 'required|min_length[1]|max_length[100]',
            'last_name'  => 'required|min_length[1]|max_length[100]',
            'email'      => 'permit_empty|valid_email',
        ])) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $result = $this->service->update($id, $this->request->getPost(), (int) $this->session->get('user_id'));
        if (! $result['success']) {
            return redirect()->back()->withInput()->with('errors', $result['errors']);
        }

        return redirect()->to('/sale/leads/' . $id)->with('success', 'Lead updated.');
    }

    public function destroy(int $id)
    {
        $result = $this->service->delete($id, (int) $this->session->get('user_id'));
        if (! $result['success']) {
            return redirect()->to('/sale/leads')->with('error', $result['error']);
        }

        return redirect()->to('/sale/leads')->with('success', 'Lead deleted.');
    }

    protected function getActiveUsers(): array
    {
        return $this->users->where('status', 'active')->orderBy('first_name', 'ASC')->findAll();
    }

    protected function buildSourceMap(): array
    {
        $map = [];
        foreach ($this->sources->findAll() as $s) {
            $map[$s['id']] = $s['name'];
        }

        return $map;
    }

    protected function buildUserMap(): array
    {
        $map = [];
        foreach ($this->getActiveUsers() as $u) {
            $map[$u->id] = $u->getFullName();
        }

        return $map;
    }
}
