import { FastifyInstance } from "fastify"
import {
    stafftimeentries,
    stafftimenetryconnects
} from "../../../db/schema"
import {
    eq,
    and,
    gte,
    lte,
    desc
} from "drizzle-orm"
import {stafftimeevents} from "../../../db/schema/staff_time_events";
import {compareTimeEvents, loadRelatedAdminEvents, loadValidEvents} from "../../modules/time/loadvalidevents.service";
import {deriveTimeSpans} from "../../modules/time/derivetimespans.service";
import {buildTimeEvaluationFromSpans} from "../../modules/time/buildtimeevaluation.service";
import {z} from "zod";
import {enrichSpansWithStatus} from "../../modules/time/enrichtimespanswithstatus.service";

export default async function staffTimeRoutesInternal(server: FastifyInstance) {


    server.post("/staff/time/event", async (req, reply) => {
        try {

            const body = req.body as {user_id:string,tenant_id:number,eventtime:string,eventtype:string}

            const normalizeDate = (val: any) => {
                if (!val) return null
                const d = new Date(val)
                return isNaN(d.getTime()) ? null : d
            }

            const dataToInsert = {
                tenant_id: body.tenant_id,
                user_id: body.user_id,
                actortype: "user",
                actoruser_id: body.user_id,
                eventtime: normalizeDate(body.eventtime),
                eventtype: body.eventtype,
                source: "WEB"
            }

            console.log(dataToInsert)

            const [created] = await server.db
                .insert(stafftimeevents)
                //@ts-ignore
                .values(dataToInsert)
                .returning()

            return created
        } catch (err: any) {
            console.error(err)
            return reply.code(400).send({ error: err.message })
        }
    })


    // GET /api/staff/time/spans
    server.get("/staff/time/spans", async (req, reply) => {
        try {

            // Query-Parameter: targetUserId ist optional
            const { targetUserId, tenantId} = req.query as { targetUserId: string, tenantId:number };

            // Falls eine targetUserId übergeben wurde, nutzen wir diese, sonst die eigene ID
            const evaluatedUserId = targetUserId;

            // 💡 "Unendlicher" Zeitraum, wie gewünscht
            const startDate = new Date(0); // 1970
            const endDate = new Date("2100-12-31");

            // SCHRITT 1: Lade ALLE Events für den ZIEL-USER (evaluatedUserId)
            const allEventsInTimeFrame = await loadValidEvents(
                server,
                tenantId,
                evaluatedUserId, // <--- Hier wird jetzt die variable ID genutzt
                startDate,
                endDate
            );

            // SCHRITT 2: Filtere faktische Events
            const FACTUAL_EVENT_TYPES = new Set([
                "work_start", "work_end", "pause_start", "pause_end",
                "sick_start", "sick_end", "vacation_start", "vacation_end",
                "overtime_compensation_start", "overtime_compensation_end",
                "auto_stop"
            ]);
            const factualEvents = allEventsInTimeFrame.filter(e => FACTUAL_EVENT_TYPES.has(e.eventtype));

            // SCHRITT 3: Hole administrative Events
            const factualEventIds = factualEvents.map(e => e.id);

            if (factualEventIds.length === 0) {
                return [];
            }

            const relatedAdminEvents = await loadRelatedAdminEvents(server, factualEventIds);

            // SCHRITT 4: Kombinieren und Sortieren
            const combinedEvents = [
                ...factualEvents,
                ...relatedAdminEvents,
            ].sort(compareTimeEvents);

            // SCHRITT 5: Spans ableiten
            const derivedSpans = deriveTimeSpans(combinedEvents);

            // SCHRITT 6: Spans anreichern
            const enrichedSpans = enrichSpansWithStatus(derivedSpans, combinedEvents);

            return enrichedSpans;

        } catch (error) {
            console.error("Fehler beim Laden der Spans:", error);
            return reply.code(500).send({ error: "Interner Fehler beim Laden der Zeitspannen." });
        }
    });


}
