<template>
    <view class="share-poster-modal">
        <view v-if="visible && !showPosterPreview" class="modal-overlay" @click="handleClose">
            <view class="modal-box" @click.stop>
                <!-- 关闭按钮 -->
                <view class="close-btn" @click="handleClose">
                    <text class="close-icon">×</text>
                </view>

                <!-- 海报预览 -->
                <view class="poster-preview">
                    <view class="poster-header">
                        <text class="poster-symbol">☯</text>
                        <text class="poster-title">易凡起名</text>
                        <text class="poster-subtitle">传承国学智慧 · 赋予美好寓意</text>
                    </view>

                    <view class="poster-card">
                        <view class="service-list">
                            <view class="service-item" v-for="item in services" :key="item">
                                <view class="service-dot"></view>
                                <text class="service-text">{{ item }}</text>
                            </view>
                        </view>

                        <view class="poster-divider"></view>

                        <view class="qr-area">
                            <view class="qr-box">
                                <image v-if="qrImageUrl" :src="qrImageUrl" class="qr-image" mode="aspectFit" />
                            </view>
                            <text class="invite-text">邀请码：{{ userId }}</text>
                        </view>
                    </view>

                    <text class="poster-footer">— 邀您共探姓名玄机 —</text>
                </view>

                <!-- 按钮 -->
                <view class="btn-row">
                    <button class="btn btn-share" open-type="share">
                        <text class="btn-label">分享好友</text>
                    </button>
                    <view class="btn btn-save" @click="handleSave">
                        <text class="btn-label">{{ isSaving ? '生成中...' : '保存图片' }}</text>
                    </view>
                </view>
            </view>
        </view>
    </view>

    <!-- 海报图片预览（直接展示） -->
    <view v-if="showPosterPreview" class="poster-save-overlay" @click="handleClose">
        <view class="poster-save-tip">{{ isSaving ? '海报生成中...' : '海报已生成，可保存到本地' }}</view>
        <img v-if="posterDataUrl" :src="posterDataUrl" class="poster-save-image" @click.stop />
        <view v-else class="poster-save-loading">海报生成中...</view>
        <view class="poster-save-actions" @click.stop>
            <view class="poster-save-btn" :class="{ 'poster-save-btn-disabled': !posterDataUrl || isSaving }" @click="handleSave">
                {{ isSaving ? '生成中...' : '保存图片' }}
            </view>
            <view class="poster-save-close" @click="handleClose">关闭</view>
        </view>
    </view>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick } from 'vue';
// @ts-ignore
import QRCode from '@/utils/qrcode.js';

const props = defineProps<{
    visible: boolean;
    userId: number;
}>();

const emit = defineEmits<{
    close: [];
}>();

const services = ['个人起名', '公司起名', '专业测名', '择吉日'];
const qrModules = ref<number[][]>([]);
const qrImageUrl = ref('');
const isSaving = ref(false);
const posterDataUrl = ref('');
const showPosterPreview = ref(false);

const QR_SIZE = 400;
const POSTER_WIDTH = 300;
const POSTER_HEIGHT = 500;
const POSTER_SCALE = 2;

const qrUrl = computed(() => `https://yfh5.action-ai.cn?invite_id=${encodeURIComponent(String(props.userId || ''))}`);

watch(() => props.visible, async (val) => {
    if (val) {
        posterDataUrl.value = '';
        qrImageUrl.value = '';
        showPosterPreview.value = true;
        await nextTick();
        await preparePoster();
    } else {
        showPosterPreview.value = false;
    }
});

const createCanvas = (width: number, height: number): HTMLCanvasElement => {
    const canvas = document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;
    return canvas;
};

const generateQrModules = (): number[][] => {
    const result = QRCode.generate(qrUrl.value, { errorCorrectionLevel: 'M' });
    const modules = result.modules || [];
    qrModules.value = modules;
    return modules;
};

