<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Session;
use App\Services\CommandeFournisseurService;

final class CommandeFournisseurController extends Controller
{
    public function index(): void
    {
        $filters = [
            'q' => trim((string)Request::get('q', '')),
            'fournisseur_id' => (int)Request::get('fournisseur_id', 0),
            'statut' => trim((string)Request::get('statut', '')),
            'archive' => trim((string)Request::get('archive', 'actives')),
        ];

        $this->view('commandes_fournisseurs/index', [
            'title' => 'Commandes fournisseurs',
            'commandes' => (new CommandeFournisseurService())->list($filters),
            'filters' => $filters,
        ]);
    }




    public function dashboard(): void
    {
        $this->view('commandes_fournisseurs/dashboard', (new CommandeFournisseurService())->purchaseDashboard() + [
            'title' => 'Tableau de bord achats',
        ]);
    }



    public function finalisation(): void
    {
        $filters = [
            'q' => trim((string)Request::get('q', '')),
            'fournisseur_id' => (int)Request::get('fournisseur_id', 0),
            'etat' => trim((string)Request::get('etat', '')),
        ];
        $this->view('commandes_fournisseurs/finalisation', (new CommandeFournisseurService())->finalisationCycle($filters) + [
            'title' => 'Finalisation du cycle fournisseurs',
        ]);
    }

    public function historique(): void
    {
        $filters = [
            'q' => trim((string)Request::get('q', '')),
            'fournisseur_id' => (int)Request::get('fournisseur_id', 0),
            'article_id' => (int)Request::get('article_id', 0),
            'date_from' => trim((string)Request::get('date_from', '')),
            'date_to' => trim((string)Request::get('date_to', '')),
        ];

        $this->view('commandes_fournisseurs/historique', (new CommandeFournisseurService())->purchaseHistory($filters) + [
            'title' => 'Historique achats',
        ]);
    }


    public function analyse(): void
    {
        $filters = [
            'q' => trim((string)Request::get('q', '')),
            'fournisseur_id' => (int)Request::get('fournisseur_id', 0),
            'marge_min' => (float)str_replace(',', '.', (string)Request::get('marge_min', 30)),
        ];

        $this->view('commandes_fournisseurs/analyse', (new CommandeFournisseurService())->purchaseAnalysis($filters) + [
            'title' => 'Analyse achats / marge',
        ]);
    }

    public function create(): void
    {
        $service = new CommandeFournisseurService();
        $data = $service->formData(null, (int)Request::get('fournisseur_id', 0));

        $this->view('commandes_fournisseurs/form', $data + [
            'title' => 'Nouvelle commande fournisseur',
            'errors' => [],
            'mode' => 'create',
        ]);
    }

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

        if (!$validator->passes()) {
            $form = $service->formData(null, (int)($data['fournisseur_id'] ?? 0));
            $this->view('commandes_fournisseurs/form', $form + [
                'title' => 'Nouvelle commande fournisseur',
                'commande' => $data + $form['commande'],
                'lines' => [],
                'errors' => $validator->errors(),
                'mode' => 'create',
            ]);
            return;
        }

        try {
            $id = $service->create($data);
            Session::flash('success', 'Commande fournisseur créée avec succès.');
            $this->redirect('commandes_fournisseurs_show&id=' . $id);
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('commandes_fournisseurs_create');
        }
    }

    public function show(): void
    {
        try {
            $data = (new CommandeFournisseurService())->findWithLines((int)Request::get('id', 0));
            $this->view('commandes_fournisseurs/show', $data + ['title' => 'Commande fournisseur']);
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('commandes_fournisseurs');
        }
    }

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

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

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

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

    public function receive(): void
    {
        try {
            $data = (new CommandeFournisseurService())->findWithLines((int)Request::get('id', 0));
            $this->view('commandes_fournisseurs/receive', $data + [
                'title' => 'Réception fournisseur',
                'errors' => [],
                'receptionNumber' => (new CommandeFournisseurService())->nextReceptionNumber(),
            ]);
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('commandes_fournisseurs');
        }
    }

    public function receptions(): void
    {
        $filters = [
            'q' => trim((string)Request::get('q', '')),
            'fournisseur_id' => (int)Request::get('fournisseur_id', 0),
            'statut' => trim((string)Request::get('statut', '')),
            'date_from' => trim((string)Request::get('date_from', '')),
            'date_to' => trim((string)Request::get('date_to', '')),
        ];
        $this->view('commandes_fournisseurs/receptions', (new CommandeFournisseurService())->receptionJournal($filters) + [
            'title' => 'Réceptions fournisseurs',
        ]);
    }

    public function cancelReception(): void
    {
        try {
            $commandeId = (new CommandeFournisseurService())->cancelReception(
                (int)Request::post('id', 0),
                (string)Request::post('motif', '')
            );
            Session::flash('success', 'Réception annulée et stock corrigé.');
            $this->redirect('commandes_fournisseurs_show&id=' . $commandeId);
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('receptions_fournisseurs');
        }
    }

    public function storeReceive(): void
    {
        $id = (int)Request::post('id', 0);

        try {
            $result = (new CommandeFournisseurService())->receive($id, Request::all());
            Session::flash('success', 'Réception fournisseur enregistrée. Stock mis à jour : ' . number_format((float)$result['stock_added'], 3, ',', ' ') . ' unité(s).');
            $this->redirect('commandes_fournisseurs_show&id=' . $id);
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('commandes_fournisseurs_receive&id=' . $id);
        }
    }

    public function deactivate(): void
    {
        try {
            (new CommandeFournisseurService())->deactivate((int)Request::post('id', 0));
            Session::flash('success', 'Commande fournisseur archivée.');
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
        }

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

    public function activate(): void
    {
        try {
            (new CommandeFournisseurService())->activate((int)Request::post('id', 0));
            Session::flash('success', 'Commande fournisseur réactivée.');
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
        }

        $this->redirect('commandes_fournisseurs&archive=archivees');
    }
}
