<?php

namespace App\Controllers;

use App\Models\OrganizationMembershipModel;
use App\Models\UserModel;

class Team extends BaseController
{
    private OrganizationMembershipModel $memberships;
    private UserModel $users;

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

    public function index()
    {
        if ($redirect = $this->requireOrganizationContext()) {
            return $redirect;
        }

        return view('team/index', [
            'title' => 'Equipa',
            'active' => 'team',
            'members' => $this->memberships->teamForOrganization((int) $this->currentOrganizationId()),
            'canManageTeam' => $this->canManageOrganization(),
        ]);
    }

    public function new()
    {
        if ($redirect = $this->requireOrganizationContext()) {
            return $redirect;
        }

        if (! $this->canManageOrganization()) {
            return redirect()->to(site_url('team'))->with('error', 'Apenas owner/admin podem gerir a equipa.');
        }

        return view('team/form', [
            'title' => 'Novo membro',
            'active' => 'team',
            'action' => site_url('team'),
            'member' => null,
        ]);
    }

    public function create()
    {
        if ($redirect = $this->requireOrganizationContext()) {
            return $redirect;
        }

        if (! $this->canManageOrganization()) {
            return redirect()->to(site_url('team'))->with('error', 'Apenas owner/admin podem gerir a equipa.');
        }

        $data = [
            'name' => trim((string) $this->request->getPost('name')),
            'email' => trim((string) $this->request->getPost('email')),
            'role' => trim((string) $this->request->getPost('role')) ?: 'member',
            'password' => (string) $this->request->getPost('password'),
        ];

        $rules = [
            'name' => 'required|min_length[3]|max_length[140]',
            'email' => 'required|valid_email',
            'role' => 'required|in_list[owner,admin,manager,member,viewer,auditor]',
            'password' => 'required|min_length[8]',
        ];

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

        $existingUser = $this->users->findByEmail($data['email']);

        if ($existingUser) {
            $existingMembership = $this->memberships
                ->where('organization_id', $this->currentOrganizationId())
                ->where('user_id', $existingUser['id'])
                ->first();

            if ($existingMembership) {
                return redirect()->back()->withInput()->with('error', 'Esse utilizador ja pertence a esta empresa.');
            }

            $userId = (int) $existingUser['id'];
        } else {
            $userId = (int) $this->users->insert([
                'name' => $data['name'],
                'email' => $data['email'],
                'password_hash' => password_hash($data['password'], PASSWORD_DEFAULT),
                'role' => 'user',
                'status' => 'active',
            ], true);
        }

        $this->memberships->insert([
            'organization_id' => (int) $this->currentOrganizationId(),
            'user_id' => $userId,
            'role' => $data['role'],
            'status' => 'active',
            'invited_by_user_id' => (int) $this->authUser()['id'],
            'joined_at' => date('Y-m-d H:i:s'),
        ]);

        return redirect()->to(site_url('team'))->with('success', 'Membro adicionado a equipa com sucesso.');
    }

    public function edit(int $membershipId)
    {
        if ($redirect = $this->requireOrganizationContext()) {
            return $redirect;
        }

        if (! $this->canManageOrganization()) {
            return redirect()->to(site_url('team'))->with('error', 'Apenas owner/admin podem gerir a equipa.');
        }

        $member = $this->findTeamMember($membershipId);
        if (! $member) {
            throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound('Membro nao encontrado.');
        }

        return view('team/form', [
            'title' => 'Editar membro',
            'active' => 'team',
            'action' => site_url('team/' . $membershipId),
            'member' => $member,
        ]);
    }

