<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Session;
use App\Services\ClientImportService;
use App\Services\ClientService;
use App\Services\TarifClientService;

final class ClientController extends Controller
{
    public function index(): void
    {
        $service = new ClientService();
        $clients = $service->listActive();

        $this->view('clients/index', [
            'title' => 'Clients',
            'clients' => $clients,
            'totalClients' => count($clients),
        ]);
    }

    public function create(): void
    {
        $data = (new ClientService())->formData();

        $this->view('clients/form', [
            'title' => 'Nouveau client',
            'client' => $data['client'],
            'typesClients' => $data['typesClients'],
            'errors' => [],
            'mode' => 'create',
        ]);
    }

    public function store(): void
    {
        $service = new ClientService();
        $data = Request::all();
        $validator = $service->validator($data);

        if (!$validator->passes()) {
            $form = $service->formData();
            $this->view('clients/form', [
                'title' => 'Nouveau client',
                'client' => $data + $form['client'],
                'typesClients' => $form['typesClients'],
                'errors' => $validator->errors(),
                'mode' => 'create',
            ]);
            return;
        }

        $id = $service->create($data);
        Session::flash('success', 'Client créé avec succès.');
        $this->redirect('clients_show&id=' . $id);
    }

    public function show(): void
    {
        try {
            $data = (new ClientService())->findWithHistory((int) Request::get('id', 0));
            $tarifsData = (new TarifClientService())->formDataForClient((int) $data['client']['id']);
            $this->view('clients/show', [
                'title' => 'Fiche client',
                'client' => $data['client'],
                'history' => $data['history'],
                'tarifsClients' => $tarifsData['tarifs'],
                'articlesTarifs' => $tarifsData['articles'],
            ]);
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('clients');
        }
    }

    public function edit(): void
    {
        try {
            $data = (new ClientService())->formData((int) Request::get('id', 0));
            $this->view('clients/form', [
                'title' => 'Modifier client',
                'client' => $data['client'],
                'typesClients' => $data['typesClients'],
                'errors' => [],
                'mode' => 'edit',
            ]);
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('clients');
        }
    }

    public function update(): void
    {
        $service = new ClientService();
        $id = (int) Request::post('id', 0);
        $data = Request::all();
        $validator = $service->validator($data);

        if (!$validator->passes()) {
            $form = $service->formData($id);
            $this->view('clients/form', [
                'title' => 'Modifier client',
                'client' => $data + $form['client'],
                'typesClients' => $form['typesClients'],
                'errors' => $validator->errors(),
                'mode' => 'edit',
            ]);
            return;
        }

        try {
            $service->update($id, $data);
            Session::flash('success', 'Client modifié avec succès.');
            $this->redirect('clients_show&id=' . $id);
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('clients');
        }
    }

    public function deactivate(): void
    {
        try {
            (new ClientService())->deactivate((int) Request::post('id', 0));
            Session::flash('success', 'Client désactivé.');
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
        }

        $this->redirect('clients');
    }

    public function import(): void
    {
        $this->view('clients/import', [
            'title' => 'Import clients Excel',
            'errors' => [],
            'preview' => null,
            'token' => null,
            'result' => null,
        ]);
    }

    public function importPreview(): void
    {
        $errors = [];
        $preview = null;
        $token = null;

        try {
            if (!isset($_FILES['client_file']) || ($_FILES['client_file']['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
                throw new \RuntimeException('Veuillez sélectionner un fichier Excel .xlsx.');
            }

            $filename = (string) ($_FILES['client_file']['name'] ?? '');
            $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
            if ($extension !== 'xlsx') {
                throw new \RuntimeException('Pour cette version, le fichier doit être au format .xlsx.');
            }

            $service = new ClientImportService();
            $preview = $service->preview((string) $_FILES['client_file']['tmp_name']);
            $token = $service->savePreview($preview);
        } catch (\Throwable $e) {
            $errors[] = $e->getMessage();
        }

        $this->view('clients/import', [
            'title' => 'Import clients Excel',
            'errors' => $errors,
            'preview' => $preview,
            'token' => $token,
            'result' => null,
        ]);
    }

    public function importExecute(): void
    {
        $errors = [];
        $result = null;
        $preview = null;
        $token = (string) Request::post('token', '');
        $mode = (string) Request::post('mode', 'skip');

        try {
            if ($token === '') {
                throw new \RuntimeException('Jeton d\'import manquant. Recommencez la prévisualisation.');
            }
            if (!in_array($mode, ['skip', 'update'], true)) {
                $mode = 'skip';
            }

            $service = new ClientImportService();
            $preview = $service->loadPreview($token);
            $result = $service->import($token, $mode);
            Session::flash('success', 'Import terminé : ' . $result['created'] . ' créé(s), ' . $result['updated'] . ' mis à jour, ' . $result['ignored'] . ' ignoré(s).');
        } catch (\Throwable $e) {
            $errors[] = $e->getMessage();
        }

        $this->view('clients/import', [
            'title' => 'Import clients Excel',
            'errors' => $errors,
            'preview' => $preview,
            'token' => $token,
            'result' => $result,
        ]);
    }
}
