<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Session;
use App\Services\DevisService;
use App\Services\DocumentEngine;
use App\Services\DocumentCycleService;
use App\Services\DocumentMailHistoryService;
use Throwable;

final class DevisController extends Controller
{
    public function index(): void
    {
        $this->view('devis/index', [
            'title' => 'Devis',
            'devis' => (new DevisService())->list(),
        ]);
    }

    public function create(): void
    {
        $data = (new DevisService())->createFormData();
        $this->view('devis/form', ['title' => 'Nouveau devis'] + $data);
    }

    public function store(): void
    {
        try {
            $id = (new DevisService())->create(Request::all());
            (new DocumentCycleService())->log('DEVIS', $id, 'CREATION', 'Devis créé');
            Session::flash('success', 'Devis créé avec succès.');
            $this->redirect('devis_show&id=' . $id);
        } catch (Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('devis_create');
        }
    }

    public function edit(): void
    {
        try {
            $id = (int) Request::get('id', 0);
            $data = (new DevisService())->editFormData($id);
            $this->view('devis/form', ['title' => 'Modifier le devis ' . $data['devis']['numero']] + $data);
        } catch (Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('devis');
        }
    }

    public function update(): void
    {
        $id = (int) Request::post('id', 0);
        try {
            (new DevisService())->update($id, Request::all());
            (new DocumentCycleService())->log('DEVIS', $id, 'MODIFICATION', 'Devis modifié');
            Session::flash('success', 'Devis modifié avec succès.');
            $this->redirect('devis_show&id=' . $id);
        } catch (Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('devis_edit&id=' . $id);
        }
    }

    public function duplicate(): void
    {
        try {
            $newId = (new DevisService())->duplicate((int) Request::post('id', 0));
            (new DocumentCycleService())->log('DEVIS', $newId, 'DUPLICATION', 'Devis créé par duplication');
            Session::flash('success', 'Devis dupliqué avec succès.');
            $this->redirect('devis_show&id=' . $newId);
        } catch (Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('devis');
        }
    }

    public function pdf(): void
    {
        try {
            $data = (new DevisService())->findWithLines((int) Request::get('id', 0));
            (new DocumentEngine())->streamDevis($data['devis'], $data['lignes']);
        } catch (Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('devis');
        }
    }

    public function show(): void
    {
        try {
            $data = (new DevisService())->findWithLines((int) Request::get('id', 0));
            $this->view('devis/show', [
                'title' => 'Devis ' . $data['devis']['numero'],
                'devis' => $data['devis'],
                'lignes' => $data['lignes'],
                'lastMailDelivery' => (new DocumentMailHistoryService())
                    ->last('DEVIS', (int)$data['devis']['id']),
                'cycleLinks' => ($cycle = new DocumentCycleService())->links('DEVIS', (int)$data['devis']['id']),
                'cycleHistory' => $cycle->forDocument('DEVIS', (int)$data['devis']['id']),
                'cycleStatus' => $cycle->status('DEVIS', $data['devis'], $cycle->links('DEVIS', (int)$data['devis']['id'])),
            ]);
        } catch (Throwable $exception) {
            Session::flash('error', $exception->getMessage());
            $this->redirect('devis');
        }
    }
}