    public function update(int $membershipId)
    {
        if ($redirect = $this->requireOrganizationContext()) {
            return $redirect;
        }

        if (! $this->canManageOrganization()) {
            return redirect()->to(site_url('team'))->with('error', 'Apenas owner/admin podem gerir a equipa.');
        }

        $member = $this->findTeamMember($membershipId);
        if (! $member) {
            throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound('Membro nao encontrado.');
        }

        $data = [
            'name' => trim((string) $this->request->getPost('name')),
            'email' => trim((string) $this->request->getPost('email')),
            'role' => trim((string) $this->request->getPost('role')) ?: 'member',
            'status' => trim((string) $this->request->getPost('status')) ?: 'active',
            'password' => (string) $this->request->getPost('password'),
        ];

        $rules = [
            'name' => 'required|min_length[3]|max_length[140]',
            'email' => 'required|valid_email|is_unique[users.email,id,' . (int) $member['user_id'] . ']',
            'role' => 'required|in_list[owner,admin,manager,member,viewer,auditor]',
            'status' => 'required|in_list[active,inactive]',
            'password' => 'permit_empty|min_length[8]',
        ];

        if (! $this->validateData($data, $rules)) {
            return redirect()->back()
                ->withInput()
                ->with('errors', $this->validator->getErrors())
                ->with('error', 'Revista os dados do membro.');
        }

        if (($member['role'] ?? '') === 'owner' && (($data['role'] !== 'owner') || ($data['status'] !== 'active')) && $this->ownerCount() <= 1) {
            return redirect()->back()->withInput()->with('error', 'A empresa precisa de pelo menos um owner ativo.');
        }

        if ((int) $member['user_id'] === (int) $this->authUser()['id'] && $data['status'] !== 'active') {
            return redirect()->back()->withInput()->with('error', 'Não podes desativar a tua própria membership nesta área.');
        }

        $userUpdate = [
            'name' => $data['name'],
            'email' => $data['email'],
        ];

        if ($data['password'] !== '') {
            $userUpdate['password_hash'] = password_hash($data['password'], PASSWORD_DEFAULT);
        }

        $this->users->update((int) $member['user_id'], $userUpdate);
        $this->memberships->update($membershipId, [
            'role' => $data['role'],
            'status' => $data['status'],
        ]);

        if ((int) $member['user_id'] === (int) $this->authUser()['id']) {
            $freshUser = $this->users->find((int) $member['user_id']);
            session()->set('auth_user', [
                'id' => $freshUser['id'],
                'name' => $freshUser['name'],
                'email' => $freshUser['email'],
                'role' => $freshUser['role'],
            ]);
        }

        return redirect()->to(site_url('team'))->with('success', 'Membro atualizado com sucesso.');
    }

    public function delete(int $membershipId)
    {
        if ($redirect = $this->requireOrganizationContext()) {
            return $redirect;
        }

        if (! $this->canManageOrganization()) {
            return redirect()->to(site_url('team'))->with('error', 'Apenas owner/admin podem gerir a equipa.');
        }

        $member = $this->findTeamMember($membershipId);
        if (! $member) {
            throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound('Membro nao encontrado.');
        }

        if ((int) $member['user_id'] === (int) $this->authUser()['id']) {
            return redirect()->to(site_url('team'))->with('error', 'Usa a tua conta para editar o teu perfil. Não podes remover-te da empresa aqui.');
        }

        if (($member['role'] ?? '') === 'owner' && $this->ownerCount() <= 1) {
            return redirect()->to(site_url('team'))->with('error', 'A empresa precisa de pelo menos um owner ativo.');
        }

        $this->memberships->delete($membershipId);

        return redirect()->to(site_url('team'))->with('success', 'Membro removido da equipa com sucesso.');
    }

    private function findTeamMember(int $membershipId): ?array
    {
        return $this->memberships
            ->select('organization_memberships.*, users.name, users.email, users.last_login_at')
            ->join('users', 'users.id = organization_memberships.user_id')
            ->where('organization_memberships.id', $membershipId)
            ->where('organization_memberships.organization_id', (int) $this->currentOrganizationId())
            ->first();
    }

    private function ownerCount(): int
    {
        return $this->memberships
            ->where('organization_id', (int) $this->currentOrganizationId())
            ->where('role', 'owner')
            ->where('status', 'active')
            ->countAllResults();
    }
}

