"use client"

import { Fragment, useEffect, useRef, useState } from "react";
import Link from "next/link";
import LiveEventTable from "@/components/table/LiveEventTable"
import RemoteCardWidget from "@/components/widget/RemoteCardWidget"

interface ChargerDetail {
    id: string
    charger_id: string
    charger_name: string
    location_name: string
    google_map_url: string
    ws: string
    database: Database
}

interface Database {
    host: string
    port: string
    username: string
    password: string
}

interface ChargerStatus {
    protocol: string;
    active: boolean;
    public: boolean;
    online: boolean;
    status: string;
    vendor: string;
    model: string;
    firmware: string;
    serial_number: string;
    last_heartbeat: string;
    nozzle: Nozzle[];
    live_event: LiveEvent[];
}

interface Nozzle {
    id: string
    name: string
    status: string
    error_code: string
    power_kw: string
    power_type: string
    transaction: Transaction
}

interface Transaction {
    email: string
    estimate_cost: string
    soc: string
}

interface LiveEvent {
    id: string
    direction: string
    action: string
    payload: unknown
    latency: string
    crated_at: string
}

interface ChargerStatusWidgetProps { 
    token: string; 
}

export default function ChargerStatusWidget({
    token
}:ChargerStatusWidgetProps) {
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState<string | null>(null);
    const [chargeDetail, setChargeDetail] = useState<ChargerDetail | null>(null);
    const [chargerStatus, setChargerStatus] = useState<ChargerStatus | null>(null);
    const socketRef = useRef<WebSocket | null>(null);

    useEffect(() => {
        if (!token) { 
            setLoading(false); 
            setError("Token is required"); 
            return; 
        }

        const loadChargerDetail = async () => {
            try {
                setLoading(true);
                setError(null);

                const fd = new FormData();
                const tokenx = decodeURIComponent(token);
                fd.append("token", tokenx);
                const response = await fetch("/api/monitoring/charger/detail",
                    {
                        method: "POST",
                        body: fd,
                    }
                );

                if (!response.ok) {
                    throw new Error(`Failed to fetch charger monitoring (${response.status})`);
                }

                const result = await response.json();
                if (!result?.data) { 
                    throw new Error("Charger detail data not found"); 
                }
                setChargeDetail(result.data);
                // tiers.forEach((tier) => {
                //     if (!tier.server || !tier.server.host || !tier.server.port) {
                //         return;
                //     }

                connectWebSocket(result.data);
                // });
            } catch (err) {
                console.log("Failed to load server infrastructure:", err);

                setError(err instanceof Error ? err.message : "Failed to load server infrastructure");
            } finally {
                setLoading(false);
            }
        };

        loadChargerDetail();
        return () => {
            if (socketRef.current) {
                socketRef.current.close();
                socketRef.current = null;
            }
        };
    }, [token])

    const connectWebSocket = (charger: ChargerDetail) => {
        // Tutup connection lama kalau ada
        if (socketRef.current) {
            socketRef.current.close();
            socketRef.current = null;
        }

        if (!charger.ws) {
            console.log("[WS] WebSocket URL is empty");
            setError("WebSocket URL is not configured");
            return;
        }

        console.log("[WS] Connecting:", charger.ws);

        const socket = new WebSocket(charger.ws);

        socketRef.current = socket;

        socket.onopen = () => {
            console.log("[WS] Connected:", charger.ws);

            const payload = {
                action: "subscribe",
                topic: "ev_charger",
                data: {
                    host: charger.database.host,
                    port: Number(charger.database.port),
                    username: charger.database.username,
                    password: charger.database.password,
                    charger_id: charger.id,
                },
            };

            console.log("[WS] Subscribe:", {
                ...payload,
                data: {
                    ...payload.data,
                    password: "******",
                },
            });

            socket.send(JSON.stringify(payload));
        };

        socket.onmessage = (event) => {
            try {
                const message = JSON.parse(event.data);

                console.log("[WS] Message:", message);

                if (message.topic !== "ev_charger") {
                    return;
                }

                if (!message.data) {
                    return;
                }

                const status: ChargerStatus = message.data;

                setChargerStatus(status);
            } catch (err) {
                console.log("[WS] Invalid message:", event.data, err);
            }
        };

        socket.onerror = (event) => {
            console.log("[WS] Error:", event);
            setChargerStatus((prev) => ({
                ...(prev ?? {
                    protocol: "",
                    active: false,
                    public: false,
                    online: false,
                    status: "Offline",
                    vendor: "",
                    model: "",
                    firmware: "",
                    serial_number: "",
                    last_heartbeat: "",
                    nozzle: [],
                    live_event: [],
                }),
                online: false,
                status: "Offline",
            }));
        };

        socket.onclose = (event) => {
            console.log(
                "[WS] Closed:",
                event.code,
                event.reason
            );

            setChargerStatus((prev) => {
                if (!prev) {
                    return null;
                }

                return {
                    ...prev,
                    online: false,
                    status: "Offline",
                };
            });

            if (socketRef.current === socket) {
                socketRef.current = null;
            }
        };
    };

    const getStatusCharger = (health?: string) => {
        switch (health?.toLowerCase()) {
            case "available":
                return ""
            default:
                return "charging";
        }
    };

    const getStatusNozzle = (health?: string) => {
        switch (health?.toLowerCase()) {
            case "available":
                return "bg-green-lt"
            case "preparing":
                return "bg-blue-lt"
            case "charging":
                return "bg-cyan-lt"
            case "suspended_ev":
                return "bg-yellow-lt"
            case "suspended_evse":
                return "bg-orange-lt"
            case "finishing":
                return "bg-indigo-lt"
            case "reserved":
                return "bg-purple-lt"
            case "unavailable":
                return "bg-dark-lt"
            case "faulted":
                return "bg-red-lt"
        }
    };

    const getOnlineCharger = (status?: boolean) => {
        switch (status) {
            case true:
                return "bg-success-lt"
            default:
                return "bg-danger-lt";
        }
    };

    const getOnlineChargerTxt = (status?: boolean) => {
        switch (status) {
            case true:
                return "Active"
            default:
                return "Non Active";
        }
    };
    const getPublicChargerTxt = (status?: boolean) => {
        switch (status) {
            case true:
                return "Public"
            default:
                return "Private";
        }
    };
    if (loading) { 
        return ( 
        <div className="card"> 
            <div className="card-body text-center py-5"> 
                <div className="spinner-border text-primary mb-3" /> 
                    <div className="text-secondary"> Loading charger detail... 
                </div> 
            </div> 
        </div> 
    )}
    if (error) { 
        return ( 
        <div className="alert alert-danger"> 
            <div className="d-flex"> 
                <div> 
                    <i className="ti ti-alert-circle me-2" /> 
                </div> 
                <div> 
                    <h4 className="alert-title"> Failed to load charger </h4> 
                    <div className="text-secondary"> {error} </div> 
                </div> 
            </div> 
        </div> 
    )}
    if (!chargeDetail) { 
        return ( 
        <div className="alert alert-warning"> Charger detail not found. </div> 
    )}
    return (
        <Fragment>
            <div className="row align-items-center">
                <div className="col-auto">
                    <span className="avatar avatar-lg bg-primary-lt">
                        <i className="ti ti-server-2"></i>
                    </span>
                </div>
                <div className="col">
                    <div className="h3 mb-1">Charger : {chargeDetail?.charger_id} - {chargeDetail.charger_name}</div>
                    <div>
                        <span className="text-secondary small">
                            Location : {chargeDetail?.location_name}
                            [<i><Link href={chargeDetail?.google_map_url} target="_blank" rel="noopener noreferrer">See on Google Maps</Link></i>]
                        </span>
                    </div>
                </div>
            </div>
            <div className="col-md-6 col-xl-4">
                <div className="d-flex justify-content-center align-items-center pt-3">
                    <div className="car-1-connector"></div>
                    <img src="/static/image/charge-station.svg" width="50%" alt="Server"/>
                </div>
                {chargerStatus?.live_event && chargerStatus.live_event.length > 0 && (
                    <RemoteCardWidget chargepoint_id={chargeDetail?.charger_id} token={token} />
                )}
            </div>
            <div className="col-md-6 col-xl-8">
                <div className="card">
                    <div className="card-body">
                        <div className="row align-items-center">
                            <div className="col">
                                <div className="row align-items-center">
                                    <div className="col-auto">
                                        <span className="avatar avatar-lg bg-primary-lt">
                                            <i className="ti ti-activity"></i>
                                        </span>
                                    </div>
                                    <div className="col">
                                        <div className="text-secondary">Active EV Charger</div>
                                        <div className="mt-1">
                                            <span className={`badge ${getOnlineCharger(chargerStatus?.online)} me-1 mb-1`}>
                                                {getOnlineChargerTxt(chargerStatus?.online)}
                                            </span>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div className="col">
                                <div className="row align-items-center">
                                    <div className="col-auto">
                                        <span className="avatar avatar-lg bg-primary-lt">
                                            <i className="ti ti-battery-vertical-charging"></i>
                                        </span>
                                    </div>
                                    <div className="col">
                                        <div className="text-secondary">Public EV Charger</div>
                                        <div className="mt-1">
                                            <span className={`badge ${getOnlineCharger(chargerStatus?.online)} me-1 mb-1`}>
                                                {getPublicChargerTxt(chargerStatus?.online)}
                                            </span>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div className="col">
                                <div className="row align-items-center">
                                    <div className="col-auto">
                                        <span className="avatar avatar-lg bg-primary-lt">
                                            <i className="ti ti-http-connect"></i>
                                        </span>
                                    </div>
                                    <div className="col">
                                        <div className="text-secondary">Online EV Charger</div>
                                        <div className="mt-1">
                                            <span className={`badge ${getOnlineCharger(chargerStatus?.online)} me-1 mb-1`}>
                                                {getOnlineChargerTxt(chargerStatus?.online)}
                                            </span>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div className="card mt-3">
                    <div className="card-body">
                        <div className="row align-items-center">
                            <div className="col-auto">
                                <span className="avatar avatar-lg bg-success-lt">
                                    <i className="ti ti-settings"></i>
                                </span>
                            </div>
                            <div className="col">
                                <div className="row">
                                    <div className="col-md-6 col-xl-4">
                                        <h3>{chargerStatus?.protocol || '...'}</h3>
                                        <h5>Protocol OCPP</h5>
                                    </div>
                                    <div className="col-md-6 col-xl-4">
                                        <h3>{chargerStatus?.firmware || '...'}</h3>
                                        <h5>Firmware Version</h5>
                                    </div>
                                    <div className="col-md-6 col-xl-4">
                                        <h3>{chargerStatus?.serial_number || '...'}</h3>
                                        <h5>Serial Number</h5>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div className="row align-items-center mt-3">
                            <div className="col-auto">
                                <span className="avatar avatar-lg bg-success-lt">
                                    <i className="ti ti-settings"></i>
                                </span>
                            </div>
                            <div className="col">
                                <div className="row">
                                    <div className="col-md-6 col-xl-4">
                                        <h3>{chargerStatus?.vendor || '...'}</h3>
                                        <h5>Vendor EV Charger</h5>
                                    </div>
                                    <div className="col-md-6 col-xl-4">
                                        <h3>{chargerStatus?.model || '...'}</h3>
                                        <h5>Model EV Charger</h5>
                                    </div>
                                    <div className="col-md-6 col-xl-4">
                                        <h3>{chargerStatus?.last_heartbeat || '...'}</h3>
                                        <h5>Last Heartbeat</h5>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div className="row row-cards mt-1">
                    {chargerStatus?.nozzle?.map((nozzle, index) => (
                        <div key={nozzle.id ?? index} className={chargerStatus.nozzle.length === 1 ? "col-md-12 col-xl-12" : "col-md-6 col-xl-6"}>
                            <div className="card">
                                <div className="card-header">
                                    <h3 className="card-title">
                                        <i className="ti ti-plug-connected"></i> Nozzle {index+1}
                                    </h3>
                                </div>
                                <div className="card-body">
                                    <table className="table table-sm table-borderless">
                                        <tbody>
                                            <tr>
                                                <td>Name</td>
                                                <td>: {nozzle.name}</td>
                                            </tr>
                                            <tr>
                                                <td>Status</td>
                                                <td>: 
                                                    <span className={`badge ${getStatusNozzle(nozzle.status)}`}>{nozzle.status}</span>
                                                    </td>
                                            </tr>
                                            <tr>
                                                <td>Error Code</td>
                                                <td>: {nozzle.error_code}</td>
                                            </tr>
                                            <tr>
                                                <td>Power</td>
                                                <td>: {nozzle.power_kw} kW</td>
                                            </tr>
                                            <tr>
                                                <td>Power Type</td>
                                                <td>: {nozzle.power_type}</td>
                                            </tr>
                                            <tr>
                                                <td>Transaction</td>
                                                <td>: {nozzle.transaction.email} - {nozzle.transaction.estimate_cost}</td>
                                            </tr>
                                        </tbody>
                                    </table>
                                </div>
                            </div>
                        </div>
                    ))}
                </div>
                {chargerStatus?.live_event &&
                chargerStatus.live_event.length > 0 && (
                    <LiveEventTable live_event={chargerStatus.live_event} />
                )}
            </div>
        </Fragment>
    )
}