<?php

namespace App\Services;

use Maatwebsite\Excel\Concerns\FromView;
use Maatwebsite\Excel\Concerns\WithStyles;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\Border;

class TemplateService implements FromView, WithStyles, WithColumnFormatting
{
    protected $columns;
    protected $requiredColumns;
    protected $relationships;
    protected $exampleData;

    public function __construct($columns, $requiredColumns = [], $relationships = [], $exampleData = [])
    {
        $this->columns = $columns;
        $this->requiredColumns = $requiredColumns;
        $this->relationships = $relationships;
        $this->exampleData = $exampleData;
    }

    public function view(): \Illuminate\Contracts\View\View
    {
        return view('excel.template', [
            'columns' => $this->columns,
            'requiredColumns' => $this->requiredColumns,
            'relationships' => $this->relationships,
            'exampleData' => $this->exampleData,
        ]);
    }

    public function styles(Worksheet $sheet)
    {
        $columnCount = count($this->columns);
        
        // Header row styling
        $headerRange = 'A1:' . $this->getColumnLetter($columnCount) . '1';
        
        return [
            $headerRange => [
                'font' => [
                    'bold' => true,
                    'size' => 12,
                    'color' => ['rgb' => 'FFFFFF'],
                ],
                'fill' => [
                    'fillType' => Fill::FILL_SOLID,
                    'startColor' => ['rgb' => '4472C4'],
                ],
                'alignment' => [
                    'horizontal' => Alignment::HORIZONTAL_CENTER,
                    'vertical' => Alignment::VERTICAL_CENTER,
                ],
                'borders' => [
                    'allBorders' => [
                        'borderStyle' => Border::BORDER_THIN,
                        'color' => ['rgb' => '000000'],
                    ],
                ],
            ],
        ];
    }

    public function columnFormats(): array
    {
        $formats = [];
        
        foreach ($this->columns as $index => $column) {
            $columnLetter = $this->getColumnLetter($index + 1);
            
            if (isset($column['type']) && $column['type'] === 'numeric') {
                $formats[$columnLetter] = NumberFormat::FORMAT_NUMBER;
            } elseif (isset($column['type']) && $column['type'] === 'date') {
                $formats[$columnLetter] = NumberFormat::FORMAT_DATE_DDMMYYYY;
            } elseif (isset($column['type']) && $column['type'] === 'email') {
                $formats[$columnLetter] = NumberFormat::FORMAT_TEXT;
            }
        }
        
        return $formats;
    }

    protected function getColumnLetter($index)
    {
        $letter = '';
        while ($index > 0) {
            $index--;
            $letter = chr(65 + ($index % 26)) . $letter;
            $index = floor($index / 26);
        }
        return $letter;
    }

    public function generateTemplate($model, $filename)
    {
        $columns = $this->getModelColumns($model);
        $requiredColumns = $this->getRequiredColumns($model);
        $relationships = $this->getModelRelationships($model);
        $exampleData = $this->getExampleData($model);

        $template = new self($columns, $requiredColumns, $relationships, $exampleData);

        return \Maatwebsite\Excel\Facades\Excel::download($template, $filename);
    }

