<?php

/**
 * Aug. 2025 Huub: created general EventManager.
 */

namespace Genealogy\Include;

use PDO;

class EventManager
{
    private $dbh, $db_functions, $userid;

    public function __construct($dbh)
    {
        $this->dbh = $dbh;
        $this->db_functions = new DbFunctions($dbh);

        $this->userid = false;
        if (is_numeric($_SESSION['user_id_admin'])) {
            $this->userid = $_SESSION['user_id_admin'];
        }
    }

    // *** Add event ***
    public function update_event($data): int
    {
        $processPlaceId = new ProcessPlaceId($this->dbh);
        $parseGedcomDate = new ParseGedcomDate();


        // TODO: check if all data fields are empty if update is done, if empty: remove the event.


        // Prepare date fields
        $event_date = $data['event_date'] ?? '';
        $event_place_lat = $data['event_place_lat'] ?? NULL;
        $event_place_lon = $data['event_place_lon'] ?? NULL;

        $parsed = $event_date ? $parseGedcomDate->parse($event_date) : ['year' => null, 'month' => null, 'day' => null];

        $event_place_id = isset($data['event_place']) ? $processPlaceId->get_id($data['event_place'], $event_place_lat, $event_place_lon) : null;
        $event_end_date = isset($data['event_end_date']) ? $data['event_end_date'] : null;
        $event_authority = isset($data['authority']) ? $data['authority'] : null;
        $event_date_hebnight = isset($data['event_date_hebnight']) ? $data['event_date_hebnight'] : '';

        // *** Check order number ***
        if (!isset($data['event_id'])) {
            if (isset($data['event_order']) && is_numeric($data['event_order'])) {
                $event_order = $data['event_order'];
            } else {
                // *** Generate a new order number ***
                // Also check event_gedcom?
                $event_sql = "SELECT * FROM humo_events
                    WHERE event_tree_id = :tree_id
                    AND event_connect_kind = :event_connect_kind
                    AND event_connect_id = :event_connect_id
                    AND event_kind = :event_kind
                    ORDER BY event_order DESC LIMIT 0,1";
                $event_qry = $this->dbh->prepare($event_sql);
                $event_qry->bindValue(':tree_id', $data['tree_id'], PDO::PARAM_STR);
                $event_qry->bindValue(':event_connect_kind', $data['event_connect_kind'], PDO::PARAM_STR);
                $event_qry->bindValue(':event_connect_id', $data['event_connect_id'], PDO::PARAM_STR);
                $event_qry->bindValue(':event_kind', $data['event_kind'], PDO::PARAM_STR);
                $event_qry->execute();
                $eventDb = $event_qry->fetch(PDO::FETCH_OBJ);

                if (isset($eventDb->event_order)) {
                    $event_order = $eventDb->event_order;
                    $event_order++;
                } else {
                    $event_order = 1;
                }
            }
        }

        /*
        // TODO Other method to check all $data items
        // Build assignments and bind only present params
        $assignments = [];
        foreach ($columns as $idx => $column) {
            $param = $values[$idx];
            // Only add if param is set in $data or is a required field
            $param_name = ltrim($param, ':');
            if (isset($data[$param_name]) || in_array($param_name, [
                'tree_id','event_date','event_date_hebnight','date_year','date_month','date_day',
                'place_id','event_text','event_order','event_new_user_id'
            ])) {
                $assignments[] = "$column = $param";
            }
        }
        $sql = "UPDATE humo_events SET " . implode(', ', $assignments) . " WHERE event_id = :event_id";
        */

        $columns = [
            'event_tree_id',
            'place_id',
            'event_new_user_id',
            'event_date',
            'event_end_date',
            'date_year',
            'date_month',
            'date_day',
            'event_date_hebnight',
            'authority'
        ];
        $values = [
            ':tree_id',
            ':place_id',
            ':event_new_user_id',
            ':event_date',
            ':event_end_date',
            ':date_year',
            ':date_month',
            ':date_day',
            ':event_date_hebnight',
            ':authority'
        ];

        // *** Data fields for new event ***
        if (!isset($data['event_id'])) {
            $columns2 = [
                'event_order',
                'event_gedcomnr',
                'event_connect_kind',
                'event_connect_id',
                'event_kind'
            ];
            $columns = array_merge($columns, $columns2);

            $values2 = [
                ':event_order',
                ':event_gedcomnr',
                ':event_connect_kind',
                ':event_connect_id',
                ':event_kind'
            ];
            $values = array_merge($values, $values2);

            // If event_connect_kind = person, add person_id. If it's family, add relation_id
            if ($data['event_connect_kind'] === 'person') {
                $columns[] = 'person_id';
                $values[] = ':person_id';
            } elseif ($data['event_connect_kind'] === 'family') {
                $columns[] = 'relation_id';
                $values[] = ':relation_id';
            } else {
                // *** If person_id or relation_id is set ***
                if (isset($data['person_id'])) {
                    $columns[] = 'person_id';
                    $values[] = ':person_id';
                }
                if (isset($data['relation_id'])) {
                    $columns[] = 'relation_id';
                    $values[] = ':relation_id';
                }
            }
        }

        if (isset($data['event_event'])) {
            $columns[] = 'event_event';
            $values[] = ':event_event';
        }
        if (isset($data['event_gedcom'])) {
            $columns[] = 'event_gedcom';
            $values[] = ':event_gedcom';
        }

        // *** Changed nov. 2025 ***
        if (isset($data['event_event_extra'])) {
            $columns[] = 'event_event_extra';
            $values[] = ':event_event_extra';
        }

        if (isset($data['event_connect_kind2'])) {
            $columns[] = 'event_connect_kind2';
            $values[] = ':event_connect_kind2';
        }
        if (isset($data['event_connect_id2'])) {
            $columns[] = 'event_connect_id2';
            $values[] = ':event_connect_id2';
        }

        if (isset($data['event_time'])) {
            $columns[] = 'event_time';
            $values[] = ':event_time';
        }
        if (isset($data['stillborn'])) {
            $columns[] = 'stillborn';
            $values[] = ':stillborn';
        }
        if (isset($data['cause'])) {
            $columns[] = 'cause';
            $values[] = ':cause';
        }
        if (isset($data['event_pers_age'])) {
            $columns[] = 'event_pers_age';
            $values[] = ':event_pers_age';
        }
        if (isset($data['cremation'])) {
            $columns[] = 'cremation';
            $values[] = ':cremation';
        }
        if (isset($data['event_text'])) {
            $columns[] = 'event_text';
            $values[] = ':event_text';
        }


        // *** For update query, add changed user id ***
        if (isset($data['event_changed_user_id'])) {
            $columns[] = 'event_changed_user_id';
            $values[] = ':event_changed_user_id';
        }

        // *** Update event ***
        if (isset($data['event_id'])) {
            // Build assignments like column = :param for each column
            $assignments = [];
            foreach ($columns as $idx => $column) {
                $param = $values[$idx];
                $assignments[] = "$column = $param";
            }
            $sql = "UPDATE humo_events SET " . implode(', ', $assignments) . " WHERE event_id = :event_id";
        } else {
            // *** New event ***
            $sql = "INSERT INTO humo_events (" . implode(', ', $columns) . ") VALUES (" . implode(', ', $values) . ")";
        }

        $stmt = $this->dbh->prepare($sql);

        $stmt->bindValue(':tree_id', $data['tree_id'], PDO::PARAM_STR);
        $stmt->bindValue(':event_date', $event_date, PDO::PARAM_STR);
        $stmt->bindValue(':event_end_date', $event_end_date, PDO::PARAM_STR);
        $stmt->bindValue(':event_date_hebnight', $event_date_hebnight, PDO::PARAM_STR);
        $stmt->bindValue(':authority', $event_authority, PDO::PARAM_STR);
        $stmt->bindValue(':date_year', $parsed['year'], PDO::PARAM_INT);
        $stmt->bindValue(':date_month', $parsed['month'], PDO::PARAM_INT);
        $stmt->bindValue(':date_day', $parsed['day'], PDO::PARAM_INT);
        $stmt->bindValue(':place_id', $event_place_id, PDO::PARAM_INT);
        $stmt->bindValue(':event_new_user_id', $this->userid, PDO::PARAM_STR);

        // *** Optional parameters - only bind if they're in the columns array ***
        $optional_params = [
            'event_event' => ':event_event',
            'event_gedcom' => ':event_gedcom',
            'event_event_extra' => ':event_event_extra',
            'event_connect_kind2' => ':event_connect_kind2',
            'event_connect_id2' => ':event_connect_id2',
            'event_time' => ':event_time',
            'stillborn' => ':stillborn',
            'cause' => ':cause',
            'event_pers_age' => ':event_pers_age',
            'cremation' => ':cremation',
            'event_text' => ':event_text'
        ];

        // event_pers_age should be PARAM_INT?
        foreach ($optional_params as $key => $param) {
            if (in_array($param, $values)) {
                $stmt->bindValue($param, $data[$key] ?? '', PDO::PARAM_STR);
            }
        }

        // *** New event: try to get person_id ***
        if (!isset($data['event_id'])) {
            if ($data['event_connect_kind'] === 'person') {
                if (isset($data['person_id'])) {
                    $stmt->bindValue(':person_id', $data['person_id'], PDO::PARAM_INT);
                } else {
                    // *** Get person_id ***
                    $this->db_functions->set_tree_id($data['tree_id']);

                    $person = $this->db_functions->get_person($data['event_connect_id']);
                    $stmt->bindValue(':person_id', isset($person->pers_id) ? $person->pers_id : null, PDO::PARAM_INT);
                }
            } elseif ($data['event_connect_kind'] === 'family') {
                if (isset($data['relation_id'])) {
                    $stmt->bindValue(':relation_id', $data['relation_id'], PDO::PARAM_INT);
                } else {
                    // *** Get relation_id ***
                    $this->db_functions->set_tree_id($data['tree_id']);

                    $family = $this->db_functions->get_family($data['event_connect_id']);
                    $stmt->bindValue(':relation_id', isset($family->fam_id) ? $family->fam_id : null, PDO::PARAM_INT);
                }
            } else {
                // *** If person_id or relation_id is set ***
                if (isset($data['person_id'])) {
                    $stmt->bindValue(':person_id', $data['person_id'], PDO::PARAM_INT);
                }
                if (isset($data['relation_id'])) {
                    $stmt->bindValue(':relation_id', $data['relation_id'], PDO::PARAM_INT);
                }
            }
        }

        if (isset($data['event_changed_user_id'])) {
            $stmt->bindValue(':event_changed_user_id', $data['event_changed_user_id'], PDO::PARAM_INT);
        }
        if (isset($data['event_id'])) {
            $stmt->bindValue(':event_id', $data['event_id'], PDO::PARAM_INT);
        } else {
            if (!isset($data['event_gedcomnr'])) {
                $data['event_gedcomnr'] = NULL;
            }

            $stmt->bindValue(':event_order', $event_order, PDO::PARAM_INT);
            $stmt->bindValue(':event_gedcomnr', $data['event_gedcomnr'], PDO::PARAM_STR);
            $stmt->bindValue(':event_connect_kind', $data['event_connect_kind'], PDO::PARAM_STR);
            $stmt->bindValue(':event_connect_id', $data['event_connect_id'], PDO::PARAM_STR);
            $stmt->bindValue(':event_kind', $data['event_kind'], PDO::PARAM_STR);
            $stmt->bindValue(':event_gedcom', $data['event_gedcom'], PDO::PARAM_STR);
        }

        $stmt->execute();

        return (int)$this->dbh->lastInsertId();
    }
}
