<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Session;
use App\Services\ArticleService;
use App\Services\FournisseurService;
use App\Services\Analytics\ArticleAnalytics;

final class ArticleController extends Controller
{
    public function index(): void
    {
        $service = new ArticleService();
        $showAll = (string)Request::get('show', '') === 'all';
        $articles = $showAll ? $service->listAll() : $service->listActive();

        $this->view('articles/index', [
            'title' => 'Articles',
            'articles' => $articles,
            'totalArticles' => count($articles),
            'showAll' => $showAll,
        ]);
    }

    public function create(): void
    {
        $this->renderForm((new ArticleService())->formData(), [], 'create');
    }

    public function store(): void
    {
        $service = new ArticleService();
        $data = Request::all();
        $errors = $service->validate($data);
        if ($errors) {
            $form = $service->formData();
            $form['article'] = $data + $form['article'];
            $this->renderForm($form, $errors, 'create');
            return;
        }
        try {
            $id = $service->create($data);
            Session::flash('success', 'Article créé avec succès.');
            $this->redirect('articles_achats&id=' . $id);
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('articles_create');
        }
    }

    public function edit(): void
    {
        try {
            $this->renderForm((new ArticleService())->formData((int)Request::get('id', 0)), [], 'edit');
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('articles');
        }
    }

    public function update(): void
    {
        $service = new ArticleService();
        $id = (int)Request::post('id', 0);
        $data = Request::all();
        $errors = $service->validate($data, $id);
        if ($errors) {
            $form = $service->formData($id);
            $form['article'] = $data + $form['article'];
            $this->renderForm($form, $errors, 'edit');
            return;
        }
        try {
            $service->update($id, $data);
            Session::flash('success', 'Article modifié avec succès.');
            $this->redirect('articles_achats&id=' . $id);
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('articles_edit&id=' . $id);
        }
    }

    public function duplicate(): void
    {
        try {
            $this->renderForm((new ArticleService())->formData((int)Request::get('id', 0), true), [], 'duplicate');
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('articles');
        }
    }

    public function toggleActive(): void
    {
        try {
            $id = (int)Request::post('id', 0);
            $active = (int)Request::post('active', 0) === 1;
            (new ArticleService())->setActive($id, $active);
            Session::flash('success', $active ? 'Article réactivé.' : 'Article désactivé.');
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
        }
        $this->redirect('articles&show=all');
    }

    private function renderForm(array $form, array $errors, string $mode): void
    {
        $this->view('articles/form', [
            'title' => $mode === 'edit' ? 'Modifier article' : ($mode === 'duplicate' ? 'Dupliquer article' : 'Nouvel article'),
            'article' => $form['article'],
            'familles' => $form['familles'],
            'marques' => $form['marques'],
            'unites' => $form['unites'],
            'fournisseurs' => $form['fournisseurs'],
            'errors' => $errors,
            'mode' => $mode,
        ]);
    }

    public function achats(): void
    {
        try {
            $articleId = (int) Request::get('id', 0);
            $articleService = new ArticleService();
            $this->view('articles/achats', [
                'title' => 'Article 360°',
                'article' => $articleService->find($articleId),
                'fournisseurs' => (new FournisseurService())->listActive(),
                'analytics' => (new ArticleAnalytics())->get($articleId),
            ]);
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('articles');
        }
    }

    public function updateAchats(): void
    {
        try {
            (new ArticleService())->updatePurchasing((int) Request::post('id', 0), Request::all());
            Session::flash('success', 'Informations d’achat de l’article mises à jour.');
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
        }
        $this->redirect('articles');
    }

    public function import(): void
    {
        $this->view('articles/import', ['title' => 'Importer les articles']);
    }

    public function previewImport(): void
    {
        try {
            $result = (new ArticleService())->previewImportFile($_FILES['fichier_excel'] ?? []);
            Session::set('articles_import_file', $result['file']);
            $this->view('articles/import_preview', [
                'title' => 'Prévisualisation import articles', 'rows' => $result['rows'],
                'total' => count($result['rows']), 'mode' => Request::post('mode_import', 'upsert'),
            ]);
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('articles_import');
        }
    }

    public function confirmImport(): void
    {
        $file = Session::get('articles_import_file');
        if (!$file || !file_exists($file)) {
            Session::flash('error', 'Le fichier d’import est introuvable. Recommencez l’import.');
            $this->redirect('articles_import');
        }
        try {
            $service = new ArticleService();
            $result = $service->importRows($service->readExcel((string)$file), (string)Request::post('mode_import', 'upsert'));
            Session::forget('articles_import_file');
            Session::flash('success', $result['created'] . ' article(s) créé(s), ' . $result['updated'] . ' article(s) mis à jour.');
            $this->redirect('articles');
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('articles_import');
        }
    }
}