    protected function getModelColumns($model)
    {
        $columnsMap = [
            'inspecteur' => [
                ['name' => 'id', 'label' => 'ID', 'type' => 'numeric', 'required' => false],
                ['name' => 'nomfr', 'label' => 'Nom (Français)', 'type' => 'text', 'required' => true],
                ['name' => 'nomar', 'label' => 'Nom (Arabe)', 'type' => 'text', 'required' => true],
                ['name' => 'matricule', 'label' => 'Matricule', 'type' => 'text', 'required' => true],
                ['name' => 'nni', 'label' => 'NNI', 'type' => 'text', 'required' => true],
                ['name' => 'date_naissance', 'label' => 'Date de naissance', 'type' => 'date', 'required' => true],
                ['name' => 'lieu_naissance_ar', 'label' => 'Lieu de naissance (Arabe)', 'type' => 'text', 'required' => true],
                ['name' => 'lieu_naissance_fr', 'label' => 'Lieu de naissance (Français)', 'type' => 'text', 'required' => true],
                ['name' => 'date_affectation', 'label' => 'Date d\'affectation', 'type' => 'date', 'required' => true],
                ['name' => 'contact', 'label' => 'Contact', 'type' => 'text', 'required' => true],
                ['name' => 'date_mise_en_corps_IES', 'label' => 'Date mise en corps IES', 'type' => 'date', 'required' => false],
                ['name' => 'bank', 'label' => 'Banque', 'type' => 'text', 'required' => false],
                ['name' => 'compte', 'label' => 'Compte', 'type' => 'text', 'required' => false],
                ['name' => 'email', 'label' => 'Email', 'type' => 'email', 'required' => true],
                ['name' => 'matrimonialite', 'label' => 'Matrimonialité', 'type' => 'text', 'required' => false],
                ['name' => 'date_recri_fp', 'label' => 'Date recrutement FP', 'type' => 'date', 'required' => false],
                ['name' => 'photo', 'label' => 'Photo', 'type' => 'text', 'required' => false],
                ['name' => 'discipline_id', 'label' => 'Discipline', 'type' => 'relationship', 'required' => true],
                ['name' => 'pole_id', 'label' => 'Pôle', 'type' => 'relationship', 'required' => true],
            ],
            'professeur' => [
                ['name' => 'id', 'label' => 'ID', 'type' => 'numeric', 'required' => false],
                ['name' => 'nomar', 'label' => 'Nom (Arabe)', 'type' => 'text', 'required' => true],
                ['name' => 'nomfr', 'label' => 'Nom (Français)', 'type' => 'text', 'required' => true],
                ['name' => 'matricule', 'label' => 'Matricule', 'type' => 'text', 'required' => true],
                ['name' => 'nni', 'label' => 'NNI', 'type' => 'text', 'required' => true],
                ['name' => 'date_naissance', 'label' => 'Date de naissance', 'type' => 'date', 'required' => true],
                ['name' => 'lieu_naissance_ar', 'label' => 'Lieu de naissance (Arabe)', 'type' => 'text', 'required' => true],
                ['name' => 'lieu_naissance_fr', 'label' => 'Lieu de naissance (Français)', 'type' => 'text', 'required' => true],
                ['name' => 'discipline_origine', 'label' => 'Discipline d\'origine', 'type' => 'text', 'required' => true],
                ['name' => 'contact', 'label' => 'Contact', 'type' => 'text', 'required' => true],
                ['name' => 'statut_id', 'label' => 'Statut', 'type' => 'relationship', 'required' => true],
                ['name' => 'cycle_id', 'label' => 'Cycle', 'type' => 'relationship', 'required' => true],
                ['name' => 'photo', 'label' => 'Photo', 'type' => 'text', 'required' => false],
                ['name' => 'date_recritement', 'label' => 'Date de recrutement', 'type' => 'date', 'required' => false],
            ],
            'etablissement' => [
                ['name' => 'id', 'label' => 'ID', 'type' => 'numeric', 'required' => false],
                ['name' => 'libellear', 'label' => 'Libellé (Arabe)', 'type' => 'text', 'required' => true],
                ['name' => 'libellefr', 'label' => 'Libellé (Français)', 'type' => 'text', 'required' => true],
                ['name' => 'cycle_id', 'label' => 'Cycle', 'type' => 'relationship', 'required' => true],
                ['name' => 'code', 'label' => 'Code', 'type' => 'text', 'required' => true],
                ['name' => 'latitude', 'label' => 'Latitude', 'type' => 'numeric', 'required' => false],
                ['name' => 'longitude', 'label' => 'Longitude', 'type' => 'numeric', 'required' => false],
                ['name' => 'etat', 'label' => 'État', 'type' => 'text', 'required' => false],
                ['name' => 'commune_id', 'label' => 'Commune', 'type' => 'relationship', 'required' => true],
            ],
            'rapport' => [
                ['name' => 'id', 'label' => 'ID', 'type' => 'numeric', 'required' => false],
                ['name' => 'date_inspection', 'label' => 'Date d\'inspection', 'type' => 'date', 'required' => true],
                ['name' => 'classe_visitee', 'label' => 'Classe visitée', 'type' => 'text', 'required' => true],
                ['name' => 'passation', 'label' => 'Passation', 'type' => 'text', 'required' => false],
                ['name' => 'titre_lecon', 'label' => 'Titre de la leçon', 'type' => 'text', 'required' => true],
                ['name' => 'deroulement', 'label' => 'Déroulement', 'type' => 'text', 'required' => false],
                ['name' => 'appreciation_generale', 'label' => 'Appréciation générale', 'type' => 'text', 'required' => false],
                ['name' => 'numero_ordre', 'label' => 'Numéro d\'ordre', 'type' => 'numeric', 'required' => true],
                ['name' => 'note', 'label' => 'Note', 'type' => 'numeric', 'required' => true],
                ['name' => 'etablissement_id', 'label' => 'Établissement', 'type' => 'relationship', 'required' => true],
                ['name' => 'professeur_id', 'label' => 'Professeur', 'type' => 'relationship', 'required' => true],
                ['name' => 'inspecteur_id', 'label' => 'Inspecteur', 'type' => 'relationship', 'required' => true],
                ['name' => 'nombre_eleve', 'label' => 'Nombre d\'élèves', 'type' => 'numeric', 'required' => false],
                ['name' => 'present', 'label' => 'Présents', 'type' => 'numeric', 'required' => false],
                ['name' => 'horaire', 'label' => 'Horaire', 'type' => 'text', 'required' => false],
            ],
            'infrastructure' => [
                ['name' => 'id', 'label' => 'ID', 'type' => 'numeric', 'required' => false],
                ['name' => 'type_infrastructure_id', 'label' => 'Type d\'infrastructure', 'type' => 'relationship', 'required' => true],
                ['name' => 'nombre_movais', 'label' => 'Nombre movais', 'type' => 'numeric', 'required' => true],
                ['name' => 'nombre_moyens', 'label' => 'Nombre moyens', 'type' => 'numeric', 'required' => true],
                ['name' => 'nombre_bons', 'label' => 'Nombre bons', 'type' => 'numeric', 'required' => true],
                ['name' => 'etablissement_id', 'label' => 'Établissement', 'type' => 'relationship', 'required' => true],
                ['name' => 'annee_id', 'label' => 'Année', 'type' => 'relationship', 'required' => true],
            ],
            'structure_pedagogique' => [
                ['name' => 'id', 'label' => 'ID', 'type' => 'numeric', 'required' => false],
                ['name' => 'niveau_id', 'label' => 'Niveau', 'type' => 'relationship', 'required' => true],
                ['name' => 'nombre_section', 'label' => 'Nombre de sections', 'type' => 'numeric', 'required' => true],
                ['name' => 'nombre_eleves', 'label' => 'Nombre d\'élèves', 'type' => 'numeric', 'required' => true],
                ['name' => 'nombre_filles', 'label' => 'Nombre de filles', 'type' => 'numeric', 'required' => true],
                ['name' => 'etablissement_id', 'label' => 'Établissement', 'type' => 'relationship', 'required' => true],
                ['name' => 'annee_id', 'label' => 'Année', 'type' => 'relationship', 'required' => true],
            ],
            'reforme' => [
                ['name' => 'id', 'label' => 'ID', 'type' => 'numeric', 'required' => false],
                ['name' => 'libelle', 'label' => 'Libellé', 'type' => 'text', 'required' => true],
                ['name' => 'description', 'label' => 'Description', 'type' => 'text', 'required' => false],
                ['name' => 'date_debut', 'label' => 'Date de début', 'type' => 'date', 'required' => true],
                ['name' => 'date_fin', 'label' => 'Date de fin', 'type' => 'date', 'required' => false],
            ],
            'niveau' => [
                ['name' => 'id', 'label' => 'ID', 'type' => 'numeric', 'required' => false],
                ['name' => 'libelle', 'label' => 'Libellé', 'type' => 'text', 'required' => true],
                ['name' => 'cycle_id', 'label' => 'Cycle', 'type' => 'relationship', 'required' => true],
            ],
            'volume_horaire' => [
                ['name' => 'id', 'label' => 'ID', 'type' => 'numeric', 'required' => false],
                ['name' => 'libelle', 'label' => 'Libellé', 'type' => 'text', 'required' => true],
                ['name' => 'volume_horaire', 'label' => 'Volume horaire', 'type' => 'numeric', 'required' => true],
            ],
            'progression' => [
                ['name' => 'id', 'label' => 'ID', 'type' => 'numeric', 'required' => false],
                ['name' => 'numero_lecon', 'label' => 'Numéro de leçon', 'type' => 'numeric', 'required' => true],
                ['name' => 'chapitre', 'label' => 'Chapitre', 'type' => 'text', 'required' => true],
                ['name' => 'titre_lecon', 'label' => 'Titre de la leçon', 'type' => 'text', 'required' => true],
                ['name' => 'numero_semaine', 'label' => 'Numéro de semaine', 'type' => 'numeric', 'required' => true],
                ['name' => 'discipline_id', 'label' => 'Discipline', 'type' => 'relationship', 'required' => true],
            ],
        ];

        return $columnsMap[$model] ?? [];
    }

