use std::io::Write;
use super::utils::{write_f32, write_pdf};
use super::ImageResource;
use crate::color::color_to_pdf_rgb;

pub fn render_image_item(
    page_height: f32,
    image: &crate::layout::LayoutImage,
    image_resources: &[ImageResource],
) -> Vec<u8> {
    let Some(resource) = image_resources.iter().find(|r| r.image.x == image.x && r.image.y == image.y && r.image.width == image.width && r.image.height == image.height) else {
        return Vec::new();
    };

    let has_opacity = image.opacity.is_some_and(|o| o < 1.0);

    if let Some(cover) = &image.cover {
        let cy = page_height - image.y - cover.height;
        let (ox, oy, sw, sh) = crate::image::calculate_cover(image.intrinsic_width, image.intrinsic_height, cover);
        let draw_y = cy + cover.height - oy - sh;
        let mut buf = Vec::with_capacity(128);
        if has_opacity {
            let gs_name = format!("/gs{}", (image.opacity.unwrap() * 100.0) as u32);
            write_pdf!(buf, "q {} gs\n", gs_name);
        }
        write_pdf!(buf, "q {:.2} {:.2} {:.2} {:.2} re W n\n", image.x, cy, cover.width, cover.height);
        write_pdf!(buf, "q {:.2} 0 0 {:.2} {:.2} {:.2} cm /{} Do Q\n", sw, sh, image.x + ox, draw_y, resource.name);
        buf.extend_from_slice(b"Q\n");
        if has_opacity {
            buf.extend_from_slice(b"Q\n");
        }
        buf
    } else {
        let y = page_height - image.y - image.height;
        let mut buf = Vec::with_capacity(64);
        if has_opacity {
            let gs_name = format!("/gs{}", (image.opacity.unwrap() * 100.0) as u32);
            write_pdf!(buf, "q {} gs\n", gs_name);
        }
        write_pdf!(buf, "q {:.2} 0 0 {:.2} {:.2} {:.2} cm /{} Do Q\n", image.width, image.height, image.x, y, resource.name);
        if has_opacity {
            buf.extend_from_slice(b"Q\n");
        }
        buf
    }
}

pub fn render_qr_item(page_height: f32, qr: &crate::layout::LayoutQr) -> Vec<u8> {
    let mut stream = Vec::new();
    if qr.modules == 0 { return stream; }
    let pad = qr.padding.unwrap_or(0.0);
    let inner_size = (qr.width - pad * 2.0).max(0.0);
    let module_size = inner_size / qr.modules as f32;

    // Background
    if let Some(ref bg) = qr.background
        && let Some((r, g, b)) = color_to_pdf_rgb(bg) {
            stream.extend_from_slice(b"q ");
            write_f32(&mut stream, r, 3); stream.push(b' ');
            write_f32(&mut stream, g, 3); stream.push(b' ');
            write_f32(&mut stream, b, 3); stream.extend_from_slice(b" rg ");
            write_f32(&mut stream, qr.x, 2); stream.push(b' ');
            write_f32(&mut stream, page_height - qr.y - qr.width, 2); stream.push(b' ');
            write_f32(&mut stream, qr.width, 2); stream.push(b' ');
            write_f32(&mut stream, qr.width, 2); stream.extend_from_slice(b" re f Q\n");
        }

    // Foreground (dark modules)
    let fg = qr.foreground.as_deref().unwrap_or("0"); // default black
    if let Some((r, g, b)) = color_to_pdf_rgb(fg) {
        write_f32(&mut stream, r, 3); stream.push(b' ');
        write_f32(&mut stream, g, 3); stream.push(b' ');
        write_f32(&mut stream, b, 3); stream.extend_from_slice(b" rg\n");
    } else {
        stream.extend_from_slice(b"0 g\n");
    }

    for module in &qr.dark_modules {
        let x = qr.x + pad + module.x as f32 * module_size;
        let y_top = qr.y + pad + module.y as f32 * module_size;
        let y = page_height - y_top - module_size;
        write_pdf!(stream, "{:.2} {:.2} {:.2} {:.2} re f\n", x, y, module_size, module_size);
    }
    stream
}
