<?php
namespace App;

use PDO;

class ClientPanel {
    public static function listEventTypes(): array {
        $db = get_db();
        $stmt = $db->query('SELECT code, label FROM event_types ORDER BY label ASC');
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public static function getEventByUser(int $userId): ?array {
        $db = get_db();
        $stmt = $db->prepare('SELECT * FROM user_events WHERE user_id = :uid ORDER BY id DESC LIMIT 1');
        $stmt->execute([':uid' => $userId]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        return $row ?: null;
    }

    public static function saveEvent(int $userId, string $eventTypeCode, string $title, ?string $eventDate, ?string $venue, ?string $notes, ?int $sourceProductId = null): void {
        $db = get_db();
        $current = self::getEventByUser($userId);
        if ($current) {
            $stmt = $db->prepare('UPDATE user_events SET event_type_code = :event_type_code, title = :title, event_date = :ed, venue = :venue, notes = :notes, source_product_id = :source_product_id, updated_at = CURRENT_TIMESTAMP WHERE id = :id');
            $stmt->execute([
                ':event_type_code' => $eventTypeCode,
                ':title' => $title,
                ':ed' => $eventDate,
                ':venue' => $venue,
                ':notes' => $notes,
                ':source_product_id' => $sourceProductId ?: ($current['source_product_id'] ?? null),
                ':id' => $current['id'],
            ]);
            return;
        }

        $stmt = $db->prepare('INSERT INTO user_events (user_id, event_type_code, title, event_date, venue, notes, source_product_id) VALUES (:uid, :event_type_code, :title, :ed, :venue, :notes, :source_product_id)');
        $stmt->execute([
            ':uid' => $userId,
            ':event_type_code' => $eventTypeCode,
            ':title' => $title,
            ':ed' => $eventDate,
            ':venue' => $venue,
            ':notes' => $notes,
            ':source_product_id' => $sourceProductId,
        ]);
    }

    public static function selectInvitationForUser(int $userId, array $product): void {
        $eventTypeCode = \App\Product::inferEventTypeCode($product) ?? 'corporativo';
        $defaultTitle = 'Evento - ' . trim((string)($product['title'] ?? 'Invitacion'));
        $current = self::getEventByUser($userId);
        if ($current) {
            $title = trim((string)($current['title'] ?? '')) !== '' ? (string)$current['title'] : $defaultTitle;
            self::saveEvent(
                $userId,
                $eventTypeCode,
                $title,
                !empty($current['event_date']) ? (string)$current['event_date'] : null,
                !empty($current['venue']) ? (string)$current['venue'] : null,
                !empty($current['notes']) ? (string)$current['notes'] : null,
                (int)($product['id'] ?? 0)
            );
            return;
        }

        self::saveEvent(
            $userId,
            $eventTypeCode,
            $defaultTitle,
            null,
            null,
            null,
            (int)($product['id'] ?? 0)
        );
    }

    public static function clearSelectedInvitationForUser(int $userId): void {
        $db = get_db();
        $stmt = $db->prepare('UPDATE user_events SET source_product_id = NULL, updated_at = CURRENT_TIMESTAMP WHERE user_id = :uid');
        $stmt->execute([':uid' => $userId]);
    }

    public static function getEventFieldTemplatesByTypeCode(string $eventTypeCode): array {
        $db = get_db();
        $stmt = $db->prepare('SELECT etf.field_key, etf.field_label, etf.input_type, etf.is_required, etf.group_name, etf.placeholder, etf.sort_order
            FROM event_field_templates etf
            INNER JOIN event_types et ON et.id = etf.event_type_id
            WHERE et.code = :code
            ORDER BY etf.sort_order ASC, etf.id ASC');
        $stmt->execute([':code' => $eventTypeCode]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public static function getEventDetailsMap(int $eventId): array {
        $db = get_db();
        $stmt = $db->prepare('SELECT field_key, field_value FROM user_event_details WHERE event_id = :eid');
        $stmt->execute([':eid' => $eventId]);
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
        $map = [];
        foreach ($rows as $r) {
            $map[(string)$r['field_key']] = (string)($r['field_value'] ?? '');
        }
        return $map;
    }

    public static function saveEventDetails(int $eventId, array $details): void {
        $db = get_db();
        $stmt = $db->prepare('INSERT INTO user_event_details (event_id, field_key, field_value, created_at, updated_at)
            VALUES (:eid, :field_key, :field_value, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
            ON DUPLICATE KEY UPDATE field_value = VALUES(field_value), updated_at = CURRENT_TIMESTAMP');
        foreach ($details as $key => $value) {
            $stmt->execute([
                ':eid' => $eventId,
                ':field_key' => (string)$key,
                ':field_value' => (string)$value,
            ]);
        }
    }

    public static function addGuest(int $userId, ?int $eventId, string $name, ?string $phone, ?string $email, int $adults, int $kids): void {
        $db = get_db();
        $stmt = $db->prepare('INSERT INTO user_guests (user_id, event_id, name, phone, email, adults, kids) VALUES (:uid, :eid, :name, :phone, :email, :adults, :kids)');
        $stmt->execute([
            ':uid' => $userId,
            ':eid' => $eventId,
            ':name' => $name,
            ':phone' => $phone,
            ':email' => $email,
            ':adults' => max(1, $adults),
            ':kids' => max(0, $kids),
        ]);
    }

    public static function listGuestsByUser(int $userId): array {
        $db = get_db();
        $stmt = $db->prepare('SELECT * FROM user_guests WHERE user_id = :uid ORDER BY id DESC');
        $stmt->execute([':uid' => $userId]);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public static function markGuestsAsInvited(int $userId, ?int $eventId = null): int {
        $db = get_db();
        if ($eventId) {
            $stmt = $db->prepare('UPDATE user_guests SET invite_sent_at = CURRENT_TIMESTAMP WHERE user_id = :uid AND event_id = :eid');
            $stmt->execute([':uid' => $userId, ':eid' => $eventId]);
            return (int)$stmt->rowCount();
        }

        $stmt = $db->prepare('UPDATE user_guests SET invite_sent_at = CURRENT_TIMESTAMP WHERE user_id = :uid');
        $stmt->execute([':uid' => $userId]);
        return (int)$stmt->rowCount();
    }

    public static function importGuestsFromCsvFile(int $userId, ?int $eventId, string $tmpFile): array {
        $handle = fopen($tmpFile, 'r');
        if ($handle === false) {
            return ['imported' => 0, 'errors' => ['No se pudo leer el archivo CSV']];
        }

        $headers = fgetcsv($handle);
        if (!$headers) {
            fclose($handle);
            return ['imported' => 0, 'errors' => ['CSV vacío']];
        }

        $normalized = array_map(static function ($h) {
            $h = strtolower(trim((string)$h));
            return str_replace([' ', '-'], '_', $h);
        }, $headers);
        $idx = array_flip($normalized);
        $required = ['name'];
        foreach ($required as $col) {
            if (!isset($idx[$col])) {
                fclose($handle);
                return ['imported' => 0, 'errors' => ["Falta columna requerida: {$col}"]];
            }
        }

        $imported = 0;
        $errors = [];
        $rowNum = 1;
        while (($row = fgetcsv($handle)) !== false) {
            $rowNum++;
            $name = trim((string)($row[$idx['name']] ?? ''));
            $phone = trim((string)($row[$idx['phone']] ?? ''));
            $email = trim((string)($row[$idx['email']] ?? ''));
            $adults = (int)($row[$idx['adults']] ?? 1);
            $kids = (int)($row[$idx['kids']] ?? 0);

            if ($name === '') {
                $errors[] = "Fila {$rowNum}: name vacío";
                continue;
            }
            if ($email !== '' && !filter_var($email, FILTER_VALIDATE_EMAIL)) {
                $errors[] = "Fila {$rowNum}: email inválido";
                continue;
            }
            self::addGuest($userId, $eventId, $name, $phone !== '' ? $phone : null, $email !== '' ? $email : null, $adults, $kids);
            $imported++;
        }
        fclose($handle);
        return ['imported' => $imported, 'errors' => $errors];
    }
}