    protected function getRequiredColumns($model)
    {
        $columns = $this->getModelColumns($model);
        return array_filter($columns, fn($col) => $col['required'] ?? false);
    }

    protected function getModelRelationships($model)
    {
        $relationshipsMap = [
            'inspecteur' => [
                'pole_id' => ['model' => 'App\\Models\\Pole', 'field' => 'libelle'],
                'discipline_id' => ['model' => 'App\\Models\\Discipline', 'field' => 'libelle'],
            ],
            'professeur' => [
                'statut_id' => ['model' => 'App\\Models\\Statut', 'field' => 'libelle'],
                'cycle_id' => ['model' => 'App\\Models\\Cycle', 'field' => 'libelle'],
            ],
            'etablissement' => [
                'cycle_id' => ['model' => 'App\\Models\\Cycle', 'field' => 'libelle'],
                'commune_id' => ['model' => 'App\\Models\\Commune', 'field' => 'libelle'],
            ],
            'infrastructure' => [
                'type_infrastructure_id' => ['model' => 'App\\Models\\TypeInfrastructure', 'field' => 'libelle'],
                'etablissement_id' => ['model' => 'App\\Models\\Etablissement', 'field' => 'libellefr'],
                'annee_id' => ['model' => 'App\\Models\\Annee', 'field' => 'libelle'],
            ],
            'structure_pedagogique' => [
                'niveau_id' => ['model' => 'App\\Models\\Niveau', 'field' => 'libelle'],
                'etablissement_id' => ['model' => 'App\\Models\\Etablissement', 'field' => 'libellefr'],
                'annee_id' => ['model' => 'App\\Models\\Annee', 'field' => 'libelle'],
            ],
            'niveau' => [
                'cycle_id' => ['model' => 'App\\Models\\Cycle', 'field' => 'libelle'],
            ],
            'rapport' => [
                'etablissement_id' => ['model' => 'App\\Models\\Etablissement', 'field' => 'libellefr'],
                'professeur_id' => ['model' => 'App\\Models\\Professeur', 'field' => 'nomfr'],
                'inspecteur_id' => ['model' => 'App\\Models\\Inspecteur', 'field' => 'nomfr'],
            ],
            'progression' => [
                'discipline_id' => ['model' => 'App\\Models\\Discipline', 'field' => 'libelle'],
            ],
        ];

        return $relationshipsMap[$model] ?? [];
    }

