<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Core\Controller;
use App\Core\Session;
use App\Models\Document;
use App\Repositories\ArticleRepository;
use App\Services\DocumentManager;
use App\Services\DocumentEngine;
use App\Services\TarifClientService;

final class DocumentController extends Controller
{
    public function index(): void
    {
        $model = new Document();
        $filters = [
            'type' => trim((string)($_GET['type'] ?? '')),
            'q' => trim((string)($_GET['q'] ?? '')),
        ];

        $this->view('documents/index', [
            'title' => 'Documents commerciaux',
            'documents' => $model->all($filters),
            'counts' => $model->countByType(),
            'filters' => $filters,
            'documentManager' => new DocumentManager(),
            'tablesReady' => $model->tableExists('documents') && $model->tableExists('documents_lignes'),
        ]);
    }

    public function create(): void
    {
        $type = strtoupper(trim((string)($_GET['type'] ?? 'DEVIS')));
        $manager = new DocumentManager();
        if (!in_array($type, $manager->allowedTypes(), true)) {
            $type = 'DEVIS';
        }

        $model = new Document();
        $this->view('documents/form', [
            'title' => 'Nouveau ' . strtolower($manager->typeLabel($type)),
            'type' => $type,
            'numero' => $manager->nextNumber($type),
            'today' => date('Y-m-d'),
            'dateEcheance' => $type === 'FACTURE' ? date('Y-m-d', strtotime('+30 days')) : '',
            'clients' => $model->clientsForSelect(),
            'articles' => (new ArticleRepository())->pickerActive(),
            'tarifsClients' => (new TarifClientService())->documentTarifsMap(),
            'documentManager' => $manager,
        ]);
    }



    public function sources(): void
    {
        $sourceType = strtoupper(trim((string)($_GET['source_type'] ?? 'DEVIS')));
        $targetType = strtoupper(trim((string)($_GET['target_type'] ?? 'BL')));
        $manager = new DocumentManager();

        if (!$manager->canTransform($sourceType, $targetType)) {
            Session::set('error', 'Transformation non autorisée.');
            $this->redirect('documents');
            return;
        }

        $model = new Document();
        $this->view('documents/sources', [
            'title' => 'Créer ' . strtolower($manager->typeLabel($targetType)) . ' depuis ' . strtolower($manager->typeLabel($sourceType)),
            'sourceType' => $sourceType,
            'targetType' => $targetType,
            'documents' => $model->sourcesForTransformation($sourceType, $targetType),
            'documentManager' => $manager,
        ]);
    }

    public function store(): void
    {
        try {
            $manager = new DocumentManager();
            $id = $manager->create($_POST);
            Session::set('success', 'Document créé avec succès.');
            $this->redirect('documents_show&id=' . $id);
        } catch (\Throwable $e) {
            Session::set('error', $e->getMessage());
            $type = urlencode((string)($_POST['type_document'] ?? 'DEVIS'));
            $this->redirect('documents_create&type=' . $type);
        }
    }

    public function show(): void
    {
        $id = (int)($_GET['id'] ?? 0);
        $model = new Document();
        $document = $model->find($id);

        if (!$document) {
            $this->view('errors/404', ['title' => 'Document introuvable']);
            return;
        }

        $manager = new DocumentManager();
        $this->view('documents/show', [
            'title' => 'Document ' . $document['numero'],
            'document' => $document,
            'lines' => $model->lines($id),
            'children' => $model->children($id),
            'relatedDocuments' => $model->relatedDocuments($id),
            'transformTargets' => $manager->transformTargets((string)$document['type_document']),
            'documentManager' => $manager,
        ]);
    }


    public function pdf(): void
    {
        $id = (int)($_GET['id'] ?? 0);
        $model = new Document();
        $document = $model->find($id);

        if (!$document) {
            $this->view('errors/404', ['title' => 'Document introuvable']);
            return;
        }

        (new DocumentEngine())->streamDocument($document, $model->lines($id));
    }

    public function edit(): void
    {
        $id = (int)($_GET['id'] ?? 0);
        try {
            $manager = new DocumentManager();
            $data = $manager->prepareForEdit($id);
            $model = new Document();
            $document = $data['document'];

            $this->view('documents/form', [
                'title' => 'Modifier ' . $document['numero'],
                'mode' => 'edit',
                'document' => $document,
                'existingLines' => $data['lignes'],
                'type' => (string)$document['type_document'],
                'numero' => (string)$document['numero'],
                'today' => (string)$document['date_document'],
                'dateEcheance' => (string)($document['date_echeance'] ?? ''),
                'clients' => $model->clientsForSelect(),
                'articles' => (new ArticleRepository())->pickerActive(),
                'tarifsClients' => (new TarifClientService())->documentTarifsMap(),
                'documentManager' => $manager,
            ]);
        } catch (\Throwable $exception) {
            Session::set('error', $exception->getMessage());
            $this->redirect('documents_show&id=' . $id);
        }
    }

    public function update(): void
    {
        $id = (int)($_POST['id'] ?? 0);
        try {
            (new DocumentManager())->updateInvoice($id, $_POST);
            Session::set('success', 'Facture modifiée avec succès.');
            $this->redirect('documents_show&id=' . $id);
        } catch (\Throwable $exception) {
            Session::set('error', $exception->getMessage());
            $this->redirect('documents_edit&id=' . $id);
        }
    }

    public function transform(): void
    {
        $id = (int)($_POST['id'] ?? 0);
        $targetType = strtoupper(trim((string)($_POST['target_type'] ?? '')));
        try {
            $manager = new DocumentManager();
            $newId = $manager->transform($id, $targetType);
            Session::set('success', 'Document transformé avec succès.');
            $this->redirect('documents_show&id=' . $newId);
        } catch (\Throwable $e) {
            Session::set('error', $e->getMessage());
            $this->redirect('documents_show&id=' . $id);
        }
    }
}
