import axios from "axios";
import { useEffect, useState } from "react";
import { toast } from "sonner";
import Container from "../Container";

function MyAccount() {
    const [wvList, setWvList] = useState([]);
    const [prList, setPrList] = useState([]);
    const [uploading, setUploading] = useState(false);
    const [username, setUsername] = useState("");
    const [apiKey, setApiKey] = useState("");
    const [password, setPassword] = useState("");
    const [passwordError, setPasswordError] = useState("");
    const [newApiKey, setNewApiKey] = useState("");
    const [apiKeyError, setApiKeyError] = useState("");

    // Fetch user info
    const fetchUserInfo = async () => {
        try {
            const response = await axios.post("/userinfo");
            setWvList(response.data.Widevine_Devices || []);
            setPrList(response.data.Playready_Devices || []);
            setUsername(response.data.Styled_Username || "");
            setApiKey(response.data.API_Key || "");
        } catch (err) {
            toast.error(`Failed to fetch user info. Reason: ${err.message}`);
            console.error("Failed to fetch user info", err);
        }
    };

    useEffect(() => {
        fetchUserInfo();
    }, []);

    useEffect(() => {
        document.title = "My account | CDRM-Project";
    }, []);

    // Handle file upload
    const handleUpload = async (event, cdmType) => {
        const file = event.target.files[0];
        if (!file) return;

        const extension = file.name.split(".").pop();
        if (
            (cdmType === "PR" && extension !== "prd") ||
            (cdmType === "WV" && extension !== "wvd")
        ) {
            toast.error(`Please upload a .${cdmType === "PR" ? "prd" : "wvd"} file.`);
            return;
        }

        const formData = new FormData();
        formData.append("file", file);

        setUploading(true);
        try {
            await axios.post(`/upload/${cdmType}`, formData);
            await fetchUserInfo(); // Refresh list after upload
        } catch (err) {
            toast.error(`Upload failed. Reason: ${err.message}`);
            console.error("Upload failed", err);
        } finally {
            toast.success(`${cdmType} CDM uploaded successfully`);
            setUploading(false);
        }
    };

    // Handle logout
    const handleLogout = async () => {
        try {
            await axios.post("/logout");
            toast.success("Logged out successfully. Reloading page...");
            window.location.reload();
        } catch (error) {
            toast.error(`Logout failed. Reason: ${error.message}`);
            console.error("Logout failed:", error);
        }
    };

    // Handle change password
    const handleChangePassword = async () => {
        if (passwordError || password === "") {
            toast.error("Please enter a valid password");
            return;
        }

        try {
            const response = await axios.post("/user/change_password", {
                new_password: password,
            });

            if (response.data.message === "True") {
                toast.success("Password changed successfully");
                setPassword("");
            } else {
                toast.error("Failed to change password");
            }
        } catch (error) {
            if (error.response && error.response.data?.message === "Invalid password format") {
                toast.error("Password format is invalid. Please try again.");
            } else {
                toast.error("Error occurred while changing password");
            }
        }
    };

    // Handle change API key
    const handleChangeApiKey = async () => {
        if (apiKeyError || newApiKey === "") {
            toast.error("Please enter a valid API key");
            return;
        }

        try {
            const response = await axios.post("/user/change_api_key", {
                new_api_key: newApiKey,
            });
            if (response.data.message === "True") {
                toast.success("API key changed successfully");
                setApiKey(newApiKey);
                setNewApiKey("");
            } else {
                toast.error("Failed to change API key");
            }
        } catch (error) {
            toast.error("Error occurred while changing API key");
            console.error(error);
        }
    };

    return (
        <>
            <Container>
                <div className="flex flex-col gap-4 p-4 lg:flex-row">
                    {/* Left Panel - Account Settings */}
                    <div className="w-full lg:w-96">
                        <div className="card bg-base-200 shadow-xl">
                            <div className="card-body">
                                <p className="text-center text-sm">Username:</p>
                                <h2 className="card-title justify-center text-center font-bold">
                                    {username}
                                </h2>

                                <div className="divider"></div>

                                <fieldset className="fieldset">
                                    <legend className="fieldset-legend text-base" htmlFor="apiKey">
                                        API Key
                                    </legend>
                                    <input
                                        name="apiKey"
                                        type="text"
                                        value={apiKey}
                                        readOnly
                                        className="input input-bordered text-center"
                                    />

                                    <legend
                                        className="fieldset-legend text-base"
                                        htmlFor="newApiKey"
                                    >
                                        New API Key
                                    </legend>
                                    <input
                                        name="newApiKey"
                                        type="text"
                                        value={newApiKey}
                                        onChange={(e) => {
                                            const value = e.target.value;
                                            const isValid = /^[^\s]+$/.test(value);
                                            if (!isValid) {
                                                setApiKeyError("API key must not contain spaces");
                                            } else {
                                                setApiKeyError("");
                                            }
                                            setNewApiKey(value);
                                        }}
                                        placeholder="Enter new API key"
                                        className="input input-bordered"
                                    />
                                    {apiKeyError && (
                                        <p className="label text-error">{apiKeyError}</p>
                                    )}
                                    <button
                                        className="btn btn-primary btn-block mt-2"
                                        onClick={handleChangeApiKey}
                                    >
                                        Change API key
                                    </button>
                                </fieldset>

                                <fieldset className="fieldset">
                                    <legend
                                        className="fieldset-legend text-base"
                                        htmlFor="passwordChange"
                                    >
                                        Change password
                                    </legend>
                                    <input
                                        name="passwordChange"
                                        type="password"
                                        value={password}
                                        onChange={(e) => {
                                            const value = e.target.value;
                                            const isValid =
                                                /^[A-Za-z0-9!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?`~]*$/.test(
                                                    value
                                                );
                                            if (!isValid) {
                                                setPasswordError("Invalid password characters");
                                            } else {
                                                setPasswordError("");
                                            }
                                            setPassword(value);
                                        }}
                                        placeholder="New password"
                                        className="input input-bordered"
                                    />
                                    {passwordError && (
                                        <p className="label text-error">{passwordError}</p>
                                    )}
                                    <button
                                        className="btn btn-secondary btn-block mt-2"
                                        onClick={handleChangePassword}
                                    >
                                        Change password
                                    </button>
                                </fieldset>

                                <div className="divider"></div>

                                <button className="btn btn-error mt-auto" onClick={handleLogout}>
                                    Log out
                                </button>
                            </div>
                        </div>
                    </div>

                    {/* Right Panel - CDM Uploads */}
                    <div className="flex w-full flex-col gap-4">
                        {/* Widevine CDM */}
                        <div className="card bg-base-200 shadow-xl">
                            <div className="card-body">
                                <h2 className="card-title">Widevine CDMs</h2>
                                <div className="divider"></div>
                                <div className="max-h-60 space-y-2 overflow-y-auto">
                                    {wvList.length === 0 ? (
                                        <div className="text-center text-sm">
                                            No Widevine CDMs uploaded.
                                        </div>
                                    ) : (
                                        wvList.map((filename, i) => (
                                            <div
                                                key={i}
                                                className={`rounded px-2 py-1 text-sm ${
                                                    i % 2 === 0 ? "bg-base-100" : "bg-base-300"
                                                }`}
                                            >
                                                {filename}
                                            </div>
                                        ))
                                    )}
                                </div>
                                <label className="btn btn-accent mt-4">
                                    {uploading ? "Uploading..." : "Upload CDM"}
                                    <input
                                        type="file"
                                        accept=".wvd"
                                        hidden
                                        onChange={(e) => handleUpload(e, "WV")}
                                    />
                                </label>
                            </div>
                        </div>

                        {/* PlayReady CDM */}
                        <div className="card bg-base-200 shadow-xl">
                            <div className="card-body">
                                <h2 className="card-title">PlayReady CDMs</h2>
                                <div className="divider"></div>
                                <div className="max-h-60 space-y-2 overflow-y-auto">
                                    {prList.length === 0 ? (
                                        <div className="text-center text-sm">
                                            No PlayReady CDMs uploaded.
                                        </div>
                                    ) : (
                                        prList.map((filename, i) => (
                                            <div
                                                key={i}
                                                className={`rounded px-2 py-1 text-sm ${
                                                    i % 2 === 0 ? "bg-base-100" : "bg-base-300"
                                                }`}
                                            >
                                                {filename}
                                            </div>
                                        ))
                                    )}
                                </div>
                                <label className="btn btn-accent mt-4">
                                    {uploading ? "Uploading..." : "Upload CDM"}
                                    <input
                                        type="file"
                                        accept=".prd"
                                        hidden
                                        onChange={(e) => handleUpload(e, "PR")}
                                    />
                                </label>
                            </div>
                        </div>
                    </div>
                </div>
            </Container>
        </>
    );
}

export default MyAccount;