const drawQrModulesToCanvas = (
    ctx: CanvasRenderingContext2D,
    modules: number[][],
    x: number,
    y: number,
    size: number
) => {
    const count = modules.length;
    if (!count) return;
    const cell = size / count;
    ctx.fillStyle = '#FFFFFF';
    ctx.fillRect(x, y, size, size);
    ctx.fillStyle = '#000000';
    for (let r = 0; r < count; r++) {
        for (let c = 0; c < count; c++) {
            if (modules[r][c]) ctx.fillRect(x + c * cell, y + r * cell, Math.ceil(cell), Math.ceil(cell));
        }
    }
};

const generateQrImage = async (): Promise<string> => {
    qrImageUrl.value = '';
    const modules = generateQrModules();
    if (!modules.length) {
        throw new Error('qrcode modules empty');
    }
    const canvas = createCanvas(QR_SIZE, QR_SIZE);
    const ctx = canvas.getContext('2d');
    if (!ctx) {
        throw new Error('qrcode canvas context unavailable');
    }
    drawQrModulesToCanvas(ctx, modules, 0, 0, QR_SIZE);
    qrImageUrl.value = canvas.toDataURL('image/png');
    return qrImageUrl.value;
};

const handleClose = () => {
    showPosterPreview.value = false;
    emit('close');
};

// H5专用loading/toast
const showLoading = (title: string) => {
    if (typeof uni?.showLoading === 'function') {
        uni.showLoading({ title });
    }
};
const hideLoading = () => {
    if (typeof uni?.hideLoading === 'function') {
        uni.hideLoading();
    }
};
const showToast = (opts: { title: string; icon?: string }) => {
    if (typeof uni?.showToast === 'function') {
        uni.showToast(opts);
    } else {
        alert(opts.title);
    }
};

// 绘制圆角矩形
const drawRoundRect = (ctx: any, x: number, y: number, w: number, h: number, r: number) => {
    ctx.beginPath();
    ctx.moveTo(x + r, y);
    ctx.arcTo(x + w, y, x + w, y + h, r);
    ctx.arcTo(x + w, y + h, x, y + h, r);
    ctx.arcTo(x, y + h, x, y, r);
    ctx.arcTo(x, y, x + w, y, r);
    ctx.closePath();
};

const drawImage = (
    ctx: CanvasRenderingContext2D,
    src: string,
    x: number,
    y: number,
    w: number,
    h: number
) => {
    return new Promise<void>((resolve, reject) => {
        const img = new Image();
        img.onload = () => {
            ctx.drawImage(img, x, y, w, h);
            resolve();
        };
        img.onerror = () => reject(new Error('image load failed'));
        img.src = src;
    });
};

const triggerDownload = (src: string, fileName: string) => {
    try {
        const link = document.createElement('a');
        if (typeof link.download !== 'string') {
            return false;
        }
        link.href = src;
        link.download = fileName;
        link.rel = 'noopener';
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        return true;
    } catch (e) {
        return false;
    }
};

