import { FastifyInstance } from "fastify";
import {buildExportZip} from "../utils/export/datev";
import {s3} from "../utils/s3";
import {GetObjectCommand, PutObjectCommand} from "@aws-sdk/client-s3"
import {getSignedUrl} from "@aws-sdk/s3-request-presigner";
import dayjs from "dayjs";
import {randomUUID} from "node:crypto";
import {secrets} from "../utils/secrets";
import {createSEPAExport} from "../utils/export/sepa";
import {generatedexports} from "../../db/schema";
import {eq} from "drizzle-orm";

const createDatevExport = async (server:FastifyInstance,req:any,startDate,endDate,beraternr,mandantennr) => {
    try {
        console.log(startDate,endDate,beraternr,mandantennr)

        // 1) ZIP erzeugen
        const buffer = await buildExportZip(server,req.user.tenant_id, startDate, endDate, beraternr, mandantennr)
        console.log("ZIP created")
        console.log(buffer)

        // 2) Dateiname & Key festlegen
        const fileKey = `${req.user.tenant_id}/exports/Export_${dayjs(startDate).format("YYYY-MM-DD")}_${dayjs(endDate).format("YYYY-MM-DD")}_${randomUUID()}.zip`
        console.log(fileKey)

        // 3) In S3 hochladen
        await s3.send(
            new PutObjectCommand({
                Bucket: secrets.S3_BUCKET,
                Key: fileKey,
                Body: buffer,
                ContentType: "application/zip",
            })
        )

        // 4) Presigned URL erzeugen (24h gültig)
        const url = await getSignedUrl(
            s3,
            new GetObjectCommand({
                Bucket: secrets.S3_BUCKET,
                Key: fileKey,
            }),
            { expiresIn: 60 * 60 * 24 }
        )

        console.log(url)

        // 5) In Haupt-DB speichern
        const inserted = await server.db
            .insert(generatedexports)
            .values({
                tenantId: req.user.tenant_id,
                startDate: new Date(startDate),
                endDate: new Date(endDate),
                validUntil: dayjs().add(24, "hours").toDate(),
                filePath: fileKey,
                url,
                type: "datev",
            })
            .returning()

        console.log(inserted[0])
    } catch (error) {
        console.log(error)
    }


}

const createSepaExport = async (server: FastifyInstance, req: any, idsToExport: number[], creditorBankaccountId: number) => {
    const exportData = await createSEPAExport(server, idsToExport, req.user.tenant_id, creditorBankaccountId)

    const fileKey = `${req.user.tenant_id}/exports/SEPA_${dayjs().format("YYYY-MM-DD")}_${randomUUID()}.xml`

    await s3.send(
        new PutObjectCommand({
            Bucket: secrets.S3_BUCKET,
            Key: fileKey,
            Body: exportData.buffer,
            ContentType: "application/xml",
        })
    )

    const url = await getSignedUrl(
        s3,
        new GetObjectCommand({
            Bucket: secrets.S3_BUCKET,
            Key: fileKey,
        }),
        { expiresIn: 60 * 60 * 24 }
    )

    const inserted = await server.db
        .insert(generatedexports)
        .values({
            tenantId: req.user.tenant_id,
            startDate: exportData.startDate,
            endDate: exportData.endDate,
            validUntil: dayjs().add(24, "hours").toDate(),
            filePath: fileKey,
            url,
            type: "sepa",
        })
        .returning()

    console.log(inserted[0])
}


export default async function exportRoutes(server: FastifyInstance) {
    //Export DATEV
    server.post("/exports/datev", async (req, reply) => {
        const { start_date, end_date, beraternr, mandantennr } = req.body as {
            start_date: string
            end_date: string
            beraternr: string
            mandantennr: string
        }



        reply.send({success:true})

        setImmediate(async () => {
            try {
                await createDatevExport(server,req,start_date,end_date,beraternr,mandantennr)
                console.log("Job done ✅")
            } catch (err) {
                console.error("Job failed ❌", err)
            }
        })

    })

    server.post("/exports/sepa", async (req, reply) => {
        const { idsToExport, creditorBankaccountId } = req.body as {
            idsToExport: Array<number>
            creditorBankaccountId: number
        }

        if (!idsToExport?.length || !creditorBankaccountId) {
            return reply.send({
                success: false,
                message: "Belege und Gläubigerkonto sind Pflichtfelder."
            })
        }


        reply.send({success:true})

        setImmediate(async () => {
            try {
                await createSepaExport(server, req, idsToExport, creditorBankaccountId)
                console.log("Job done ✅")
            } catch (err) {
                console.error("Job failed ❌", err)
            }
        })

    })

    //List Exports Available for Download

    server.get("/exports", async (req,reply) => {
        const data = await server.db
            .select({
                id: generatedexports.id,
                created_at: generatedexports.createdAt,
                tenant_id: generatedexports.tenantId,
                start_date: generatedexports.startDate,
                end_date: generatedexports.endDate,
                valid_until: generatedexports.validUntil,
                type: generatedexports.type,
                url: generatedexports.url,
                file_path: generatedexports.filePath,
            })
            .from(generatedexports)
            .where(eq(generatedexports.tenantId, req.user.tenant_id))

        console.log(data)
        reply.send(data)

    })





}
