<?php

declare(strict_types=1);

use Fisharebest\Webtrees\Auth;
use Fisharebest\Webtrees\Fact;
use Fisharebest\Webtrees\Gedcom;
use Fisharebest\Webtrees\I18N;
use Fisharebest\Webtrees\Individual;
use Fisharebest\Webtrees\Menu;
use Fisharebest\Webtrees\Module\ModuleChartInterface;
use Fisharebest\Webtrees\Registry;
use Fisharebest\Webtrees\Services\ModuleService;

/**
 * @var Individual|null  $individual
 */

if ($individual === null) {
    echo '<div class="wt-chart-box"></div>';

    return;
}

$module_service = Registry::container()->get(ModuleService::class);

$menus = $module_service->findByComponent(ModuleChartInterface::class, $individual->tree(), Auth::user())
    ->map(static fn (ModuleChartInterface $module): Menu|null => $module->chartBoxMenu($individual))
    ->filter();

foreach ($individual->spouseFamilies() as $family) {
    $menus->push(new Menu('<strong>' . I18N::translate('Family with spouse') . '</strong>', $family->url()));
    $spouse  = $family->spouse($individual);
    if ($spouse instanceof Individual && $spouse->canShow()) {
        $menus->push(new Menu($spouse->fullName(), $spouse->url()));
    }
    foreach ($family->children() as $child) {
        if ($child->canShow()) {
            $menus->push(new Menu($child->fullName(), $child->url()));
        }
    }
}

// Do not show these facts in the expanded chart boxes.
$exclude = [
    'FAM:CHAN',
    'FAM:CHIL',
    'FAM:HUSB',
    'FAM:NOTE',
    'FAM:OBJE',
    'FAM:RESN',
    'FAM:SOUR',
    'FAM:WIFE',
    'INDI:ADDR',
    'INDI:ALIA',
    'INDI:ASSO',
    'INDI:CHAN',
    'INDI:EMAIL',
    'INDI:FAMC',
    'INDI:FAMS',
    'INDI:NAME',
    'INDI:NOTE',
    'INDI:OBJE',
    'INDI:PHON',
    'INDI:RESI',
    'INDI:RESN',
    'INDI:SEX',
    'INDI:SOUR',
    'INDI:SSN',
    'INDI:SUBM',
    'INDI:TITL',
    'INDI:URL',
    'INDI:WWW',
    'INDI:_EMAIL',
    'INDI:_TODO',
    'INDI:_UID',
    'INDI:_WT_OBJE_SORT'
];

$all_facts = $individual->facts();
foreach ($individual->spouseFamilies() as $family) {
    foreach ($family->facts() as $fact) {
        $all_facts->push($fact);
    }
}

$all_facts = $all_facts->filter(static fn (Fact $fact): bool => !in_array($fact->tag(), $exclude, true));

$all_facts = Fact::sortFacts($all_facts);

$id = Registry::idFactory()->id();
?>

<div class="wt-chart-box wt-chart-box-<?= strtolower($individual->sex()) ?> <?= $individual->isPendingAddition() ? 'wt-new' : '' ?> <?= $individual->isPendingDeletion() ? 'wt-old' : '' ?> overflow-hidden" data-wt-chart-xref="<?= e($individual->xref()) ?>" data-tree="<?= e($individual->tree()->name()) ?>">
    <?php if ($individual->canShow() && $individual->tree()->getPreference('SHOW_HIGHLIGHT_IMAGES') === '1') : ?>
        <div class="wt-chart-box-thumbnail float-start me-1">
            <?= $individual->displayImage(40, 50, 'crop', ['class' => 'wt-chart-box-thumbnail']) ?>
        </div>
    <?php endif ?>

    <?php if ($individual->canShow()) : ?>
        <div class="wt-chart-box-extra d-print-none float-end ms-1">
            <div class="dropdown position-static wt-chart-box-zoom">
                <a class="wt-chart-box-icon" href="#" role="button" id="chart-box-zoom-<?= $id ?>" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="<?= I18N::translate('Zoom in') ?>">
                    <div><?= view('icons/zoom-in') ?></div>
                    <div class="d-none"><?= view('icons/zoom-out') ?></div>
                </a>

                <div class="dropdown-menu dropdown-menu-end wt-chart-box-dropdown wt-chart-box-zoom-dropdown" style="position: inherit" aria-labelledby="#chart-box-zoom-<?= $id ?>">
                    <?php foreach ($all_facts as $fact) : ?>
                        <?= $fact->summary() ?>
                    <?php endforeach ?>
                </div>
            </div>

            <div class="dropdown position-static wt-chart-box-links">
                <a class="wt-chart-box-icon" href="#" role="button" id="chart-box-menu-<?= $id ?>" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="<?= I18N::translate('Links') ?>">
                    <span class="icon-pedigree">
                        <?= view('icons/menu') ?>
                    </span>
                </a>

                <div class="dropdown-menu dropdown-menu-end wt-chart-box-dropdown wt-chart-box-links-dropdown" style="position: inherit" aria-labelledby="#chart-box-menu-<?= $id ?>">
                    <?php foreach ($menus as $menu) : ?>
                        <a class="dropdown-item p-1 <?= e($menu->getClass()) ?>" href="<?= e($menu->getLink()) ?>">
                            <?= $menu->getLabel() ?>
                        </a>
                    <?php endforeach ?>
                </div>
            </div>
        </div>
    <?php endif ?>

    <div class="wt-chart-box-name">
        <?php if ($individual->canShow()) : ?>
            <a href="<?= e($individual->url()) ?>"><?= $individual->fullName() ?></a>
        <?php else : ?>
            <?= $individual->fullName() ?>
        <?php endif ?>
    </div>

    <div class="wt-chart-box-name wt-chart-box-name-alt">
        <?= $individual->alternateName() ?>
    </div>

    <div class="wt-chart-box-lifespan">
        <?= $individual->lifespan() ?>
    </div>

    <div class="wt-chart-box-facts">
        <div class="wt-chart-box-fact small">
            <?php
            $opt_tags = preg_split('/\W/', $individual->tree()->getPreference('CHART_BOX_TAGS'), 0, PREG_SPLIT_NO_EMPTY);
            preg_match_all('/\w+/', $individual->tree()->getPreference('CHART_BOX_TAGS'), $matches);
            $opt_tags = array_filter($matches[0], static fn (string $tag): bool => !in_array($tag, Gedcom::BIRTH_EVENTS, true) && !in_array($tag, Gedcom::DEATH_EVENTS, true));

            // Show BIRT or equivalent event
            foreach (Gedcom::BIRTH_EVENTS as $birttag) {
                if (!in_array($birttag, $opt_tags, true)) {
                    $event = $individual->facts([$birttag])->first();

                    if ($event instanceof Fact) {
                        echo $event->summary();
                        break;
                    }
                }
            }

            // Show optional events
            foreach ($opt_tags as $key => $tag) {
                if (!in_array($tag, Gedcom::BIRTH_EVENTS + Gedcom::DEATH_EVENTS, true)) {
                    $event = $individual->facts([$tag])->first();

                    if ($event instanceof Fact) {
                        echo $event->summary();
                    }
                }
            }

            // Show DEAT or equivalent event
            foreach (Gedcom::DEATH_EVENTS as $deattag) {
                $event = $individual->facts([$deattag])->first();

                if ($event instanceof Fact) {
                    echo $event->summary();
                    break;
                }
            }
            ?>
        </div>
    </div>
</div>
