import QRCode from 'qrcode';
import { BRANCH_QR_BASE_URL } from '../constants.js';

const DEFAULT_QR_SECRET = 'qms-branch-qr-v1';

function getQrSecret() {
    return import.meta.env.VITE_QR_TOKEN_SECRET || DEFAULT_QR_SECRET;
}

function toBase64Url(bytes) {
    let binary = '';
    bytes.forEach((byte) => {
        binary += String.fromCharCode(byte);
    });
    return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, '');
}

function fromBase64Url(token) {
    const padded = token.replace(/-/g, '+').replace(/_/g, '/');
    const padLength = (4 - (padded.length % 4)) % 4;
    const base64 = padded + '='.repeat(padLength);
    const binary = atob(base64);
    const bytes = new Uint8Array(binary.length);
    for (let i = 0; i < binary.length; i += 1) {
        bytes[i] = binary.charCodeAt(i);
    }
    return bytes;
}

function xorBytes(bytes, secret) {
    const key = new TextEncoder().encode(secret);
    return bytes.map((byte, index) => byte ^ key[index % key.length]);
}

/** Opaque token so QR URLs don't expose tenant code / branch id. */
export function encodeBranchQrToken(tenantCode, branchId, secret = getQrSecret()) {
    const plain = `v1:${String(tenantCode).trim().toUpperCase()}:${Number(branchId)}`;
    const plainBytes = new TextEncoder().encode(plain);
    return toBase64Url(xorBytes(plainBytes, secret));
}

export function decodeBranchQrToken(token, secret = getQrSecret()) {
    try {
        const plain = new TextDecoder().decode(xorBytes(fromBase64Url(token), secret));
        const match = /^v1:([^:]+):(\d+)$/.exec(plain);
        if (!match) return null;
        return {
            tenantCode: match[1],
            branchId: Number(match[2]),
        };
    } catch {
        return null;
    }
}

export function getBranchTicketUrl(tenantCode, branchId) {
    const base = BRANCH_QR_BASE_URL.replace(/\/$/, '');
    const token = encodeBranchQrToken(tenantCode, branchId);
    return `${base}/q/${token}`;
}

export async function generateBranchQrDataUrl(tenantCode, branchId) {
    return QRCode.toDataURL(getBranchTicketUrl(tenantCode, branchId), {
        errorCorrectionLevel: 'M',
        margin: 2,
        width: 1024,
        color: {
            dark: '#000000',
            light: '#ffffff',
        },
    });
}

function slugify(value) {
    return String(value)
        .trim()
        .toLowerCase()
        .replace(/[^a-z0-9]+/g, '-')
        .replace(/^-|-$/g, '') || 'branch';
}

export function downloadDataUrl(dataUrl, filename) {
    const link = document.createElement('a');
    link.href = dataUrl;
    link.download = filename;
    link.click();
}

export async function downloadBranchQr({ tenantCode, branchId, branchName }) {
    const dataUrl = await generateBranchQrDataUrl(tenantCode, branchId);
    downloadDataUrl(dataUrl, `qr-${slugify(branchName)}-${branchId}.png`);
    return dataUrl;
}
