import { useState, useEffect, useMemo } from 'react';
import { useNavigate } from 'react-router-dom';
import Header from './Header';
import useSerialData from '../hooks/useSerialData';
import { useNomenclatures } from '../contexts/NomenclatureContext';
import { useNomenclatureData } from '../contexts/NomenclatureDataContext';
import NomenclatureDropdown from './NomenclatureUI/NomenclatureDropdown';
import ReportPreviewModal from './ReportPreviewModal';
import api from '../services/api';
import './Main.css';

export default function Main() {
    const navigate = useNavigate();
    const { readings, isConnected } = useSerialData();
    const { vehicles } = useNomenclatures();

    const [selectedVehicleId, setSelectedVehicleId] = useState(null);
    const [searchQuery, setSearchQuery] = useState('');
    const [showNewForm, setShowNewForm] = useState(false);
    const [newForm, setNewForm] = useState({ vehicle_number: '', trailer1_number: '', trailer2_number: '', driver_pid: '' });
    const [newExtraData, setNewExtraData] = useState({});
    const [error, setError] = useState('');
    const [isSaving, setIsSaving] = useState(false);
    const [showNoticeReport, setShowNoticeReport] = useState(false);

    // Nomenclature data from context
    const { definitions, entries } = useNomenclatureData();
    const vehicleNomenclatures = useMemo(
        () => Object.values(definitions)
            .filter(d => d.applies_to === 'vehicle')
            .sort((a, b) => (a.sort_order || 0) - (b.sort_order || 0)),
        [definitions]
    );
    const [extraData, setExtraData] = useState({});

    // Current reading from COM port
    // Data format: "Value: 36106.04" or just "36106.04"
    const currentReading = readings.length > 0 ? readings[0].data : null;
    const currentWeight = useMemo(() => {
        if (!currentReading) return null;
        // Extract numeric value - handle "Value: 123.45" or just "123.45"
        const match = currentReading.match(/[\d.]+/);
        if (match) {
            const val = parseFloat(match[0]);
            return isNaN(val) ? null : Math.round(val);
        }
        return null;
    }, [currentReading]);

    // Selected vehicle object (refreshes when vehicles list updates via SSE)
    const selectedVehicle = useMemo(
        () => vehicles.find(v => v.id === selectedVehicleId) || null,
        [vehicles, selectedVehicleId]
    );

    // Filtered vehicles
    const filteredVehicles = useMemo(() => {
        if (!searchQuery.trim()) return vehicles;
        const q = searchQuery.toLowerCase();
        return vehicles.filter(v => v.vehicle_number.toLowerCase().includes(q));
    }, [vehicles, searchQuery]);

    // When vehicle selection changes, load its extra data
    useEffect(() => {
        if (selectedVehicle?.extra?.data) {
            setExtraData({ ...selectedVehicle.extra.data });
        } else {
            setExtraData({});
        }
    }, [selectedVehicle]);

    // Open new vehicle form
    const handleNewVehicle = () => {
        setSelectedVehicleId(null);
        setShowNewForm(true);
        setNewForm({ vehicle_number: '', trailer1_number: '', trailer2_number: '', driver_pid: '' });
        setNewExtraData({});
        setError('');
    };

    // Cancel new vehicle form
    const handleCancelNew = () => {
        setShowNewForm(false);
        setNewForm({ vehicle_number: '', trailer1_number: '', trailer2_number: '', driver_pid: '' });
        setNewExtraData({});
        setError('');
    };

    // Create new vehicle
    const handleCreateVehicle = async () => {
        if (!newForm.vehicle_number.trim()) return;
        setIsSaving(true);
        setError('');
        try {
            const payload = {
                vehicle_number: newForm.vehicle_number.trim(),
                trailer1_number: newForm.trailer1_number.trim() || null,
                trailer2_number: newForm.trailer2_number.trim() || null,
                driver_pid: newForm.driver_pid.trim() || null,
            };
            // Include extra data if any values set
            const hasExtra = Object.values(newExtraData).some(v => v !== undefined && v !== null && v !== '');
            if (hasExtra) {
                payload.extra = { data: newExtraData };
            }
            const res = await api.post('/api/vehicles/', payload);
            setSelectedVehicleId(res.data.id);
            setShowNewForm(false);
            setNewForm({ vehicle_number: '', trailer1_number: '', trailer2_number: '', driver_pid: '' });
            setNewExtraData({});
        } catch (err) {
            const data = err.response?.data;
            const msg = data?.vehicle_number?.[0] || data?.detail || (typeof data === 'string' ? data : JSON.stringify(data)) || 'Failed to create vehicle';
            setError(msg);
        } finally {
            setIsSaving(false);
        }
    };

    // Set tare
    const handleSetTare = async () => {
        if (!selectedVehicle || currentWeight === null || isNaN(currentWeight)) return;
        setError('');
        try {
            await api.post(`/api/vehicles/${selectedVehicle.id}/set-tare/`, { value: currentWeight });
        } catch {
            setError('Failed to set tare');
        }
    };

    // Set gross
    const handleSetGross = async () => {
        if (!selectedVehicle || currentWeight === null || isNaN(currentWeight)) return;
        setError('');
        try {
            await api.post(`/api/vehicles/${selectedVehicle.id}/set-gross/`, { value: currentWeight });
        } catch {
            setError('Failed to set gross');
        }
    };

    // Save extra data
    const handleSaveExtra = async () => {
        if (!selectedVehicle) return;
        setIsSaving(true);
        setError('');
        try {
            await api.patch(`/api/vehicles/${selectedVehicle.id}/`, {
                extra: { data: extraData },
            });
        } catch (err) {
            const data = err.response?.data;
            setError(typeof data === 'string' ? data : JSON.stringify(data) || 'Failed to save');
        } finally {
            setIsSaving(false);
        }
    };

    // Format date
    const formatDate = (dateStr) => {
        if (!dateStr) return '';
        const d = new Date(dateStr);
        return d.toLocaleDateString() + ' ' + d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
    };

    // Net weight
    const netWeight = (selectedVehicle?.tare != null && selectedVehicle?.gross != null)
        ? selectedVehicle.gross - selectedVehicle.tare
        : null;

    // Vehicle data shaped for report preview/design
    // Transforms extra.data keys from raw codes/ids to { [nomenclature name]: display value }
    const vehicleReportData = useMemo(() => {
        if (!selectedVehicle) return null;
        const rawExtra = selectedVehicle.extra?.data || {};
        const extra = {};
        for (const [code, value] of Object.entries(rawExtra)) {
            const def = definitions[code];
            if (!def) continue;
            if (def.kind === 'lookup') {
                const entry = (entries[code] || []).find(e => e.id === value);
                extra[def.name] = entry?.display_value ?? '';
            } else {
                extra[def.name] = value ?? '';
            }
        }
        return {
            vehicle: {
                ...selectedVehicle,
                net: netWeight,
                extra,
            }
        };
    }, [selectedVehicle, netWeight, definitions, entries]);

    return (
        <div>
            <Header />
            <div className="main">
                {/* Left panel - Vehicle list */}
                <div className="main-left">
                    <div className="vehicle-list-header">
                        <button
                            className="vehicle-add-btn"
                            onClick={handleNewVehicle}
                        >
                            + New Vehicle
                        </button>
                        <input
                            className="vehicle-search"
                            type="text"
                            placeholder="Search..."
                            value={searchQuery}
                            onChange={e => setSearchQuery(e.target.value)}
                        />
                    </div>

                    <div className="vehicle-list">
                        {filteredVehicles.map(v => (
                            <div
                                key={v.id}
                                className={`vehicle-list-item ${selectedVehicleId === v.id ? 'vehicle-list-item--active' : ''}`}
                                onClick={() => { setSelectedVehicleId(v.id); setShowNewForm(false); setError(''); }}
                            >
                                <span className="vehicle-list-number">{v.vehicle_number}</span>
                                {v.tare != null && (
                                    <span className="vehicle-list-weight">{v.tare} kg</span>
                                )}
                            </div>
                        ))}
                        {filteredVehicles.length === 0 && (
                            <div className="vehicle-list-empty">No vehicles found</div>
                        )}
                    </div>
                </div>

                {/* Right panel - Vehicle detail or New form */}
                <div className="main-right">
                    {showNewForm ? (
                        <div className="vehicle-detail">
                            {error && <div className="vehicle-error">{error}</div>}

                            <h2 className="vehicle-detail-title">New Vehicle</h2>

                            <div className="vehicle-form-section">
                                <div className="extra-fields">
                                    <div className="extra-field">
                                        <label>Vehicle Number *</label>
                                        <input
                                            type="text"
                                            value={newForm.vehicle_number}
                                            onChange={e => setNewForm(prev => ({ ...prev, vehicle_number: e.target.value }))}
                                            disabled={isSaving}
                                            autoFocus
                                        />
                                    </div>
                                    <div className="extra-field">
                                        <label>Trailer 1</label>
                                        <input
                                            type="text"
                                            value={newForm.trailer1_number}
                                            onChange={e => setNewForm(prev => ({ ...prev, trailer1_number: e.target.value }))}
                                            disabled={isSaving}
                                        />
                                    </div>
                                    <div className="extra-field">
                                        <label>Trailer 2</label>
                                        <input
                                            type="text"
                                            value={newForm.trailer2_number}
                                            onChange={e => setNewForm(prev => ({ ...prev, trailer2_number: e.target.value }))}
                                            disabled={isSaving}
                                        />
                                    </div>
                                    <div className="extra-field">
                                        <label>Driver PID</label>
                                        <input
                                            type="text"
                                            value={newForm.driver_pid}
                                            onChange={e => setNewForm(prev => ({ ...prev, driver_pid: e.target.value }))}
                                            disabled={isSaving}
                                        />
                                    </div>
                                </div>
                            </div>

                            {vehicleNomenclatures.length > 0 && (
                                <div className="extra-section">
                                    <h3>Additional Data</h3>
                                    <div className="extra-fields">
                                        {vehicleNomenclatures.map(nom => (
                                            <div key={nom.code} className="extra-field">
                                                <NomenclatureDropdown
                                                    nomenclatureCode={nom.code}
                                                    value={newExtraData[nom.code]}
                                                    onChange={val => setNewExtraData(prev => ({
                                                        ...prev,
                                                        [nom.code]: val,
                                                    }))}
                                                    disabled={isSaving}
                                                />
                                            </div>
                                        ))}
                                    </div>
                                </div>
                            )}

                            <div className="vehicle-form-actions">
                                <button
                                    className="vehicle-form-cancel"
                                    onClick={handleCancelNew}
                                    disabled={isSaving}
                                >
                                    Cancel
                                </button>
                                <button
                                    className="extra-save-btn"
                                    onClick={handleCreateVehicle}
                                    disabled={isSaving || !newForm.vehicle_number.trim()}
                                >
                                    {isSaving ? 'Creating...' : 'Create Vehicle'}
                                </button>
                            </div>
                        </div>
                    ) : !selectedVehicle ? (
                        <div className="main-placeholder">
                            Select a vehicle or create a new one
                        </div>
                    ) : (
                        <div className="vehicle-detail">
                            {error && <div className="vehicle-error">{error}</div>}

                            <h2 className="vehicle-detail-title">{selectedVehicle.vehicle_number}</h2>

                            {/* Current reading */}
                            <div className="reading-display">
                                <label>Current Reading</label>
                                <div className={`reading-value ${isConnected ? '' : 'reading-value--disconnected'}`}>
                                    {currentWeight !== null && !isNaN(currentWeight)
                                        ? `${currentWeight} kg`
                                        : (isConnected ? 'Waiting...' : 'Disconnected')
                                    }
                                </div>
                            </div>

                            {/* Weighing section */}
                            <div className="weighing-section">
                                {/* Tare */}
                                <div className="weight-card">
                                    <div className="weight-card-header">Tare</div>
                                    <div className="weight-card-value">
                                        {selectedVehicle.tare != null ? `${selectedVehicle.tare} kg` : '---'}
                                    </div>
                                    {selectedVehicle.tare_date && (
                                        <div className="weight-card-meta">
                                            {formatDate(selectedVehicle.tare_date)}
                                            {selectedVehicle.tare_user_name && ` (${selectedVehicle.tare_user_name})`}
                                        </div>
                                    )}
                                    <button
                                        className="weight-set-btn"
                                        onClick={handleSetTare}
                                        disabled={currentWeight === null || isNaN(currentWeight) || selectedVehicle?.tare != null}
                                    >
                                        Set Tare
                                    </button>
                                </div>

                                {/* Gross */}
                                <div className="weight-card">
                                    <div className="weight-card-header">Gross</div>
                                    <div className="weight-card-value">
                                        {selectedVehicle.gross != null ? `${selectedVehicle.gross} kg` : '---'}
                                    </div>
                                    {selectedVehicle.gross_date && (
                                        <div className="weight-card-meta">
                                            {formatDate(selectedVehicle.gross_date)}
                                            {selectedVehicle.gross_user_name && ` (${selectedVehicle.gross_user_name})`}
                                        </div>
                                    )}
                                    <button
                                        className="weight-set-btn"
                                        onClick={handleSetGross}
                                        disabled={currentWeight === null || isNaN(currentWeight) || selectedVehicle?.gross != null}
                                    >
                                        Set Gross
                                    </button>
                                </div>

                                {/* Net */}
                                {netWeight !== null && (
                                    <div className="weight-card weight-card--net">
                                        <div className="weight-card-header">Net</div>
                                        <div className="weight-card-value">{netWeight} kg</div>
                                        <button
                                            className="weight-set-btn"
                                            onClick={() => setShowNoticeReport(true)}
                                        >
                                            Print Notice
                                        </button>
                                        <button
                                            className="weight-set-btn"
                                            onClick={() => navigate('/report-editor', {
                                                state: {
                                                    reportName: 'notice_report',
                                                    vehicleData: vehicleReportData,
                                                }
                                            })}
                                        >
                                            Design Notice
                                        </button>
                                    </div>
                                )}
                            </div>

                            {/* Extra fields from nomenclatures */}
                            {vehicleNomenclatures.length > 0 && (
                                <div className="extra-section">
                                    <h3>Additional Data</h3>
                                    <div className="extra-fields">
                                        {vehicleNomenclatures.map(nom => (
                                            <div key={nom.code} className="extra-field">
                                                <NomenclatureDropdown
                                                    nomenclatureCode={nom.code}
                                                    value={extraData[nom.code]}
                                                    onChange={val => setExtraData(prev => ({
                                                        ...prev,
                                                        [nom.code]: val,
                                                    }))}
                                                />
                                            </div>
                                        ))}
                                    </div>
                                    <button
                                        className="extra-save-btn"
                                        onClick={handleSaveExtra}
                                        disabled={isSaving}
                                    >
                                        {isSaving ? 'Saving...' : 'Save Extra Data'}
                                    </button>
                                </div>
                            )}
                        </div>
                    )}
                </div>
            </div>
            {showNoticeReport && vehicleReportData && (
                <ReportPreviewModal
                    vehicleData={vehicleReportData}
                    onClose={() => setShowNoticeReport(false)}
                />
            )}
        </div>
    );
}