const buildPosterDataUrl = async (qrSrc: string) => {
    const width = POSTER_WIDTH * POSTER_SCALE;
    const height = POSTER_HEIGHT * POSTER_SCALE;
    const posterCanvas = createCanvas(width, height);
    const ctx = posterCanvas.getContext('2d');
    if (!ctx) {
        throw new Error('poster canvas context unavailable');
    }
    ctx.scale(POSTER_SCALE, POSTER_SCALE);
    const w = POSTER_WIDTH;
    const h = POSTER_HEIGHT;

    // 1. 背景
    ctx.fillStyle = '#2d1515';
    ctx.fillRect(0, 0, w, h);
    ctx.fillStyle = '#d4af37';
    ctx.fillRect(0, 0, w, 5);

    // 2. 标题区
    ctx.textAlign = 'center';
    ctx.fillStyle = '#d4af37';
    ctx.font = 'bold 28px serif';
    ctx.fillText('☯', w / 2, 45);
    ctx.fillStyle = '#f2e6d8';
    ctx.font = 'bold 22px serif';
    ctx.fillText('易凡起名', w / 2, 80);
    ctx.fillStyle = '#d4af37';
    ctx.font = '12px sans-serif';
    ctx.fillText('传承国学智慧 · 赋予美好寓意', w / 2, 100);

    // 3. 卡片
    const cardX = 20;
    const cardY = 115;
    const cardW = w - 40;
    const cardH = 310;
    ctx.fillStyle = '#fffdf9';
    drawRoundRect(ctx, cardX, cardY, cardW, cardH, 8);
    ctx.fill();

    // 4. 服务项目
    ctx.font = '13px sans-serif';
    ctx.textAlign = 'left';
    services.forEach((name, i) => {
        const col = i % 2;
        const row = Math.floor(i / 2);
        const x = cardX + 25 + col * 115;
        const y = cardY + 32 + row * 26;
        ctx.fillStyle = '#8b2323';
        ctx.beginPath();
        ctx.arc(x - 8, y - 4, 3, 0, Math.PI * 2);
        ctx.fill();
        ctx.fillStyle = '#333';
        ctx.fillText(name, x, y);
    });

    // 5. 分隔线
    const lineY = cardY + 85;
    ctx.strokeStyle = '#d4af37';
    ctx.lineWidth = 1;
    ctx.beginPath();
    ctx.moveTo(cardX + 15, lineY);
    ctx.lineTo(cardX + cardW - 15, lineY);
    ctx.stroke();

    // 6. 二维码
    const qrSize = 120;
    const qrX = (w - qrSize) / 2;
    const qrY = lineY + 15;
    ctx.strokeStyle = '#d4af37';
    ctx.lineWidth = 2;
    ctx.strokeRect(qrX - 5, qrY - 5, qrSize + 10, qrSize + 10);
    ctx.fillStyle = '#fff';
    ctx.fillRect(qrX, qrY, qrSize, qrSize);

    try {
        await drawImage(ctx, qrSrc, qrX, qrY, qrSize, qrSize);
    } catch (e) {
        if (qrModules.value.length) {
            drawQrModulesToCanvas(ctx, qrModules.value, qrX, qrY, qrSize);
        }
    }

    // 7. 邀请码
    ctx.textAlign = 'center';
    ctx.fillStyle = '#8b2323';
    ctx.font = '12px sans-serif';
    ctx.fillText(`邀请码：${props.userId}`, w / 2, qrY + qrSize + 20);
    ctx.fillStyle = '#999';
    ctx.font = '11px sans-serif';
    ctx.fillText('长按识别 · 开启好运', w / 2, qrY + qrSize + 38);

    // 8. 底部
    ctx.fillStyle = '#d4af37';
    ctx.font = '11px sans-serif';
    ctx.fillText('— 邀您共探姓名玄机 —', w / 2, h - 20);
    ctx.fillRect(0, h - 5, w, 5);

    return posterCanvas.toDataURL('image/png');
};

const preparePoster = async () => {
    if (isSaving.value) return;
    isSaving.value = true;
    showLoading('生成中...');

    try {
        const qrSrc = qrImageUrl.value || await generateQrImage();
        posterDataUrl.value = await buildPosterDataUrl(qrSrc);
    } catch (err: any) {
        console.error('海报生成失败:', err);
        showToast({ title: '生成失败', icon: 'none' });
    } finally {
        hideLoading();
        isSaving.value = false;
    }
};

const handleSave = async () => {
    if (isSaving.value) return;
    if (!posterDataUrl.value) {
        await preparePoster();
    }
    if (!posterDataUrl.value) return;

    const downloaded = triggerDownload(posterDataUrl.value, `poster-${props.userId || 'share'}.png`);
    showToast({ title: downloaded ? '已下载海报' : '请长按图片保存', icon: downloaded ? 'success' : 'none' });
};
</script>

<style scoped>
.modal-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.8);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 9999;
}

.modal-box {
    width: 85%;
    max-width: 600rpx;
    position: relative;
}

