import React, { useEffect, useRef, useState } from 'react';
import {
    Accordion, AccordionSummary, AccordionDetails, Typography, Grid, Modal, Box
} from '@mui/material';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import './SampleImage.css';
import { DataGridPremium, GridColDef, GridValueGetterParams } from "@mui/x-data-grid-premium";
import { LineChart } from '@mui/x-charts/LineChart';


import { SamplesService } from "../../openapi";

interface RunDetailsProps {
    run: TreeRow;
    runId: number;
    sample_id: number;
    basePath: string;
    onHeightChange?: (height: number) => void;
    onResultsFetched: (runId: number, hasResults: boolean) => void; // New callback
}

interface CCPoint {
    resolution: number;
    value: number;
}

interface ExperimentParameters {
    run_number: number;
    id: number;
    sample_id: number;
    beamline_parameters: BeamlineParameters;
    images: Image[];
}


interface ProcessingResults {
    id: number;
    pipeline: string;
    resolution: number;
    unit_cell: string;
    spacegroup: string;
    rmerge: number;
    rmeas: number;
    isig: number;
    cc: CCPoint[];
    cchalf: CCPoint[];
    completeness: number;
    multiplicity: number;
    nobs: number;
    total_refl: number;
    unique_refl: number;
    comments?: string | null;
}


