<?php

namespace Database\Seeders;

use App\Enums\CommitmentStatus;
use App\Enums\FaseStatus;
use App\Enums\FaseType;
use App\Enums\Prioriteit;
use App\Enums\ProjectRol;
use App\Enums\ProjectStatus;
use App\Enums\SpeerpuntStatus;
use App\Models\Afhankelijkheid;
use App\Models\Commitment;
use App\Models\Document;
use App\Models\Fase;
use App\Models\Project;
use App\Models\Role;
use App\Models\Speerpunt;
use App\Models\Thema;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * Planning 2026 – R&D Lab Waterschap Brabantse Delta
     * Source: Planning 2026.pptx
     */
    public function run(): void
    {
        // ──────────────────────────────────────────────────────────────
        // 1. System roles
        // ──────────────────────────────────────────────────────────────
        $roleAdmin = Role::create([
            'naam' => 'admin',
            'beschrijving' => 'Volledige toegang tot het platform',
            'permissies' => ['*'],
        ]);

        $roleProjectOwner = Role::create([
            'naam' => 'project_owner',
            'beschrijving' => 'Kan projecten beheren en bewerken',
            'permissies' => ['projects.manage', 'commitments.manage', 'documents.manage'],
        ]);

        $roleTeamMember = Role::create([
            'naam' => 'team_member',
            'beschrijving' => 'Kan bijdragen aan toegewezen projecten',
            'permissies' => ['projects.view', 'commitments.edit', 'documents.upload'],
        ]);

        Role::create([
            'naam' => 'viewer',
            'beschrijving' => 'Alleen-lezen toegang',
            'permissies' => ['projects.view', 'documents.view'],
        ]);

        // ──────────────────────────────────────────────────────────────
        // 2. Users (R&D team)
        // ──────────────────────────────────────────────────────────────
        $admin = User::create([
            'name' => 'Admin',
            'email' => 'admin@innovatieplatform.nl',
            'password' => Hash::make('password'),
            'functie' => 'Platform Beheerder',
            'afdeling' => 'R&D Lab',
            'email_verified_at' => now(),
        ]);
        $admin->roles()->attach($roleAdmin);

        $rene = User::create([
            'name' => 'Rene de Ren',
            'email' => 'rene@wbd-rd.nl',
            'password' => Hash::make('password'),
            'functie' => 'R&D Engineer / Teamlead',
            'afdeling' => 'R&D Lab',
            'email_verified_at' => now(),
        ]);
        $rene->roles()->attach($roleProjectOwner);

        $pim = User::create([
            'name' => 'Pim Moerman',
            'email' => 'p.moerman@wbd-rd.nl',
            'password' => Hash::make('password'),
            'functie' => 'Technisch Adviseur OT/IT',
            'afdeling' => 'R&D Lab',
            'email_verified_at' => now(),
        ]);
        $pim->roles()->attach($roleTeamMember);

        $sjoerd = User::create([
            'name' => 'Sjoerd Fijnje',
            'email' => 's.fijnje@wbd-rd.nl',
            'password' => Hash::make('password'),
            'functie' => 'Werktuigbouwkundige / Elektro',
            'afdeling' => 'R&D Lab',
            'email_verified_at' => now(),
        ]);
        $sjoerd->roles()->attach($roleTeamMember);

        // ──────────────────────────────────────────────────────────────
        // 3. Themas – 2026 strategic themes
        //
        // Kaders: geen nieuwe ML-modellen, geen nieuwe digital twins,
        // focus op werkend krijgen, architectuur aantonen, overdragen.
        // ──────────────────────────────────────────────────────────────
        $themaArchitectuur = Thema::create([
            'naam' => 'Architectuur & Veiligheid',
            'beschrijving' => 'Aantonen dat de EDGE-laag architectuur veilig, betrouwbaar en schaalbaar is. OT/IT-scheiding, Siemens-koppeling, CI/CD implementatie.',
            'prioriteit' => Prioriteit::Hoog,
            'periode_start' => '2026-01-01',
            'periode_eind' => '2026-12-31',
        ]);

        $themaProductie = Thema::create([
            'naam' => 'Productiewaardig Maken',
            'beschrijving' => 'Bestaande innovaties werkend, overdraagbaar en schaalbaar maken. Begeleiding van aanbestedingen en overdracht naar Bouwen/Beheer.',
            'prioriteit' => Prioriteit::Hoog,
            'periode_start' => '2026-01-01',
            'periode_eind' => '2026-12-31',
        ]);

        $themaLab = Thema::create([
            'naam' => 'Lab & Prototyping',
            'beschrijving' => 'Fysieke opstellingen valideren, uitbreiden en koppelen tot een realistische testomgeving voor afvlakkingsregelingen.',
            'prioriteit' => Prioriteit::Midden,
            'periode_start' => '2026-01-01',
            'periode_eind' => '2026-12-31',
        ]);

        $themaGovernance = Thema::create([
            'naam' => 'Governance & Teamborging',
            'beschrijving' => 'R&D minder persoonsafhankelijk maken. Projectstructuur, documentatie, besluitvorming en rolafbakening vastleggen.',
            'prioriteit' => Prioriteit::Midden,
            'periode_start' => '2026-01-01',
            'periode_eind' => '2026-12-31',
        ]);

        // ──────────────────────────────────────────────────────────────
        // 4. Speerpunten (2 per thema)
        // ──────────────────────────────────────────────────────────────

        // Architectuur & Veiligheid
        $spEdge = Speerpunt::create([
            'thema_id' => $themaArchitectuur->id,
            'naam' => 'EDGE-laag & OT/IT-scheiding',
            'beschrijving' => 'Implementatie en validatie van de EDGE-architectuur met beveiligde OT/IT-scheiding op pilotlocatie.',
            'eigenaar_id' => $rene->id,
            'status' => SpeerpuntStatus::Actief,
        ]);

        $spCicd = Speerpunt::create([
            'thema_id' => $themaArchitectuur->id,
            'naam' => 'CI/CD & DevOps R&D-stack',
            'beschrijving' => 'Continuous Integration en Deployment implementeren in de R&D-stack voor maximale efficiëntie en herhaalbaarheid.',
            'eigenaar_id' => $rene->id,
            'status' => SpeerpuntStatus::Concept,
        ]);

        // Productiewaardig Maken
        $spOverdracht = Speerpunt::create([
            'thema_id' => $themaProductie->id,
            'naam' => 'Overdracht naar Bouwen/Beheer',
            'beschrijving' => 'Innovaties begeleiden van R&D naar productie: documentatie, oplevering, kennisoverdracht.',
            'eigenaar_id' => $rene->id,
            'status' => SpeerpuntStatus::Actief,
        ]);

        $spAanbesteding = Speerpunt::create([
            'thema_id' => $themaProductie->id,
            'naam' => 'Aanbesteding & TCO-toetsing',
            'beschrijving' => 'Technische toetsing van aanbestedingen op prestatie-eisen, energie-efficiëntie en inpasbaarheid.',
            'eigenaar_id' => $pim->id,
            'status' => SpeerpuntStatus::Actief,
        ]);

        // Lab & Prototyping
        $spDtValidatie = Speerpunt::create([
            'thema_id' => $themaLab->id,
            'naam' => 'Digital Twin Validatie',
            'beschrijving' => 'Valideren van 2025-ontwikkelingen (Measurement, Rotating Machine, Aeration Tank, MGC, Diffuser) op het fysieke prototype.',
            'eigenaar_id' => $rene->id,
            'status' => SpeerpuntStatus::Actief,
        ]);

        $spGemalenketen = Speerpunt::create([
            'thema_id' => $themaLab->id,
            'naam' => 'Gemalenketen Testomgeving',
            'beschrijving' => 'Realiseren van een volledige gemalenketen in het lab voor experimentele afvlakkingsregelingen.',
            'eigenaar_id' => $sjoerd->id,
            'status' => SpeerpuntStatus::Concept,
        ]);

        // Governance & Teamborging
        $spProjectstructuur = Speerpunt::create([
            'thema_id' => $themaGovernance->id,
            'naam' => 'Projectstructuur & Documentatie',
            'beschrijving' => 'Afspraken vastleggen over projectstructuur, documentatie, besluitvorming en beleid.',
            'eigenaar_id' => $rene->id,
            'status' => SpeerpuntStatus::Actief,
        ]);

        $spRolafbakening = Speerpunt::create([
            'thema_id' => $themaGovernance->id,
            'naam' => 'Rolafbakening R&D ↔ Organisatie',
            'beschrijving' => 'Verduidelijken wat R&D wel en niet doet. Afbakening richting Beheer, Bouwen, ICT en Datalab.',
            'eigenaar_id' => $rene->id,
            'status' => SpeerpuntStatus::Concept,
        ]);

        // ──────────────────────────────────────────────────────────────
        // 5. Projects – 2026 planning (6 projects from the presentation)
        // ──────────────────────────────────────────────────────────────

        // --- B.R.I.D.G.E (Bidirectional Real-time Interface for Data & Grid Exchange) ---
        $bridge = $this->createProject([
            'speerpunt_id' => $spEdge->id,
            'naam' => 'B.R.I.D.G.E – Pilot Klundert',
            'beschrijving' => 'Aantonen dat de nieuwe EDGE-laag veilig en betrouwbaar assets kan uitlezen en aansturen, en correct kan koppelen met Siemens-omgevingen. Implementatie Ubuntu LTS, Node-RED orkestratie, OPC UA communicatie met Siemens PLC (T-serie).',
            'eigenaar_id' => $rene->id,
            'status' => ProjectStatus::Pilot,
            'prioriteit' => Prioriteit::Hoog,
            'startdatum' => '2026-01-15',
            'streef_einddatum' => '2026-09-30',
        ], [FaseType::Signaal, FaseType::Verkenning, FaseType::Concept, FaseType::Experiment, FaseType::Pilot]);

        // --- C.R.I.S.P (Compressor Replacement for Immediate System Performance) ---
        $crisp = $this->createProject([
            'speerpunt_id' => $spAanbesteding->id,
            'naam' => 'C.R.I.S.P – Compressor Aanbesteding',
            'beschrijving' => 'Technische toetsing van aanbestedingsmethodiek voor compressorvervanging Nieuwveer. Prestatie-eisen, energie-efficiëntie, inpasbaarheid in procesautomatisering. R&D als inhoudelijke sparringpartner voor Bouwen.',
            'eigenaar_id' => $pim->id,
            'status' => ProjectStatus::Verkenning,
            'prioriteit' => Prioriteit::Hoog,
            'startdatum' => '2026-02-01',
            'streef_einddatum' => '2026-08-31',
        ], [FaseType::Signaal, FaseType::Verkenning]);

        // --- W.I.S.E (Weather and Influent Sampling Engine) ---
        $wise = $this->createProject([
            'speerpunt_id' => $spOverdracht->id,
            'naam' => 'W.I.S.E – Monsternamekast Overdracht',
            'beschrijving' => 'Overdracht monsternamekast naar Bouwen. Opleveren Node-RED flows, documentatie, afbakening R&D vs beheer. Samenwerking met Datalab (data & integratie voorspellend model) en Beheer/Operatie.',
            'eigenaar_id' => $rene->id,
            'status' => ProjectStatus::OverdrachtBouwen,
            'prioriteit' => Prioriteit::Hoog,
            'startdatum' => '2025-06-01',
            'streef_einddatum' => '2026-06-30',
        ], [FaseType::Signaal, FaseType::Verkenning, FaseType::Concept, FaseType::Experiment, FaseType::Pilot, FaseType::Besluitvorming, FaseType::OverdrachtBouwen]);

        // --- Gemaal 3.0 – Prototype Validatie ---
        $gemaal = $this->createProject([
            'speerpunt_id' => $spDtValidatie->id,
            'naam' => 'Gemaal 3.0 – Prototype Validatie',
            'beschrijving' => 'Valideren dat het recent gebouwde prototype functioneel correct is. Testen van alle elektrische aansluitingen, I/O-functionaliteit en randapparatuur. Go/no-go voor verdere uitrol naar 2 kopieën.',
            'eigenaar_id' => $sjoerd->id,
            'status' => ProjectStatus::Experiment,
            'prioriteit' => Prioriteit::Midden,
            'startdatum' => '2026-03-01',
            'streef_einddatum' => '2026-07-31',
        ], [FaseType::Signaal, FaseType::Verkenning, FaseType::Concept, FaseType::Experiment]);

        // --- Afvlakkingsregeling – Lab Gemalenketen ---
        $afvlak = $this->createProject([
            'speerpunt_id' => $spGemalenketen->id,
            'naam' => 'Afvlakkingsregeling – Lab Keten',
            'beschrijving' => 'Nabootsen van een volledige gemalenketen in het lab, klaarstomen voor afvlakkingsregeling. Realiseren 2 extra opstellingen, koppelen tot keten, basissoftware testen op ketengedrag.',
            'eigenaar_id' => $sjoerd->id,
            'status' => ProjectStatus::Concept,
            'prioriteit' => Prioriteit::Midden,
            'startdatum' => '2026-06-01',
            'streef_einddatum' => '2026-12-31',
        ], [FaseType::Signaal, FaseType::Verkenning, FaseType::Concept]);

        // --- Structuur & Borging R&D-team ---
        $governance = $this->createProject([
            'speerpunt_id' => $spProjectstructuur->id,
            'naam' => 'Structuur & Borging R&D',
            'beschrijving' => 'R&D minder persoonsafhankelijk en beter voorspelbaar maken. Afspraken over projectstructuur, documentatie, besluitvorming, beleid. Inrichten ICT in Bouvigne voor R&D en Datanetwerkteam.',
            'eigenaar_id' => $rene->id,
            'status' => ProjectStatus::Verkenning,
            'prioriteit' => Prioriteit::Midden,
            'startdatum' => '2026-01-01',
            'streef_einddatum' => '2026-12-31',
        ], [FaseType::Signaal, FaseType::Verkenning]);

        // ──────────────────────────────────────────────────────────────
        // 6. Assign team members
        // ──────────────────────────────────────────────────────────────
        $bridge->teamleden()->attach($pim->id, ['rol' => ProjectRol::Lid->value]);
        $bridge->teamleden()->attach($sjoerd->id, ['rol' => ProjectRol::Lid->value]);
        $crisp->teamleden()->attach($rene->id, ['rol' => ProjectRol::Reviewer->value]);
        $wise->teamleden()->attach($pim->id, ['rol' => ProjectRol::Lid->value]);
        $gemaal->teamleden()->attach($rene->id, ['rol' => ProjectRol::Reviewer->value]);
        $afvlak->teamleden()->attach($rene->id, ['rol' => ProjectRol::Reviewer->value]);
        $governance->teamleden()->attach($pim->id, ['rol' => ProjectRol::Lid->value]);
        $governance->teamleden()->attach($sjoerd->id, ['rol' => ProjectRol::Lid->value]);

        // ──────────────────────────────────────────────────────────────
        // 7. Commitments
        // ──────────────────────────────────────────────────────────────

        // BRIDGE
        Commitment::create([
            'project_id' => $bridge->id,
            'beschrijving' => 'Architectuur validatiedocument opleveren conform stackKlundertPilot.pdf',
            'eigenaar_id' => $rene->id,
            'deadline' => '2026-04-30',
            'status' => CommitmentStatus::InUitvoering,
            'bron' => 'Planning 2026 – slide 3',
        ]);

        Commitment::create([
            'project_id' => $bridge->id,
            'beschrijving' => 'OT/IT beveiligingsassessment en scheidingsrapport',
            'eigenaar_id' => $pim->id,
            'deadline' => '2026-06-30',
            'status' => CommitmentStatus::Open,
            'bron' => 'Planning 2026 – slide 3',
        ]);

        Commitment::create([
            'project_id' => $bridge->id,
            'beschrijving' => 'Beslisdocument voor opschaling EDGE-laag naar andere locaties',
            'eigenaar_id' => $rene->id,
            'deadline' => '2026-09-30',
            'status' => CommitmentStatus::Open,
            'bron' => 'Planning 2026 – slide 3',
        ]);

        // CRISP
        Commitment::create([
            'project_id' => $crisp->id,
            'beschrijving' => 'TCO-onderbouwde aanbestedingsdocumenten technisch getoetst vóór marktgang',
            'eigenaar_id' => $pim->id,
            'deadline' => '2026-05-31',
            'status' => CommitmentStatus::Open,
            'bron' => 'Planning 2026 – slide 4',
        ]);

        // WISE
        Commitment::create([
            'project_id' => $wise->id,
            'beschrijving' => 'Node-RED flows opleveren aan Bouwen / uitvoerende partij',
            'eigenaar_id' => $rene->id,
            'deadline' => '2026-03-31',
            'status' => CommitmentStatus::InUitvoering,
            'bron' => 'Planning 2026 – slide 5',
        ]);

        Commitment::create([
            'project_id' => $wise->id,
            'beschrijving' => 'Overdracht- en documentatiepakket compleet (afbakening R&D vs beheer)',
            'eigenaar_id' => $rene->id,
            'deadline' => '2026-06-30',
            'status' => CommitmentStatus::Open,
            'bron' => 'Planning 2026 – slide 5',
        ]);

        // Gemaal 3.0
        Commitment::create([
            'project_id' => $gemaal->id,
            'beschrijving' => 'Go/no-go besluit voor uitrol naar 2 kopieën op basis van testresultaten',
            'eigenaar_id' => $sjoerd->id,
            'deadline' => '2026-06-30',
            'status' => CommitmentStatus::Open,
            'bron' => 'Planning 2026 – slide 6',
        ]);

        Commitment::create([
            'project_id' => $gemaal->id,
            'beschrijving' => 'Overzicht software/hardware functionaliteiten en validatie digital twins',
            'eigenaar_id' => $rene->id,
            'deadline' => '2026-07-31',
            'status' => CommitmentStatus::Open,
            'bron' => 'Planning 2026 – slide 6',
        ]);

        // Afvlakkingsregeling
        Commitment::create([
            'project_id' => $afvlak->id,
            'beschrijving' => '2 extra opstellingen gerealiseerd en gekoppeld tot keten',
            'eigenaar_id' => $sjoerd->id,
            'deadline' => '2026-10-31',
            'status' => CommitmentStatus::Open,
            'bron' => 'Planning 2026 – slide 7',
        ]);

        // Governance
        Commitment::create([
            'project_id' => $governance->id,
            'beschrijving' => 'Projectstructuur- en documentatieafspraken vastgelegd',
            'eigenaar_id' => $rene->id,
            'deadline' => '2026-03-31',
            'status' => CommitmentStatus::InUitvoering,
            'bron' => 'Planning 2026 – slide 8',
        ]);

        Commitment::create([
            'project_id' => $governance->id,
            'beschrijving' => 'Rolafbakening R&D ↔ Beheer ↔ Bouwen vastgelegd en gecommuniceerd',
            'eigenaar_id' => $rene->id,
            'deadline' => '2026-06-30',
            'status' => CommitmentStatus::Open,
            'bron' => 'Planning 2026 – slide 8',
        ]);

        // ──────────────────────────────────────────────────────────────
        // 8. Documents
        // ──────────────────────────────────────────────────────────────
        Document::create([
            'project_id' => $bridge->id,
            'titel' => 'Stack Architectuur Klundert Pilot',
            'type' => 'technisch_ontwerp',
            'inhoud' => 'Systeemarchitectuur EDGE-laag: Ubuntu LTS, Node-RED orkestratie, OPC UA communicatie met Siemens PLC T-serie, InfluxDB/Grafana datastromen.',
            'versie' => 1,
            'auteur_id' => $rene->id,
        ]);

        Document::create([
            'project_id' => $wise->id,
            'titel' => 'Overdrachtsprotocol Monsternamekast',
            'type' => 'protocol',
            'inhoud' => 'Opleverdocument voor de overdracht van de monsternamekast naar Bouwen. Bevat: Node-RED flow specificaties, integratie voorspellend model, afbakening verantwoordelijkheden.',
            'versie' => 1,
            'auteur_id' => $rene->id,
        ]);

        Document::create([
            'project_id' => $crisp->id,
            'titel' => 'Technische Toetsing Aanbesteding Compressoren',
            'type' => 'technisch_rapport',
            'inhoud' => 'Q&A en technische beoordeling van aanbestedingsdocumenten voor compressorvervanging Nieuwveer. TCO-analyse, prestatie-eisen, energie-efficiëntie.',
            'versie' => 1,
            'auteur_id' => $pim->id,
        ]);

        Document::create([
            'project_id' => $gemaal->id,
            'titel' => 'Testrapport Prototype Gemaal 3.0',
            'type' => 'technisch_rapport',
            'inhoud' => 'Bevindingen en verbeterpunten uit validatie van het prototype: elektrische aansluitingen, I/O-functionaliteit, randapparatuur, digital twin koppelingen.',
            'versie' => 1,
            'auteur_id' => $sjoerd->id,
        ]);

        Document::create([
            'project_id' => $governance->id,
            'titel' => 'R&D Projectstructuur & Beleidskader',
            'type' => 'projectplan',
            'inhoud' => 'Afspraken over projectstructuur, documentatiestandaarden, besluitvormingsproces en beleid voor het R&D-lab.',
            'versie' => 1,
            'auteur_id' => $rene->id,
        ]);

        // ──────────────────────────────────────────────────────────────
        // 9. Dependencies between projects
        // ──────────────────────────────────────────────────────────────

        // Afvlakkingsregeling hangt af van Gemaal 3.0 (prototype moet gevalideerd zijn)
        Afhankelijkheid::create([
            'project_id' => $afvlak->id,
            'afhankelijk_van_project_id' => $gemaal->id,
            'type' => 'technisch',
            'beschrijving' => 'De afvlakkingsregeling vereist gevalideerde prototypes van Gemaal 3.0 (× 2 kopieën) als basis voor de ketenopstelling.',
            'status' => 'open',
        ]);

        // WISE overdracht profiteert van BRIDGE architectuur (gedeelde EDGE-infrastructuur)
        Afhankelijkheid::create([
            'project_id' => $wise->id,
            'afhankelijk_van_project_id' => $bridge->id,
            'type' => 'infrastructuur',
            'beschrijving' => 'De monsternamekast draait op dezelfde EDGE-architectuur die BRIDGE valideert.',
            'status' => 'open',
        ]);

        // Gemaal 3.0 validatie van digital twins hangt samen met BRIDGE architectuur
        Afhankelijkheid::create([
            'project_id' => $gemaal->id,
            'afhankelijk_van_project_id' => $bridge->id,
            'type' => 'technisch',
            'beschrijving' => 'Digital twin validatie in Gemaal 3.0 gebruikt dezelfde EDGE-laag als bewezen in BRIDGE.',
            'status' => 'open',
        ]);
    }

    /**
     * Helper: create a project with its completed and active phases.
     */
    private function createProject(array $attributes, array $faseTypes): Project
    {
        $project = Project::create($attributes);

        $project->teamleden()->attach($attributes['eigenaar_id'], ['rol' => ProjectRol::Eigenaar->value]);

        foreach ($faseTypes as $index => $faseType) {
            $isLast = $index === count($faseTypes) - 1;

            Fase::create([
                'project_id' => $project->id,
                'type' => $faseType,
                'status' => $isLast ? FaseStatus::Actief : FaseStatus::Afgerond,
                'startdatum' => now()->subMonths(count($faseTypes) - 1 - $index),
                'einddatum' => $isLast ? null : now()->subMonths(count($faseTypes) - 2 - $index),
            ]);
        }

        return $project;
    }
}
