import dayjs from "dayjs"
import customParseFormat from "dayjs/plugin/customParseFormat"

dayjs.extend(customParseFormat)

export const TAX_EVALUATION_PERIOD_OPTIONS = [
    { label: "Monatlich", value: "monthly" },
    { label: "Quartalsweise", value: "quarterly" },
    { label: "Jährlich", value: "yearly" },
]

export const normalizeTaxEvaluationPeriod = (value?: string) => {
    if (value === "quarterly" || value === "yearly") return value
    return "monthly"
}

const ZERO_BREAKDOWN = () => ({
    net19: 0,
    tax19: 0,
    net7: 0,
    tax7: 0,
    net0: 0,
})

const isTaxFreeDocument = (taxType?: string | null) => {
    return ["13b UStG", "19 UStG", "12.3 UStG"].includes(String(taxType || ""))
}

export const getTaxEvaluationPeriodBounds = (
    referenceDate: dayjs.ConfigType,
    period: string
) => {
    const normalized = normalizeTaxEvaluationPeriod(period)
    const base = dayjs(referenceDate)

    if (normalized === "yearly") {
        return {
            start: base.startOf("year"),
            end: base.endOf("year"),
        }
    }

    if (normalized === "quarterly") {
        const quarterStartMonth = Math.floor(base.month() / 3) * 3
        const start = base.month(quarterStartMonth).startOf("month")

        return {
            start,
            end: start.add(2, "month").endOf("month"),
        }
    }

    return {
        start: base.startOf("month"),
        end: base.endOf("month"),
    }
}

export const shiftTaxEvaluationPeriodStart = (
    periodStart: dayjs.ConfigType,
    period: string,
    offset: number
) => {
    const normalized = normalizeTaxEvaluationPeriod(period)
    const base = dayjs(periodStart)

    if (normalized === "yearly") return base.add(offset, "year").startOf("year")
    if (normalized === "quarterly") return base.add(offset * 3, "month").startOf("month")
    return base.add(offset, "month").startOf("month")
}

export const formatTaxEvaluationPeriodLabel = (
    periodStart: dayjs.ConfigType,
    period: string
) => {
    const { start, end } = getTaxEvaluationPeriodBounds(periodStart, period)
    const normalized = normalizeTaxEvaluationPeriod(period)

    if (normalized === "yearly") {
        return start.format("YYYY")
    }

    if (normalized === "quarterly") {
        return `Q${Math.floor(start.month() / 3) + 1} ${start.format("YYYY")}`
    }

    return start.format("MMMM YYYY")
}

export const formatTaxEvaluationPeriodRange = (
    periodStart: dayjs.ConfigType,
    period: string
) => {
    const { start, end } = getTaxEvaluationPeriodBounds(periodStart, period)
    return `${start.format("DD.MM.YYYY")} - ${end.format("DD.MM.YYYY")}`
}

export const getCreatedDocumentTaxBreakdown = (doc: any) => {
    const breakdown = ZERO_BREAKDOWN()

    if (!doc || isTaxFreeDocument(doc.taxType)) {
        return breakdown
    }

    ;(doc.rows || []).forEach((row: any) => {
        if (!row || ["pagebreak", "title", "text"].includes(row.mode)) return

        const quantity = Number(row.quantity || 0)
        const price = Number(row.price || 0)
        const discountPercent = Number(row.discountPercent || 0)
        const taxPercent = Number(row.taxPercent || 0)
        const net = Number((quantity * price * (1 - discountPercent / 100)).toFixed(2))

        if (!Number.isFinite(net) || net === 0) return

        if (taxPercent === 19) {
            breakdown.net19 += net
            breakdown.tax19 += Number((net * 0.19).toFixed(2))
        } else if (taxPercent === 7) {
            breakdown.net7 += net
            breakdown.tax7 += Number((net * 0.07).toFixed(2))
        } else {
            breakdown.net0 += net
        }
    })

    return {
        net19: Number(breakdown.net19.toFixed(2)),
        tax19: Number(breakdown.tax19.toFixed(2)),
        net7: Number(breakdown.net7.toFixed(2)),
        tax7: Number(breakdown.tax7.toFixed(2)),
        net0: Number(breakdown.net0.toFixed(2)),
    }
}

export const getIncomingInvoiceTaxBreakdown = (invoice: any) => {
    const breakdown = ZERO_BREAKDOWN()

    ;(invoice?.accounts || []).forEach((account: any) => {
        const taxType = String(account?.taxType || "")
        const amountNet = Number(account?.amountNet || 0)
        const amountTax = Number(account?.amountTax || 0)

        if (taxType === "19") {
            breakdown.net19 += amountNet
            breakdown.tax19 += amountTax
        } else if (taxType === "7") {
            breakdown.net7 += amountNet
            breakdown.tax7 += amountTax
        } else {
            breakdown.net0 += amountNet
        }
    })

    return {
        net19: Number(breakdown.net19.toFixed(2)),
        tax19: Number(breakdown.tax19.toFixed(2)),
        net7: Number(breakdown.net7.toFixed(2)),
        tax7: Number(breakdown.tax7.toFixed(2)),
        net0: Number(breakdown.net0.toFixed(2)),
    }
}
