<?php

declare(strict_types=1);

namespace App\Controllers;

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

final class FactureFournisseurController 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', '')),
            'etat' => trim((string)Request::get('etat', 'actives')),
        ];

        $this->view('factures_fournisseurs/index', (new FactureFournisseurService())->list($filters) + [
            'title' => 'Factures fournisseurs',
        ]);
    }


    public function dashboard(): void
    {
        $this->view('factures_fournisseurs/dashboard', (new FactureFournisseurService())->dashboard() + [
            'title' => 'Tableau de bord fournisseurs',
        ]);
    }


    public function finalisation(): void
    {
        $this->view('factures_fournisseurs/finalisation', (new FactureFournisseurService())->finalisation() + [
            'title' => 'Finalisation fournisseurs',
        ]);
    }

    public function echeancier(): void
    {
        $filters = [
            'fournisseur_id' => (int)Request::get('fournisseur_id', 0),
            'periode' => trim((string)Request::get('periode', 'toutes')),
            'date_debut' => trim((string)Request::get('date_debut', '')),
            'date_fin' => trim((string)Request::get('date_fin', '')),
        ];

        $this->view('factures_fournisseurs/echeancier', (new FactureFournisseurService())->echeancier($filters) + [
            'title' => 'Échéancier fournisseurs',
        ]);
    }

    public function createFromCommande(): void
    {
        try {
            $data = (new FactureFournisseurService())->formData((int)Request::get('commande_id', 0));
            $this->view('factures_fournisseurs/form', $data + [
                'title' => 'Enregistrement d’une facture fournisseur reçue',
                'errors' => [],
            ]);
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('factures_fournisseurs');
        }
    }

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

        if (!$validator->passes()) {
            Session::flash('error', implode(' ', $validator->errors()));
            $commandeId = (int)($data['commande_fournisseur_id'] ?? 0);
            $this->redirect('factures_fournisseurs_create' . ($commandeId > 0 ? '&commande_id=' . $commandeId : ''));
        }

        try {
            $id = $service->create($data);
            Session::flash('success', 'Facture fournisseur créée avec succès.');
            $this->redirect('factures_fournisseurs_show&id=' . $id);
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $commandeId = (int)($data['commande_fournisseur_id'] ?? 0);
            $this->redirect('factures_fournisseurs_create' . ($commandeId > 0 ? '&commande_id=' . $commandeId : ''));
        }
    }

    public function edit(): void
    {
        try { $this->view('factures_fournisseurs/form',(new FactureFournisseurService())->editData((int)Request::get('id',0))+['title'=>'Modifier la facture fournisseur','errors'=>[]]); }
        catch (\Throwable $e) { Session::flash('error',$e->getMessage()); $this->redirect('factures_fournisseurs'); }
    }

    public function update(): void
    {
        $id=(int)Request::post('id',0);
        try { (new FactureFournisseurService())->update($id,Request::all()); Session::flash('success','Facture fournisseur modifiée.'); $this->redirect('factures_fournisseurs_show&id='.$id); }
        catch (\Throwable $e) { Session::flash('error',$e->getMessage()); $this->redirect('factures_fournisseurs_edit&id='.$id); }
    }

    public function justificatif(): void
    {
        try {
            $f=(new FactureFournisseurService())->find((int)Request::get('id',0))['facture'];
            if (empty($f['justificatif_fichier'])) throw new \RuntimeException('Aucun justificatif.');
            $path=dirname(__DIR__,2).'/storage/documents/factures-fournisseurs/'.basename((string)$f['justificatif_fichier']);
            if (!is_file($path)) throw new \RuntimeException('Fichier justificatif introuvable.');
            header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="'.basename((string)$f['justificatif_nom']).'"'); header('Content-Length: '.filesize($path)); readfile($path); exit;
        } catch (\Throwable $e) { Session::flash('error',$e->getMessage()); $this->redirect('factures_fournisseurs'); }
    }

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


    public function reglement(): void
    {
        try {
            $this->view('factures_fournisseurs/reglement', (new FactureFournisseurService())->reglementFormData((int)Request::get('id', 0)) + [
                'title' => 'Règlement fournisseur',
                'errors' => [],
            ]);
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('factures_fournisseurs');
        }
    }

    public function storeReglement(): void
    {
        $service = new FactureFournisseurService();
        $factureId = (int)Request::post('facture_fournisseur_id', 0);
        $data = Request::all();
        $validator = $service->reglementValidator($data);

        if (!$validator->passes()) {
            Session::flash('error', implode(' ', $validator->errors()));
            $this->redirect('factures_fournisseurs_reglement&id=' . $factureId);
        }

        try {
            $service->addReglement($factureId, $data);
            Session::flash('success', 'Règlement fournisseur enregistré avec succès.');
            $this->redirect('factures_fournisseurs_show&id=' . $factureId);
        } catch (\Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('factures_fournisseurs_reglement&id=' . $factureId);
        }
    }

    public function reglements(): void
    {
        $filters = ['fournisseur_id' => (int)Request::get('fournisseur_id', 0), 'mode_reglement' => trim((string)Request::get('mode_reglement', '')), 'date_debut' => trim((string)Request::get('date_debut', '')), 'date_fin' => trim((string)Request::get('date_fin', '')), 'etat' => trim((string)Request::get('etat', 'actifs'))];
        $this->view('factures_fournisseurs/reglements', (new FactureFournisseurService())->journalReglements($filters) + ['title' => 'Règlements fournisseurs']);
    }

    public function annulerReglement(): void
    {
        try {
            $factureId = (new FactureFournisseurService())->annulerReglement((int)Request::post('id', 0), trim((string)Request::post('motif', '')));
            Session::flash('success', 'Règlement fournisseur annulé. Les totaux de la facture ont été recalculés.');
            $this->redirect('factures_fournisseurs_show&id=' . $factureId);
        } catch (\Throwable $e) { Session::flash('error', $e->getMessage()); $this->redirect('reglements_fournisseurs'); }
    }

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

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

    public function reactivate(): void
    {
        try { (new FactureFournisseurService())->reactivate((int)Request::post('id',0)); Session::flash('success','Facture fournisseur réactivée.'); }
        catch (\Throwable $e) { Session::flash('error',$e->getMessage()); }
        $this->redirect('factures_fournisseurs&etat=annulees');
    }
}