    protected function getExampleData($model)
    {
        $examplesMap = [
            'inspecteur' => [
                'id' => '1',
                'nomfr' => 'Dupont',
                'nomar' => 'دوبون',
                'matricule' => 'INS001',
                'nni' => '1234567890123',
                'date_naissance' => '01/01/1980',
                'lieu_naissance_ar' => 'نواكشوط',
                'lieu_naissance_fr' => 'Nouakchott',
                'date_affectation' => '01/09/2010',
                'contact' => '221123456789',
                'date_mise_en_corps_IES' => '01/09/2010',
                'bank' => 'Banque Nationale',
                'compte' => '123456789',
                'email' => 'inspecteur@example.com',
                'matrimonialite' => 'Marié',
                'date_recri_fp' => '01/09/2010',
                'photo' => 'photo.jpg',
                'discipline_id' => 'Mathématiques',
                'pole_id' => 'Pôle Éducation',
            ],
            'professeur' => [
                'id' => '1',
                'nomar' => 'مارتن',
                'nomfr' => 'Martin',
                'matricule' => 'PROF001',
                'nni' => '1234567890124',
                'date_naissance' => '15/05/1985',
                'lieu_naissance_ar' => 'نواكشوط',
                'lieu_naissance_fr' => 'Nouakchott',
                'discipline_origine' => 'Physique',
                'contact' => '221987654321',
                'statut_id' => 'Titulaire',
                'cycle_id' => 'Secondaire',
                'photo' => 'photo.jpg',
                'date_recritement' => '01/09/2015',
            ],
            'etablissement' => [
                'id' => '1',
                'libellear' => 'مدرسة نواكشوط',
                'libellefr' => 'Lycée Nouakchott',
                'cycle_id' => 'Secondaire',
                'code' => 'LYC001',
                'latitude' => '18.0858',
                'longitude' => '-15.9785',
                'etat' => 'Actif',
                'commune_id' => 'Tevragh Zeina',
            ],
            'rapport' => [
                'id' => '1',
                'date_inspection' => '15/01/2024',
                'classe_visitee' => '3ème A',
                'passation' => 'Oui',
                'titre_lecon' => 'Les équations du second degré',
                'deroulement' => 'Déroulement normal',
                'appreciation_generale' => 'Bonne leçon',
                'numero_ordre' => '1',
                'note' => '15',
                'etablissement_id' => 'Lycée Nouakchott',
                'professeur_id' => 'Martin',
                'inspecteur_id' => 'Dupont',
                'nombre_eleve' => '30',
                'present' => '28',
                'horaire' => '08:00-09:00',
            ],
            'infrastructure' => [
                'id' => '1',
                'type_infrastructure_id' => 'Salle de classe',
                'nombre_movais' => '10',
                'nombre_moyens' => '5',
                'nombre_bons' => '8',
                'etablissement_id' => 'Lycée Nouakchott',
                'annee_id' => '2024-2025',
            ],
            'structure_pedagogique' => [
                'id' => '1',
                'niveau_id' => 'Première',
                'nombre_section' => '5',
                'nombre_eleves' => '150',
                'nombre_filles' => '80',
                'etablissement_id' => 'Lycée Nouakchott',
                'annee_id' => '2024-2025',
            ],
            'reforme' => [
                'id' => '1',
                'libelle' => 'Réforme 2024',
                'description' => 'Nouvelle réforme éducative',
                'date_debut' => '01/09/2024',
                'date_fin' => '30/06/2025',
            ],
            'niveau' => [
                'id' => '1',
                'libelle' => 'Première',
                'cycle_id' => 'Secondaire',
            ],
            'volume_horaire' => [
                'id' => '1',
                'libelle' => 'Horaire standard',
                'volume_horaire' => '20',
            ],
            'progression' => [
                'id' => '1',
                'numero_lecon' => '1',
                'chapitre' => 'Chapitre 1',
                'titre_lecon' => 'Introduction',
                'numero_semaine' => '1',
                'discipline_id' => 'Mathématiques',
            ],
        ];

        return $examplesMap[$model] ?? [];
    }
}