.close-btn {
    position: absolute;
    top: -50rpx;
    right: 0;
    width: 50rpx;
    height: 50rpx;
    display: flex;
    align-items: center;
    justify-content: center;
}

.close-icon {
    font-size: 40rpx;
    color: rgba(255, 255, 255, 0.7);
}

/* 海报预览 */
.poster-preview {
    background: linear-gradient(180deg, #1a0a0a 0%, #2d1515 50%, #1a0a0a 100%);
    border-radius: 16rpx;
    padding: 40rpx 32rpx;
    border: 4rpx solid #d4af37;
}

.poster-header {
    text-align: center;
    margin-bottom: 32rpx;
}

.poster-symbol {
    font-size: 44rpx;
    color: #d4af37;
    display: block;
    margin-bottom: 12rpx;
}

.poster-title {
    font-size: 44rpx;
    font-weight: bold;
    color: #f2e6d8;
    letter-spacing: 0.2em;
    display: block;
}

.poster-subtitle {
    font-size: 20rpx;
    color: #d4af37;
    display: block;
    margin-top: 12rpx;
}

.poster-card {
    background: #fffdf9;
    border-radius: 12rpx;
    padding: 28rpx 24rpx;
}

.service-list {
    display: flex;
    flex-wrap: wrap;
}

.service-item {
    width: 50%;
    display: flex;
    align-items: center;
    margin-bottom: 16rpx;
}

.service-dot {
    width: 10rpx;
    height: 10rpx;
    background: #8b2323;
    border-radius: 50%;
    margin-right: 12rpx;
}

.service-text {
    font-size: 24rpx;
    color: #333;
}

.poster-divider {
    height: 1rpx;
    background: #d4af37;
    margin: 20rpx 0;
}

.qr-area {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.qr-box {
    width: 180rpx;
    height: 180rpx;
    padding: 8rpx;
    border: 2rpx solid #d4af37;
    background: #fff;
}

.qr-image {
    width: 100%;
    height: 100%;
}

.invite-text {
    font-size: 22rpx;
    color: #8b2323;
    margin-top: 16rpx;
}

.scan-text {
    font-size: 18rpx;
    color: #999;
    margin-top: 6rpx;
}

.poster-footer {
    text-align: center;
    font-size: 20rpx;
    color: #d4af37;
    margin-top: 24rpx;
    display: block;
}

/* 按钮 */
.btn-row {
    display: flex;
    gap: 20rpx;
    margin-top: 28rpx;
}

.btn {
    flex: 1;
    height: 84rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 12rpx;
    border: none;
    padding: 0;
    margin: 0;
}

.btn::after {
    border: none;
}

.btn-share {
    background: linear-gradient(135deg, #8b2323, #6b1a1a);
}

.btn-save {
    background: linear-gradient(135deg, #d4af37, #b8962e);
}

.btn-label {
    font-size: 28rpx;
    color: #fff;
    font-weight: 500;
}

.poster-save-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.9);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    z-index: 10000;
}

.poster-save-tip {
    color: #fff;
    font-size: 28rpx;
    margin-bottom: 24rpx;
}

.poster-save-image {
    max-width: 80%;
    max-height: 70vh;
    border-radius: 16rpx;
}

.poster-save-loading {
    color: rgba(255, 255, 255, 0.8);
    font-size: 24rpx;
    padding: 60rpx 0;
}

.poster-save-actions {
    display: flex;
    gap: 20rpx;
    margin-top: 24rpx;
}

.poster-save-btn {
    background: linear-gradient(135deg, #d4af37, #b8962e);
    color: #fff;
    font-size: 26rpx;
    border-radius: 12rpx;
    padding: 14rpx 40rpx;
}

.poster-save-btn-disabled {
    opacity: 0.6;
}

.poster-save-close {
    margin-top: 0;
    color: rgba(255, 255, 255, 0.7);
    font-size: 28rpx;
    padding: 16rpx 40rpx;
}
</style>
