use anyhow::anyhow;
use egui::{Button, RichText, Ui};
use egui_extras::{Column, TableBuilder};
use log::warn;

use crate::views::stats_viewer::create_file_download;
use crate::{app_state::AppState, stream::CurrentFrame};

use crate::views::{RenderView, SelectedObject};

use super::SelectedObjectKind;

pub struct BlockInfoViewer;

// TODO(comc): Click on a MV to load the corresponding frame and block.
impl RenderView for BlockInfoViewer {
    fn title(&self) -> String {
        "Block Info".into()
    }

    fn render(&self, ui: &mut Ui, state: &mut AppState) -> anyhow::Result<()> {
        let Some(frame) = state.stream.current_frame() else {
            // No frame loaded yet.
            return Ok(());
        };
        let Some(SelectedObject {
            kind: selected_object_kind,
            ..
        }) = &state.settings.selected_object
        else {
            // Nothing is selected.
            return Ok(());
        };
        let selected_object_kind = selected_object_kind.clone();
        let is_transform_unit = matches!(selected_object_kind, SelectedObjectKind::TransformUnit(_));
        let is_superblock = matches!(selected_object_kind, SelectedObjectKind::Superblock(_));
        if ui.add_enabled(!is_superblock, Button::new("Go to parent")).clicked() {
            if let Some(parent) = selected_object_kind.get_parent(frame) {
                state.settings.selected_object = Some(SelectedObject::new(parent));
            }
        }
        ui.end_row();

        if ui.button("Show pixels for current block").clicked() {
            state.settings.sharable.show_pixel_viewer = true;
        }
        ui.end_row();

        if let SelectedObjectKind::CodingUnit(cu) = selected_object_kind {
            let ctx = cu.try_resolve(frame).ok_or(anyhow!("Invalid coding unit index"))?;
            if ui.button("Dump current block as JSON").clicked() {
                if let Some(stream) = &state.stream {
                    let Some(rect) = selected_object_kind.rect(frame) else {
                        return Err(anyhow!("Invalid coding unit index"));
                    };
                    let file_name = format!(
                        "{}_frame_{:04}_block_{}x{}_x{}_y{}.json",
                        stream.stream_info.stream_name,
                        stream.current_frame_index,
                        rect.width() as i32,
                        rect.height() as i32,
                        rect.left_top().x as i32,
                        rect.left_top().y as i32,
                    );

                    let data = serde_json::to_string_pretty(ctx.coding_unit).unwrap();

                    if let Err(err) = create_file_download(data.as_bytes(), &file_name) {
                        warn!("Failed to create file download: {err:?}");
                    }
                }
            }
        }

        // TODO(comc): Grey out instead of removing?
        if is_transform_unit && ui.button("Show transform coeffs").clicked() {
            state.settings.sharable.show_coeffs_viewer = true;
        }

        ui.separator();

        let Ok(info) = state
            .settings
            .selected_object
            .as_mut()
            .unwrap()
            .get_or_calculate_info(frame)
        else {
            return Ok(());
        };

        TableBuilder::new(ui)
            .column(Column::initial(300.0).resizable(true))
            .column(Column::remainder())
            .striped(true)
            .header(20.0, |mut header| {
                header.col(|ui| {
                    ui.label(RichText::new("Property").strong());
                });
                header.col(|ui| {
                    ui.label(RichText::new("Value").strong());
                });
            })
            .body(|mut body| {
                for field in info.fields.iter() {
                    body.row(20.0, |mut row| {
                        row.col(|col| {
                            col.label(&field.name);
                        });
                        row.col(|col| {
                            col.label(&field.value);
                        });
                    });
                }
            });
        Ok(())
    }
}
