import API_URL from "../../../../config/api";
import { useEffect, useState } from "react";
import { Link, useParams } from "react-router";
import { CgSpinner } from "react-icons/cg";
import type { ApiErrorResponse, Workshop } from "../../../../types";
import { LuArrowLeft, LuCalendar, LuCheck, LuClock3, LuPencil, LuTrash2, LuUpload, LuUsers, LuX} from "react-icons/lu";
import { pt } from "date-fns/locale";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import Swal from "sweetalert2";
import styles from "./styles.module.css";
import { imageSkeletonFadeStyle, onImageSkeletonLoad } from "../../../../utils/imageSkeleton";
import { motion } from "framer-motion";
import { slideFromLeftVariants, slideFromLeftOnMountTransition, slideFromLeftTransition, slideFromRightVariants, slideFromRightTransition, slideFromTopTransition, slideFromTopVariants } from "../../../../utils/pageMotionVariants";

export default function Workshop() {
    const { id } = useParams();
    const [loading, setLoading] = useState(true);
    const [workshop, setWorkshop] = useState<Workshop | null>(null);
    const [error, setError] = useState<ApiErrorResponse | null>(null);
    const [formEdit, setFormEdit] = useState<boolean>(false);
    const [title, setTitle] = useState<string>("");
    const [description, setDescription] = useState<string>("");
    const [image, setImage] = useState<File | null>(null);
    const [date, setDate] = useState<Date | null>(null);
    const [time_start, setTimeStart] = useState<Date | null>(null);
    const [time_end, setTimeEnd] = useState<Date | null>(null);
    const [status, setStatus] = useState<string>("");
    const [listagemInscritos, setListagemInscritos] = useState<boolean>(false);
    const [role, setRole] = useState<number>(0);

    /* Para enviar a data no formato que o backend espera */
    function formatDateToYmd(value: Date): string {
        const year = value.getFullYear();
        const month = String(value.getMonth() + 1).padStart(2, "0");
        const day = String(value.getDate()).padStart(2, "0");
        return `${year}-${month}-${day}`;
    }

    function formatTimeToHm(value: Date): string {
        const hours = String(value.getHours()).padStart(2, "0");
        const minutes = String(value.getMinutes()).padStart(2, "0");
        return `${hours}:${minutes}`;
    }

    useEffect(() => {
        getWorkshop();
    }, [id]);

    async function getWorkshop() {
        setLoading(true);
        try {
            const response = await fetch(`${API_URL}/api/edit-workshop/${id}`, {
                method: "GET",
                headers: {
                    Accept: "application/json",
                    "Content-Type": "application/json",
                    Authorization: `Bearer ${localStorage.getItem("token")}`
                },
            });

            const data = await response.json();

            if (response.ok) {
                setWorkshop(data.data);
                setStatus(data.data.status);
                setRole(data.role);
                setLoading(false);
            } else {
                setWorkshop(null);
                setError(data as ApiErrorResponse);
                setLoading(false);
            }

        } catch {
            console.error(error);
        } finally {
            setLoading(false);
        }
    }

    async function update(event?: React.FormEvent<HTMLFormElement>, overrides?: { status?: string }) {
        event?.preventDefault();

        if (!workshop) return;

        const formData = new FormData();
        formData.append("title", title || workshop.title);
        formData.append("description", description || workshop.description);
        formData.append("date", date ? formatDateToYmd(date) : workshop.date);
        formData.append("time_start", time_start ? formatTimeToHm(time_start) : workshop.time_start.slice(0, 5));
        formData.append("time_end", time_end ? formatTimeToHm(time_end) : workshop.time_end.slice(0, 5));
        formData.append("status", overrides?.status || status || workshop.status);

        if (image) {
            formData.append("image", image);
        }

        const response = await fetch(`${API_URL}/api/edit-workshop/${id}`, {
            method: "POST",
            headers: {
                Accept: "application/json",
                Authorization: `Bearer ${localStorage.getItem("token")}`
            },
            body: formData,
        });

        const data = await response.json();

        if (response.ok) {
            Swal.fire({
                title: data.message as string,
                icon: 'success',
                showConfirmButton: false,
                showCloseButton: true,
            });
            if (overrides?.status === "canceled") {
                Swal.fire({
                    title: "Workshop cancelado com sucesso",
                    icon: 'error',
                    showConfirmButton: false,
                    showCloseButton: true,
                });
            }
            getWorkshop();
            setFormEdit(false);
        } else {
            Swal.fire({
                title: data.message as string,
                icon: 'error',
                showConfirmButton: false,
                showCloseButton: false,
            });
        }
    }

    function handleCancelWorkshop() {
        Swal.fire({
            text: 'Tem a certeza que deseja cancelar este workshop?',
            showCancelButton: true,
            confirmButtonText: 'Sim, cancelar',
            confirmButtonColor: 'var(--primary-color)',
            cancelButtonText: 'Cancelar',
        }).then((result) => {
            if (result.isConfirmed) {
                update(undefined, { status: "canceled" })
            }
        });
    }

    /* async function destroy(id: number) {
        const response = await fetch(`${API_URL}/api/workshop/${id}`, {
            method: "DELETE",
            headers: {
                Accept: "application/json",
                "Content-Type": "application/json",
                Authorization: `Bearer ${localStorage.getItem("token")}`
            },
        });

        const data = await response.json();

        if (response.ok) {
            setMessageDeleteWorkshop(data.message as string);
            setError(null);
            getWorkshop();
        } else {
            setMessageDeleteWorkshop("");
            setError(data as ApiErrorResponse);
        }
    }

    function handleDeleteWorkshop() {
        Swal.fire({
            text: 'Tem a certeza que deseja cancelar este workshop?',
            showCancelButton: true,
            confirmButtonText: 'Sim, apagar',
            confirmButtonColor: 'var(--primary-color)',
            cancelButtonText: 'Cancelar',
        }).then((result) => {
            if (result.isConfirmed) {
                destroy(workshop?.id as number);
            }
        });
    } */

    if (loading) {
        return (
            <div className="text-center mt-5 d-flex flex-column gap-2 align-items-center">
                <CgSpinner className={`${styles.animateSpin} text-2xl fs-3`} />
            </div>
        )
    }

    return (
        <div className={`${styles.container} p-3 p-xl-0`}>
            <motion.div variants={slideFromLeftVariants} initial="initial" animate="animate" transition={slideFromLeftOnMountTransition} className={"text-start mb-3"}>
                <button className={`${styles.button} border-0 bg-transparent fs-5`}>
                    <Link className={`${styles.link} text-decoration-none`} to="/workshops">
                        <LuArrowLeft className={`${styles.LinkIcon} mb-1 fs-4 align-items-center`} /> <span className={styles.linkText}>Workshops</span>
                    </Link>
                </button>
            </motion.div>

            {workshop ? (
                <>
                    <div className={`${styles.container} d-flex flex-column gap-2`}>
                        <div className="row mt-4 g-3 gx-md-4 gx-lg-5 ms-0">
                            <motion.div variants={slideFromLeftVariants} initial="initial" animate="animate" transition={slideFromLeftTransition} className={`${styles.thumbnailWrapper} col-12 col-lg-3 align-self-center align-self-sm-center px-0 mt-0`}>
                                <img
                                    src={`${API_URL}/storage/${workshop.image}`}
                                    alt={workshop.title}
                                    className={`${styles.thumbnail} w-100`}
                                    style={imageSkeletonFadeStyle}
                                    onLoad={onImageSkeletonLoad}
                                />
                            </motion.div>
                            <motion.div variants={slideFromRightVariants} initial="initial" animate="animate" transition={slideFromRightTransition} className="col-12 col-lg-9 d-flex flex-column justify-content-between gap-2">
                                <div className="d-flex flex-column flex-wrap  gap-1 justify-content-center justify-content-md-start">
                                    {role === 1 ? (
                                        <span className={`${styles.statusWorkshop} text-center d-inline-block py-1 mb-1 mb-sm-0 ${workshop.status === "pending" ? "alert alert-primary" : workshop.status === "realized" ? "alert alert-success" : "alert alert-danger"}`} style={{ width: "fit-content" }}>
                                            <span className="fw-bold">{workshop.status === "pending" ? (<><LuClock3 className="mb-1" /> Agendado</>) : workshop.status === "realized" ? (<><LuCheck className="mb-1" /> Realizado</>) : (<><LuX className="mb-1" /> Cancelado</>)}</span>
                                        </span>
                                    ) : null}

                                    <h2 className={`${styles.title} text-start d-inline-block`}>{workshop.title}</h2>
                                    <p className={`${styles.description} text-start`}>{workshop.description}</p>
                                </div>

                            <div className="col-12 px-0">
                                <div className="d-flex flex-wrap gap-3 text-start gap-1 mt-2">
                                    <div className={`${styles.dateWorkshop} text-start align-content-center d-inline-block px-3 py-2`}>
                                        <small className="d-block text-muted me-2"><LuCalendar className={`${styles.iconCalendar} mb-1 me-2`} /> Dia</small>
                                        {workshop.date.split("-").reverse().join("-")}
                                    </div>

                                    <div className={`${styles.timeWorkshop} text-start align-content-center d-inline-block px-3 py-2`}>
                                        <small className="d-block text-muted me-2"><LuClock3 className={`${styles.iconClock} mb-1 me-2`} /> Hora</small>
                                        {workshop.time_start.slice(0, 5).split(":").join("h")} - {workshop.time_end.slice(0, 5).split(":").join("h")}
                                    </div>

                                    {role === 1 && workshop.users.length === 0 ? (
                                        <div className={`${styles.timeWorkshop} text-start align-content-center d-inline-block px-3 py-2`}>
                                            <small className="d-block text-muted me-2"><LuUsers className={`${styles.iconClock} mb-1 me-2`} /> Inscritos</small>
                                            <span className={`${styles.contagemUtilizadoresInscritos} fs-6`}>0 utilizadores</span>
                                        </div>
                                    ) : role === 1 && workshop.users.length > 0 ? (
                                        <div className={`${styles.timeWorkshop} text-start align-content-center d-inline-block px-3 py-2`}>
                                            <small className="d-block text-muted mb-1 me-2"><LuUsers className={`${styles.iconClock} mb-1 me-2`} /> Inscritos</small>
                                            <span className={`${styles.contagemUtilizadoresInscritos} fs-6 px-0`}>{workshop.users.length === 1 ? "1 utilizador" : `${workshop.users.length} utilizadores`} </span>
                                            <a type="button" className="align-content-center text-muted text-decoration-none fw-semibold fs-6 ms-1" onClick={() => { setListagemInscritos(true); setFormEdit(false) }}>
                                                <small className="text-muted"> (Ver todos)</small>
                                            </a>
                                        </div>
                                    ) : null}
                                </div>
                            </div>
                            </motion.div>
                        </div>


                        {listagemInscritos ? (
                            <motion.div variants={slideFromTopVariants} initial="initial" animate="animate" transition={slideFromTopTransition} className={`${styles.users} mt-4`}>
                                <div className="table-responsive">
                                    <button type="button" className={`${styles.btnClose} d-flex float-end p-1 mb-1`} onClick={() => setListagemInscritos(false)}><LuX className={`${styles.iconClose}`} /> </button>
                                    <table className="table table-striped table-hover align-middle mt-3">
                                        <thead className="table-dark">
                                            <tr>
                                                <th scope="col">ID</th>
                                                <th scope="col">Nome</th>
                                                <th scope="col">Email</th>
                                                <th scope="col">Inscrito em</th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            {workshop.users.map((user) => (
                                                <tr key={user.id}>
                                                    <td className="text-muted fw-semibold">#{user.id}</td>
                                                    <td>{user.name}</td>
                                                    <td>{user.email}</td>
                                                    <td>
                                                        {user.pivot?.created_at
                                                            ? new Date(user.pivot.created_at).toLocaleString("pt-PT", {
                                                                day: "2-digit",
                                                                month: "2-digit",
                                                                year: "numeric",
                                                                hour: "2-digit",
                                                                minute: "2-digit",
                                                            })
                                                            : "-"}
                                                    </td>
                                                </tr>
                                            ))}
                                        </tbody>
                                    </table>
                                </div>
                            </motion.div>
                        ) : null}
                    </div>

                    {!formEdit && role === 1 ? (
                        <motion.div variants={slideFromTopVariants} initial="initial" animate="animate" transition={slideFromTopTransition} className={`${styles.buttonsContainer} d-flex flex-wrap gap-2 justify-content-center mt-5`}>
                            <button
                                type="button"
                                className={`${styles.updateButton} bg-primary`}
                                onClick={() => {
                                    setFormEdit(true);
                                    setListagemInscritos(false);
                                    setTitle(workshop.title);
                                    setDescription(workshop.description);
                                    setImage(null);
                                    setDate(new Date(workshop.date));
                                    setTimeStart(new Date(`1970-01-01T${workshop.time_start}`));
                                    setTimeEnd(new Date(`1970-01-01T${workshop.time_end}`));
                                }}
                            >
                                <LuPencil className="mb-1" /> Editar
                            </button>
                            {workshop.status === "pending" ? (
                                <button type="button" className={`${styles.cancelButton}`} onClick={handleCancelWorkshop}><LuTrash2 className="mb-1 btn-danger" /> Cancelar Workshop</button>
                            ) : null}
                        </motion.div>
                    ) : null}




                    {formEdit ? (
                        <motion.form variants={slideFromTopVariants} initial="initial" animate="animate" transition={slideFromTopTransition} className={`${styles.formEdit} mt-5`} onSubmit={update}>
                            <span className={styles.subtitle}>Alterar detalhes do workshop</span>
                            <div className="row mx-auto g-4 mt-1">
                                <div className="col-12 px-1 text-start">
                                    <label className={`${styles.label} form-label fw-bold`} htmlFor="title">Título</label>
                                    <input type="text" className="form-control py-2 text-truncate" id="title" name="title" placeholder="Insira o título do workshop" defaultValue={workshop.title} onChange={(e) => setTitle(e.target.value)} required />
                                </div>
                                <div className="col-12 px-1 text-start">
                                    <label className={`${styles.label} form-label fw-bold`} htmlFor="description">Descrição</label>
                                    <textarea rows={5} className="form-control py-2" id="description" name="description" placeholder="Insira uma descrição para o workshop" defaultValue={workshop.description} onChange={(e) => setDescription(e.target.value)} />
                                </div>
                                <div className="col-12 px-1 text-start">
                                    <label className={`${styles.label} form-label fw-bold`} htmlFor="image">Adicionar imagem</label>
                                    <div className="position-relative">
                                        <span className={`${styles.inputFiles} form-control py-2 position-absolute top-0 start-0 px-3 w-100 text-decoration-none text-start fw-light fs-6 text-truncate`}>
                                            <LuUpload className="mb-1 me-2" /> {image ? image.name : "Carregar nova imagem"}
                                        </span>
                                        <input type="file" className={`${styles.inputFiles} form-control py-2 text-truncate`} id="image" name="image" accept="image/*" style={{ width: "100%", height: "100%", cursor: "pointer", zIndex: 1000, opacity: 0 }} onChange={(e) => setImage(e.target.files?.[0] ?? null)} />
                                    </div>
                                </div>
                                <div className="col-12 col-sm-4 px-1 text-start d-flex flex-column">
                                    <label className={`${styles.label} form-label fw-bold mb-2`} htmlFor="date">Data</label>
                                    <DatePicker
                                        selected={date ?? new Date(workshop.date)}
                                        onChange={(d: Date | null) => setDate(d)}
                                        dateFormat="dd/MM/yyyy"
                                        locale={pt}
                                        className="form-control py-2"
                                        placeholderText="Seleciona a data"
                                        id="date"
                                        name="date"
                                        minDate={new Date()}
                                    />
                                </div>
                                <div className="col-12 col-sm-4 px-1 text-start d-flex flex-column">
                                    <label className={`${styles.label} form-label fw-bold`} htmlFor="time_start">Hora de início</label>
                                    <DatePicker
                                        selected={time_start ? time_start : new Date(`1970-01-01T${workshop.time_start}`)}
                                        onChange={(t: Date | null) => setTimeStart(t)}
                                        showTimeSelect
                                        showTimeSelectOnly
                                        timeIntervals={10}
                                        timeFormat="HH:mm"
                                        dateFormat="HH:mm"
                                        locale={pt}
                                        className="form-control py-2"
                                        placeholderText="Hora de início"
                                        id="time_start"
                                        name="time_start"
                                        minTime={new Date(new Date().setHours(9, 0, 0, 0))}
                                        maxTime={new Date(new Date().setHours(22, 0, 0, 0))}
                                    />
                                </div>
                                <div className="col-12 col-sm-4 px-1 text-start d-flex flex-column">
                                    <label className={`${styles.label} form-label fw-bold`} htmlFor="time_end">Hora de término</label>
                                    <DatePicker
                                        selected={time_end ? time_end : new Date(`1970-01-01T${workshop.time_end}`)}
                                        onChange={(t: Date | null) => setTimeEnd(t)}
                                        showTimeSelect
                                        showTimeSelectOnly
                                        timeIntervals={10}
                                        timeFormat="HH:mm"
                                        dateFormat="HH:mm"
                                        locale={pt}
                                        className="form-control py-2"
                                        placeholderText="Hora de término"
                                        id="time_end"
                                        name="time_end"
                                        minTime={time_start
                                            ? new Date(new Date(time_start).getTime() + 30 * 60 * 1000)
                                            : new Date(new Date().setHours(23, 59, 59, 999))
                                        }
                                        maxTime={new Date(new Date().setHours(22, 0, 0, 0))}

                                    />
                                </div>

                                <div className="col-12 col-sm-4 px-1 text-start d-flex flex-column">
                                    <label className={`${styles.label} form-label fw-bold`} htmlFor="tags">Estado</label>
                                    <div className="d-flex flex-column flex-sm-row  gap-2 gap-sm-4">
                                        <span>
                                            <input
                                                type="radio"
                                                name="status"
                                                id="status_pending"
                                                value="pending"
                                                checked={status === "pending"}
                                                onChange={() => setStatus("pending")}
                                            />
                                            <label className="ms-1" htmlFor="status_pending">Agendado</label>
                                        </span>
                                        <span>
                                            <input
                                                type="radio"
                                                name="status"
                                                id="status_realized"
                                                value="realized"
                                                checked={status === "realized"}
                                                onChange={() => setStatus("realized")}
                                            />
                                            <label className="ms-1" htmlFor="status_realized">Realizado</label>
                                        </span>
                                        <span>
                                            <input
                                                type="radio"
                                                name="status"
                                                id="status_canceled"
                                                value="canceled"
                                                checked={status === "canceled"}
                                                onChange={() => setStatus("canceled")}
                                            />
                                            <label className="ms-1" htmlFor="status_canceled">Cancelado</label>
                                        </span>
                                    </div>
                                </div>

                                {error ? (
                                    <div className="">
                                        <div className="alert alert-danger mt-4">
                                            <p>{(error as ApiErrorResponse).message}</p>
                                        </div>
                                    </div>
                                ) : null}

                                <div className="buttonsContainer mt-4 d-flex gap-2 justify-content-center">
                                    <button type="button" className={`${styles.cancelButton}`} onClick={() => setFormEdit(false)}> <LuX className="mb-1" /> Cancelar </button>
                                    <button type="submit" className={`${styles.updateButton} bg-primary`} ><LuCheck className="mb-1" /> Submeter dados</button>
                                </div>
                            </div>
                        </motion.form>
                    ) : null}
                </>
            ) : (
                <div className="text-center alert alert-danger mt-5 align-items-center">
                    <span>Workshop não encontrado</span>
                </div>
            )}
        </div>
    );
}