const RunDetails: React.FC<RunDetailsProps> = ({ run, onHeightChange, basePath, runId, sample_id, onResultsFetched }) => {
    console.log('onResultsFetched is available:', onResultsFetched);

    const containerRef = useRef<HTMLDivElement | null>(null);
    const [currentHeight, setCurrentHeight] = useState<number>(0);
    const [modalOpen, setModalOpen] = useState<boolean>(false);
    const [selectedImage, setSelectedImage] = useState<string | null>(null);
    const [expandedResults, setExpandedResults] = useState(false);
    const [processingResult, setProcessingResult] = useState<ProcessingResults[] | null>(null);

    const {beamline_parameters, images} = run;
    const {synchrotron, beamline, detector} = beamline_parameters;

    useEffect(() => {
        fetchResults(sample_id, runId);   // fetching based on experimentId
    }, [runId]);

    const fetchResults = async (sample_id: number, runId: number) => {
        console.log(`Fetching results for sample_id: ${sample_id}, runId: ${runId}`);
        try {
            const results = await SamplesService.getResultsForRunAndSample(sample_id, runId);

            const mappedResults: ProcessingResults[] = results.map((res): ProcessingResults => ({
                id: res.id,
                pipeline: res.result?.pipeline || 'N/A',
                resolution: res.result?.resolution ?? 0,
                unit_cell: res.result?.unit_cell || 'N/A',
                spacegroup: res.result?.spacegroup || 'N/A',
                rmerge: res.result?.rmerge ?? 0,
                rmeas: res.result?.rmeas ?? 0,
                isig: res.result?.isig ?? 0,
                cc: res.result?.cc || [],
                cchalf: res.result?.cchalf || [],
                completeness: res.result?.completeness ?? 0,
                multiplicity: res.result?.multiplicity ?? 0,
                nobs: res.result?.nobs ?? 0,
                total_refl: res.result?.total_refl ?? 0,
                unique_refl: res.result?.unique_refl ?? 0,
                comments: res.result?.comments || null,
            }));

            setProcessingResult(mappedResults);

            console.log(`Mapped results for runId ${runId}:`, mappedResults);
            console.log(`Boolean value for hasResults: ${mappedResults.length > 0}`);
            onResultsFetched(runId, mappedResults.length > 0);

        } catch (error) {
            console.error(`Error fetching results for RunId ${runId}:`, error);
        }
    };


    const resultColumns: GridColDef<ProcessingResults>[] = [
        { field: 'pipeline', headerName: 'Pipeline', flex: 1 },
        { field: 'resolution', headerName: 'Resolution (Å)', flex: 1 },
        { field: 'unit_cell', headerName: 'Unit Cell (Å)', flex: 1.5 },
        { field: 'spacegroup', headerName: 'Spacegroup', flex: 1 },
        { field: 'rmerge', headerName: 'Rmerge', flex: 1 },
        { field: 'rmeas', headerName: 'Rmeas', flex: 1 },
        { field: 'isig', headerName: 'I/sig(I)', flex: 1 },
        {
            field: 'cc',
            headerName: 'CC',
            flex: 1,
            valueGetter: (params: GridValueGetterParams<ProcessingResults, string>) =>
                Array.isArray(params.row?.cc)
                    ? params.row.cc.map((point: CCPoint) => `${point.value.toFixed(2)}@${point.resolution.toFixed(2)}`).join(', ')
                    : '',
        },
        {
            field: 'cchalf',
            headerName: 'CC(1/2)',
            flex: 1,
            valueGetter: (params: GridValueGetterParams<ProcessingResults, string>) =>
                Array.isArray(params.row?.cchalf)
                    ? params.row.cchalf.map((point: CCPoint) => `${point.value.toFixed(2)}@${point.resolution.toFixed(2)}`).join(', ')
                    : '',
        },
        { field: 'completeness', headerName: 'Completeness (%)', flex: 1 },
        { field: 'multiplicity', headerName: 'Multiplicity', flex: 1 },
        { field: 'nobs', headerName: 'N obs.', flex: 1 },
        { field: 'total_refl', headerName: 'Total Reflections', flex: 1 },
        { field: 'unique_refl', headerName: 'Unique Reflections', flex: 1 },
        { field: 'comments', headerName: 'Comments', flex: 2 },
    ];

    const updateHeight = () => {
        if (containerRef.current) {
            const newHeight = containerRef.current.offsetHeight;
            if (newHeight !== currentHeight && onHeightChange) {
                setCurrentHeight(newHeight);
                onHeightChange(newHeight);
            }
        }
    };

    useEffect(() => {
        const observer = new ResizeObserver(updateHeight);
        if (containerRef.current) observer.observe(containerRef.current);
        return () => observer.disconnect();
    }, [containerRef.current, processingResult]);

    const handleImageClick = (imagePath: string) => {
        setSelectedImage(imagePath);
        setModalOpen(true);
    };

    const closeModal = () => {
        setSelectedImage(null);
        setModalOpen(false);
    };


    return (
        <div
            className="details-panel"
            ref={containerRef}
            style={{
                display: 'flex',
                flexDirection: 'column', // Stack children vertically
                gap: '16px',
                padding: '16px',
                border: '1px solid #ccc',
                borderRadius: '4px',
            }}
        >

            {/* Wrap details and images together */}
            <div style={{display: 'flex', gap: '16px', alignItems: 'flex-start'}}>
                {/* Main Details Section */}
                <div style={{flexGrow: 1}}>
                    <Typography variant="h6" gutterBottom>
                        Run {run.run_number} Details
                    </Typography>
                    <Typography variant="subtitle1" gutterBottom>
                        Beamline: {beamline} | Synchrotron: {synchrotron}
                    </Typography>

                    {/* Detector Details Accordion */}
                    <Accordion>
                        <AccordionSummary
                            expandIcon={<ExpandMoreIcon/>}
                            aria-controls="detector-content"
                            id="detector-header"
                        >
                            <Typography><strong>Detector Details</strong></Typography>
                        </AccordionSummary>
                        <AccordionDetails>
                            <Typography>Manufacturer: {detector?.manufacturer || 'N/A'}</Typography>
                            <Typography>Model: {detector?.model || 'N/A'}</Typography>
                            <Typography>Type: {detector?.type || 'N/A'}</Typography>
                            <Typography>
                                Beam Center (px): x: {detector?.beamCenterX_px || 'N/A'},
                                y: {detector?.beamCenterY_px || 'N/A'}
                            </Typography>
                        </AccordionDetails>
                    </Accordion>

                    {/* Beamline Details Accordion */}
                    <Accordion>
                        <AccordionSummary expandIcon={<ExpandMoreIcon/>}>
                            <Typography><strong>Beamline Details</strong></Typography>
                        </AccordionSummary>
                        <AccordionDetails>
                            <Typography>Synchrotron: {beamline_parameters?.synchrotron || 'N/A'}</Typography>
                            <Typography>Ring mode: {beamline_parameters?.ringMode || 'N/A'}</Typography>
                            <Typography>Ring current: {beamline_parameters?.ringCurrent_A || 'N/A'}</Typography>
                            <Typography>Beamline: {beamline_parameters?.beamline || 'N/A'}</Typography>
                            <Typography>Undulator: {beamline_parameters?.undulator || 'N/A'}</Typography>
                            <Typography>Undulator gap: {beamline_parameters?.undulatorgap_mm || 'N/A'}</Typography>
                            <Typography>Focusing optic: {beamline_parameters?.focusingOptic || 'N/A'}</Typography>
                            <Typography>Monochromator: {beamline_parameters?.monochromator || 'N/A'}</Typography>
                        </AccordionDetails>
                    </Accordion>

                    {/* Beam Characteristics Accordion */}
                    <Accordion>
                        <AccordionSummary expandIcon={<ExpandMoreIcon/>}>
                            <Typography><strong>Beam Characteristics</strong></Typography>
                        </AccordionSummary>
                        <AccordionDetails>
                            <Typography>Wavelength: {beamline_parameters?.wavelength || 'N/A'}</Typography>
                            <Typography>Energy: {beamline_parameters?.energy || 'N/A'}</Typography>
                            <Typography>Transmission: {beamline_parameters?.transmission || 'N/A'}</Typography>
                            <Typography>
                                Beam focus (µm): vertical: {beamline_parameters?.beamSizeHeight || 'N/A'},
                                horizontal:{' '}
                                {beamline_parameters?.beamSizeWidth || 'N/A'}
                            </Typography>
                            <Typography>Flux at sample
                                (ph/s): {beamline_parameters?.beamlineFluxAtSample_ph_s || 'N/A'}</Typography>
                        </AccordionDetails>
                    </Accordion>
                </div>

                {/* Image Section */}
                <div style={{width: '900px'}}>
                    <Typography variant="h6" gutterBottom>
                        Associated Images
                    </Typography>
                    {images && images.length > 0 ? (
                        <Grid container spacing={1}>
                            {images.map((img) => (
                                <Grid item xs={4} key={img.id}>
                                    <div
                                        className="image-container"
                                        onClick={() => handleImageClick(`${basePath || ''}${img.filepath}`)}
                                        style={{cursor: 'pointer'}}
                                    >
                                        <img
                                            src={`${basePath || ''}${img.filepath}`}
                                            alt={img.comment || 'Image'}
                                            className="zoom-image"
                                            style={{
                                                width: '100%',
                                                maxWidth: '100%',
                                                borderRadius: '4px',
                                            }}
                                        />
                                    </div>
                                </Grid>
                            ))}
                        </Grid>
                    ) : (
                        <Typography variant="body2" color="textSecondary">
                            No images available.
                        </Typography>
                    )}
                </div>
            </div>

            {/* Processing Results Accordion - Full Width Below */}
            <div style={{width: '100%'}}>
                <Accordion expanded={expandedResults} onChange={(e, expanded) => setExpandedResults(expanded)}>
                    <AccordionSummary expandIcon={<ExpandMoreIcon/>}>
                        <Typography><strong>Processing Results</strong></Typography>
                    </AccordionSummary>
                    <AccordionDetails style={{width: '100%', overflowX: 'auto'}}>
                        {processingResult ? (
                            <div style={{width: '100%'}}>
                                <DataGridPremium<ProcessingResults>
                                    rows={processingResult.map((res, idx) => ({ id: idx, ...res }))}
                                    columns={resultColumns}
                                    autoHeight
                                    hideFooter
                                    columnVisibilityModel={{ id: false }}
                                    disableColumnResize={false}
                                />
                            </div>
                        ) : (
                            <Typography variant="body2" color="textSecondary">Loading results...</Typography>
                        )}
                    </AccordionDetails>
                </Accordion>
            </div>

            {processingResult && processingResult.length > 0 && (
                <div style={{width: 400,  marginTop: '16px' }}>
                    <Typography variant="h6" gutterBottom>CC and CC(1/2) vs Resolution</Typography>
                    <LineChart
                        xAxis={[
                            {
                                data: processingResult[0].cc
                                    .map((point) => point.resolution) // Grab the resolution values
                                    .reverse(), // Reverse the data for resolution
                                label: 'Resolution (Å)',
                                reverse: true, // This ensures the visual flip on the chart, low-res to right and high-res to left
                            },
                        ]}
                        series={[
                            {
                                data: processingResult[0].cc
                                    .map((point) => point.value)
                                    .reverse(), // Reverse the CC values to match the reversed resolution
                                label: 'CC',
                            },
                            {
                                data: processingResult[0].cchalf
                                    .map((point) => point.value)
                                    .reverse(), // Reverse the CC(1/2) values to match the reversed resolution
                                label: 'CC(1/2)',
                            },
                        ]}
                        height={300}
                    />
                </div>
            )}

            {/* Modal for Zoomed Image */}
            <Modal open={modalOpen} onClose={closeModal}>
                <Box
                    style={{
                        position: 'absolute',
                        top: '50%',
                        left: '50%',
                        transform: 'translate(-50%, -50%)',
                        backgroundColor: '#fff',
                        boxShadow: 24,
                        padding: 16,
                        maxHeight: '90%',
                        overflow: 'auto',
                    }}
                >
                    {selectedImage && (
                        <img
                            src={selectedImage}
                            alt="Zoomed"
                            style={{
                                maxWidth: '100%',
                                height: 'auto',
                                borderRadius: '4px',
                            }}
                        />
                    )}
                </Box>
            </Modal>
        </div>
    );
};
export default RunDetails;