<?php

namespace Modules\Sale\Controllers;

use App\Controllers\BaseController;
use App\Models\CompanyModel;
use App\Models\SalesActivityModel;
use Modules\Sale\Services\SalesActivityService;

abstract class SalesActivityController extends BaseController
{
    protected string $activityType;
    protected string $permissionGroup;
    protected string $routePrefix;
    protected string $viewFolder;
    protected string $singularLabel;
    protected string $pluralLabel;
    protected string $heroTitle;
    protected string $heroDesc;
    protected string $icon;

    protected SalesActivityModel $activities;
    protected CompanyModel $companies;
    protected SalesActivityService $service;

    public function initController(\CodeIgniter\HTTP\RequestInterface $request, \CodeIgniter\HTTP\ResponseInterface $response, \Psr\Log\LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->activities = new SalesActivityModel();
        $this->companies  = new CompanyModel();
        $this->service    = new SalesActivityService();
    }

    public function index()
    {
        $search    = trim((string) $this->request->getGet('q'));
        $status    = $this->request->getGet('status') ?: null;
        $companyId = $this->request->getGet('company_id') ?: null;

        $entries = $this->activities
            ->scopeForList($search ?: null, $this->activityType, $status, $companyId ? (int) $companyId : null)
            ->orderBy('scheduled_at', 'DESC')
            ->orderBy('due_at', 'DESC')
            ->orderBy('id', 'DESC')
            ->paginate(25);

        return view('Modules\\Sale\\Views\\' . $this->viewFolder . '\\index', array_merge($this->viewContext(), [
            'title'      => $this->pluralLabel,
            'entries'    => $entries,
            'pager'      => $this->activities->pager,
            'companies'  => $this->companies->getActive(),
            'companyMap' => $this->buildCompanyMap(),
            'filters'    => compact('search', 'status', 'companyId'),
        ]));
    }

    public function createForm()
    {
        return view('Modules\\Sale\\Views\\' . $this->viewFolder . '\\create', array_merge($this->viewContext(), [
            'title'     => 'Add ' . $this->singularLabel,
            'companies' => $this->companies->getActive(),
        ]));
    }

    public function store()
    {
        if (! $this->validate($this->validationRules())) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $input = $this->request->getPost();
        $input['activity_type'] = $this->activityType;

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

        return redirect()->to('/' . $this->routePrefix)->with('success', $this->singularLabel . ' created.');
    }

    public function editForm(int $id)
    {
        $entry = $this->findTyped($id);
        if (! $entry) {
            return redirect()->to('/' . $this->routePrefix)->with('error', $this->singularLabel . ' not found.');
        }

        return view('Modules\\Sale\\Views\\' . $this->viewFolder . '\\edit', array_merge($this->viewContext(), [
            'title'     => 'Edit ' . $this->singularLabel,
            'entry'     => $entry,
            'companies' => $this->companies->getActive(),
        ]));
    }

    public function update(int $id)
    {
        $entry = $this->findTyped($id);
        if (! $entry) {
            return redirect()->to('/' . $this->routePrefix)->with('error', $this->singularLabel . ' not found.');
        }

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

        $input = $this->request->getPost();
        $input['activity_type'] = $this->activityType;

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

        return redirect()->to('/' . $this->routePrefix)->with('success', $this->singularLabel . ' updated.');
    }

    public function complete(int $id)
    {
        $entry = $this->findTyped($id);
        if (! $entry) {
            return redirect()->to('/' . $this->routePrefix)->with('error', $this->singularLabel . ' not found.');
        }

        $result = $this->service->complete($id, (int) $this->session->get('user_id'));
        if (! $result['success']) {
            return redirect()->to('/' . $this->routePrefix)->with('error', $result['error']);
        }

        return redirect()->to('/' . $this->routePrefix)->with('success', $this->singularLabel . ' marked complete.');
    }

    public function cancel(int $id)
    {
        $entry = $this->findTyped($id);
        if (! $entry) {
            return redirect()->to('/' . $this->routePrefix)->with('error', $this->singularLabel . ' not found.');
        }

        $result = $this->service->cancel($id, (int) $this->session->get('user_id'));
        if (! $result['success']) {
            return redirect()->to('/' . $this->routePrefix)->with('error', $result['error']);
        }

        return redirect()->to('/' . $this->routePrefix)->with('success', $this->singularLabel . ' cancelled.');
    }

    public function destroy(int $id)
    {
        $entry = $this->findTyped($id);
        if (! $entry) {
            return redirect()->to('/' . $this->routePrefix)->with('error', $this->singularLabel . ' not found.');
        }

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

        return redirect()->to('/' . $this->routePrefix)->with('success', $this->singularLabel . ' deleted.');
    }

    protected function findTyped(int $id): ?array
    {
        $entry = $this->activities->find($id);
        if (! $entry || $entry['activity_type'] !== $this->activityType) {
            return null;
        }

        return $entry;
    }

    protected function validationRules(): array
    {
        return [
            'subject' => 'required|min_length[2]|max_length[200]',
            'status'  => 'permit_empty|in_list[planned,completed,cancelled]',
            'priority'=> 'permit_empty|in_list[low,normal,high]',
        ];
    }

    protected function viewContext(): array
    {
        return array_merge($this->baseViewData(), [
            'routePrefix'   => $this->routePrefix,
            'viewFolder'    => $this->viewFolder,
            'singularLabel' => $this->singularLabel,
            'pluralLabel'   => $this->pluralLabel,
            'heroTitle'     => $this->heroTitle,
            'heroDesc'      => $this->heroDesc,
            'icon'          => $this->icon,
        ]);
    }

    protected function buildCompanyMap(): array
    {
        $map = [];
        foreach ($this->companies->findAll() as $c) {
            $map[$c['id']] = $c['name'];
        }

        return $map;
    }
}
