<?php

namespace App\Controllers;

use App\Models\OrganizationMembershipModel;
use App\Models\OrganizationModel;

class Organizations extends BaseController
{
    private OrganizationModel $model;
    private OrganizationMembershipModel $memberships;

    public function __construct()
    {
        $this->model = new OrganizationModel();
        $this->memberships = new OrganizationMembershipModel();
    }

    public function index()
    {
        $organizations = $this->isPlatformAdmin()
            ? $this->model->orderBy('name', 'ASC')->findAll()
            : $this->model->forUser((int) $this->authUser()['id']);

        return view('organizations/index', [
            'title' => 'Organizacoes',
            'active' => 'organizations',
            'organizations' => $organizations,
            'canCreate' => $this->isPlatformAdmin(),
            'currentOrganizationId' => $this->currentOrganizationId(),
        ]);
    }

    public function new()
    {
        if (! $this->isPlatformAdmin()) {
            return redirect()->to(site_url('organizations'))->with('error', 'Novas empresas fazem onboarding pelo registo.');
        }

        return view('organizations/form', [
            'title' => 'Nova organizacao',
            'active' => 'organizations',
            'organization' => null,
            'action' => site_url('organizations'),
            'method' => 'post',
            'isPlatformAdmin' => true,
        ]);
    }

    public function create()
    {
        if (! $this->isPlatformAdmin()) {
            return redirect()->to(site_url('organizations'))->with('error', 'Nao tens permissao para criar empresas aqui.');
        }

        $data = $this->collectData();

        if (! $this->validateData($data, $this->rules())) {
            return redirect()->back()->withInput()->with('error', 'Verifica os campos obrigatorios.');
        }

        $this->model->insert($data);

        return redirect()->to(site_url('organizations'))->with('success', 'Organizacao criada com sucesso.');
    }

    public function edit(int $id)
    {
        $organization = $this->model->find($id);
        if (! $organization || ! $this->canAccessOrganization($organization['id'])) {
            throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound('Organizacao nao encontrada.');
        }

        return view('organizations/form', [
            'title' => 'Editar organizacao',
            'active' => 'organizations',
            'organization' => $organization,
            'action' => site_url('organizations/' . $id),
            'method' => 'post',
            'isPlatformAdmin' => $this->isPlatformAdmin(),
        ]);
    }

    public function update(int $id)
    {
        $organization = $this->model->find($id);
        if (! $organization || ! $this->canAccessOrganization($organization['id'])) {
            throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound('Organizacao nao encontrada.');
        }

        if (! $this->isPlatformAdmin() && ! $this->canManageOrganization()) {
            return redirect()->to(site_url('organizations'))->with('error', 'Apenas owner/admin podem editar a empresa.');
        }

        $data = $this->collectData();
        if (! $this->validateData($data, $this->rules($id))) {
            return redirect()->back()->withInput()->with('error', 'Verifica os campos obrigatorios.');
        }

        $this->model->update($id, $data);

        return redirect()->to(site_url('organizations'))->with('success', 'Organizacao atualizada com sucesso.');
    }

    public function delete(int $id)
    {
        if (! $this->isPlatformAdmin()) {
            return redirect()->to(site_url('organizations'))->with('error', 'A remocao de empresas esta reservada ao admin da plataforma.');
        }

        $organization = $this->model->find($id);
        if (! $organization) {
            return redirect()->to(site_url('organizations'))->with('error', 'Organizacao nao encontrada.');
        }

        $this->model->delete($id);

        return redirect()->to(site_url('organizations'))->with('success', 'Organizacao removida com sucesso.');
    }

    private function collectData(): array
    {
        return [
            'name' => trim((string) $this->request->getPost('name')),
            'slug' => trim((string) $this->request->getPost('slug')),
            'organization_type' => trim((string) $this->request->getPost('organization_type')),
            'country_code' => strtoupper(trim((string) $this->request->getPost('country_code'))),
            'email' => trim((string) $this->request->getPost('email')) ?: null,
            'website' => trim((string) $this->request->getPost('website')) ?: null,
            'status' => trim((string) $this->request->getPost('status')) ?: 'active',
        ];
    }

    private function rules(?int $id = null): array
    {
        $slugRule = 'required|min_length[3]|max_length[120]|is_unique[organizations.slug]';
        if ($id !== null) {
            $slugRule = 'required|min_length[3]|max_length[120]|is_unique[organizations.slug,id,' . $id . ']';
        }

        return [
            'name' => 'required|min_length[3]|max_length[160]',
            'slug' => $slugRule,
            'organization_type' => 'required|in_list[issuer,client,partner,auditor]',
            'country_code' => 'permit_empty|exact_length[2]',
            'email' => 'permit_empty|valid_email',
            'website' => 'permit_empty|max_length[190]',
            'status' => 'required|in_list[active,inactive,pending]',
        ];
    }

    private function canAccessOrganization(int $organizationId): bool
    {
        if ($this->isPlatformAdmin()) {
            return true;
        }

        return $this->memberships->findActiveMembership((int) $this->authUser()['id'], $organizationId) !== null;
    }
}
