import React, { useEffect, useState } from "react";
import {
  Col,
  Row,
  Form,
  Input,
  Modal,
  Table,
  Select,
  Button,
  Upload,
  Divider,
  Checkbox,
  DatePicker,
  message,
  Tooltip,
} from "antd";
import {
  SaveOutlined,
  UploadOutlined,
  ArrowLeftOutlined,
  PlusCircleOutlined,
  MinusCircleOutlined,
} from "@ant-design/icons";
import "moment/locale/es-mx";
import moment from "moment";
import locale from "antd/es/date-picker/locale/es_ES";
import { useHistory } from "react-router-dom";
import { push, ref as refDatabase } from "firebase/database";
import {
  addDoc,
  collection,
  doc,
  getDoc,
  updateDoc,
  onSnapshot,
  query as firebseQuery,
  getDocs,
  where,
} from "firebase/firestore";
import {
  ref as refStorage,
  uploadBytes,
  deleteObject,
  getStorage,
  getDownloadURL,
} from "firebase/storage";

import { useQuery } from "../../../hooks";
import { ViewLoading } from "../../../components";
import { DefaultLayout } from "../../../components/layouts";
import { firestore, storage, database } from "../../../services/firebase";

const EventosDetalle = () => {
  const urlweb = "/administracion/eventos";
  const query = useQuery();
  const history = useHistory();
  const { TextArea, Search } = Input;
  const { Option } = Select;
  const id = query.get("id");
  const editando = !!id;
  const [form] = Form.useForm();

  const [evento, setEvento] = useState([]);
  const [cargandoEvento, setCargandoEvento] = useState(true);
  const [guadandoCargando, setGuardandoCargando] = useState(false);
  const [sinFechaFin, setSinFechaFin] = useState(false);
  const [visible, setVisible] = useState(false);
  const [cargandoGrupos, setCargandoGrupos] = useState(true);
  const [grupos, setGrupos] = useState([]);
  const [filteredResults, setFilteredResults] = useState([]);
  const [searchInput, setSearchInput] = useState("");
  const [selectedGrupos, setSelectedGrupos] = useState([]);
  const [selectedFile, setSelectedFile] = useState(null);
  const [selectedFileList, setSelectedFileList] = useState([]);
  const [previaImg, setPreviaImg] = useState(null);
  const [redes, setRedes] = useState([]);

  const defaultText = (prop) =>
    prop || <span style={{ color: "#c7c3c3" }}>---</span>;

  const multipleButtonData = [
    {
      text: "Volver",
      to: () => history.goBack(),
      icon: <ArrowLeftOutlined />,
      props: { disabled: false, type: "primary" },
    },
  ];

  const columns = [
    {
      title: "Nombre",
      dataIndex: "nombre",
      key: "nombre",
      render: defaultText,
    },
    {
      title: "Ciudad",
      dataIndex: "ciudad",
      key: "ciudad",
      render: defaultText,
    },
    {
      title: "Creado",
      dataIndex: "timestamp",
      key: "timestamp",
      render: (_, item) =>
        moment(item?.timestamp?.toDate()).format("DD-MM-YYYY"),
    },
  ];

  const redesSociales = [
    "Facebook",
    "Twitter",
    "Instagram",
    "Whatsapp",
    "YouTube",
    "TikTok",
    "Otro",
  ];

  const acciones = [
    { id: 0, value: "Ver", label: "Ver", icon: "👁" },
    { id: 1, value: "Me gusta", label: "Me gusta", icon: "👍" },
    { id: 2, value: "Compartir", label: "Compartir", icon: "🔄" },
  ];

  const rowSelection = {
    onChange: (selectedRowKeys, _) => {
      setSelectedGrupos(selectedRowKeys);
    },
  };

  const obtenerUsuariosGrupo = async () => {
    try {
      const q = firebseQuery(
        collection(firestore, "usuarios"),
        where("grupos", "array-contains-any", selectedGrupos)
      );
      const querySnapshot = await getDocs(q);
      const docs = [];

      querySnapshot.forEach((doc) => {
        const data = doc.data();
        if (data?.estatus) {
          docs.push({
            grupos: data?.grupos,
            facebook: data?.facebook,
            twitter: data?.twitter,
            instagram: data?.instagram,
            telefono: data?.telefono,
            nombre: data?.nombre,
            uid: data?.uid,
            id: doc.id,
            facebookVerificado: data?.facebookVerificado,
            instagramVerificado: data?.instagramVerificado,
            twitterVerificado: data?.twitterVerificado,
          });
        }
      });

      return docs;
    } catch (error) {
      console.log("error al obtener grupos: ", error);
    }
  };

  const normFile = (e) => {
    if (Array.isArray(e)) {
      return e;
    }
    return e && e.fileList;
  };

  const dummyRequest = ({ onSuccess }) => {
    setTimeout(() => {
      onSuccess("ok");
    }, 0);
  };

  const onChangeFile = (info) => {
    let src = URL.createObjectURL(info.file.originFileObj);
    setPreviaImg(src);
    switch (info.file.status) {
      case "uploading":
        setSelectedFileList([info.file]);
        break;
      case "done":
        setSelectedFile(info.file);
        setSelectedFileList([info.file]);
        break;
      default:
        setSelectedFile(null);
        setSelectedFileList([]);
    }
  };

  const eliminarImagen = async (fileRoute) => {
    const storage = getStorage();
    const desertRef = refStorage(storage, fileRoute);
    deleteObject(desertRef)
      .then((e) => {})
      .catch((error) => {
        console.log(error);
      });
  };

  const onSearch = (searchValue) => {
    setSearchInput(searchValue);
    if (searchValue !== "") {
      const filteredData = grupos.filter((item) => {
        return Object.values(item)
          .join("")
          .toLowerCase()
          .includes(searchValue.toLowerCase());
      });
      setFilteredResults(filteredData);
    } else {
      setFilteredResults(grupos);
    }
  };

  const onFinish = async (values) => {
    try {
      const {
        accion,
        ciudad,
        descripcion,
        fechaFinal,
        fechaInicio,
        nombre,
        redSocial,
        url,
      } = values;

      setGuardandoCargando(true);

      let file = selectedFile ? selectedFile.originFileObj : null;

      if (!editando && !file) {
        Modal.warning({
          title: "Atención",
          content: "Debes subir una imagen del evento.",
          style: { marginTop: "20vh" },
        });
      }

      let rutaFoto = evento?.fotoEvento;
      let pathFirebase = evento?.pathFirebase;

      if (file) {
        if (editando) {
          await eliminarImagen(evento?.fotoEvento);
        }

        const postListRef = refDatabase(database, "fotosEventos");
        const newPostRef = push(postListRef);
        rutaFoto = `fotosEventos/${newPostRef?.key}`;
        const fotoRefStorage = refStorage(storage, rutaFoto);
        try {
          let res = await uploadBytes(fotoRefStorage, file);
          pathFirebase = await getDownloadURL(res?.ref);
        } catch (error) {
          console.log("Error en el uploadbytes: ", error);
        }
      }

      const docsUsuarios = await obtenerUsuariosGrupo();

      let resultado = { ...evento?.resultado };
      let usuarios = [];

      for (let u = 0; u < docsUsuarios?.length; u++) {
        if (resultado[docsUsuarios[u]?.uid] === undefined) {
          resultado[docsUsuarios[u]?.uid] = [];
        }

        if (resultado[docsUsuarios[u]?.uid]?.length < 1) {
          resultado = {
            ...resultado,
            [docsUsuarios[u].uid]: [],
          };
        }

        usuarios.push({
          id: docsUsuarios[u]?.id,
          uid: docsUsuarios[u]?.uid,
          grupos: docsUsuarios[u]?.grupos,
          nombre: docsUsuarios[u]?.nombre,
          twitter: docsUsuarios[u]?.twitter,
          telefono: docsUsuarios[u]?.telefono,
          facebook: docsUsuarios[u]?.facebook,
          instagram: docsUsuarios[u]?.instagram,
          facebookVerificado: Boolean(docsUsuarios[u]?.facebookVerificado),
          instagramVerificado: Boolean(docsUsuarios[u]?.instagramVerificado),
          twitterVerificado: Boolean(docsUsuarios[u]?.twitterVerificado),
        });
      }

      let body = {
        accion: accion || [],
        ciudad: ciudad || "",
        descripcion: descripcion || "",
        fechaFinal: fechaFinal?.toString() || "",
        fechaInicio: fechaInicio?.toString(),
        sinFechaFin: sinFechaFin,
        nombre: nombre || "",
        redSocial: redSocial || "",
        url: url || "",
        grupos: selectedGrupos,
        fotoEvento: rutaFoto,
        pathFirebase: pathFirebase,
        timestamp: editando ? evento?.timestamp : new Date(),
        estatus: editando ? evento?.estatus : true,
        usuarios: usuarios,
        redes: redes,
        resultado: resultado,
        sincronizado: null,
      };

      const tag = makeid(8);

      //Crear grupo de eventos
      if (redes.length > 0) {
        let grupoEvento = {
          accion: accion,
          ciudad: ciudad,
          descripcion: descripcion,
          fechaFinal: fechaFinal?.toString() || "",
          fechaInicio: fechaInicio?.toString(),
          sinFechaFin: sinFechaFin,
          nombre: nombre || "",
          grupos: selectedGrupos,
          fotoEvento: rutaFoto,
          pathFirebase: pathFirebase,
          timestamp: editando ? evento?.timestamp : new Date(),
          estatus: editando ? evento?.estatus : true,
          tag: tag,
          redes: redes,
          usuarios: usuarios,
          resultado: resultado,
        };

        await addDoc(collection(firestore, "gruposEvento"), grupoEvento);
      }

      if (editando) {
        await updateDoc(doc(firestore, "eventos", id), body);
        return;
      }

      for (let i = 0; i < redes?.length; i++) {
        body = {
          ...body,
          redSocial: redes[i]?.redSocial,
          url: redes[i]?.url,
        };

        if (!editando) {
          body["tag"] = tag;
        }
        await addDoc(collection(firestore, "eventos"), body);
      }

      Modal.success({
        title: "Éxito",
        content: "Evento guardado correctamente",
      });

      history.push(urlweb);
    } catch (error) {
      Modal.warning({
        title: "Atención",
        content: "Hubo un problema al guardar, intentalo de nuevo.",
      });
      console.log("Error al guardar evento: ", error);
    } finally {
      setGuardandoCargando(false);
    }
  };

  const onFinishFailed = () => {
    Modal.warning({
      title: "Atención",
      content: "Por favor revise los datos.",
      style: { marginTop: "20vh" },
    });
  };

  function makeid(length) {
    let result = "";
    const characters =
      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    const charactersLength = characters.length;
    for (var i = 0; i < length; i++) {
      result += characters.charAt(Math.floor(Math.random() * charactersLength));
    }
    return result;
  }

  const agregarRedSocial = () => {
    const key = makeid(6);
    const datos = [...redes];

    const url = form.getFieldValue("url");
    const red = form.getFieldValue("redSocial");

    if (!url) {
      message.warning({
        content: "Ingresa una URL",
      });
      return;
    }

    if (!red) {
      message.warning({
        content: "Selecciona una red social",
      });
      return;
    }

    let existe = false;
    for (let i = 0; i < redes.length; i++) {
      if (redes[i]?.redSocial === red) existe = true;
      break;
    }

    if (existe) {
      message.warning({
        content: "Esta red social ya existe, elige otra diferente.",
      });
      return;
    }

    datos.push({
      key: key,
      url: url,
      redSocial: red,
    });

    setRedes(datos);
    form.setFieldsValue({
      url: null,
      redSocial: null,
    });
  };

  const quitarRedSocial = (key) => {
    let data = [...redes];
    for (let i = 0; i < data?.length; i++) {
      if (redes[i].key === key) {
        data.splice(i, 1);
        break;
      }
    }
    setRedes(data);
  };

  const leerLink = (evento) => {
    let link = evento?.target?.value;
    const facebook =
      /https?:\/\/(www\.)?facebook\.com\/[a-zA-Z0-9.-]+\/?/ ||
      /https?:\/\/(www\.)?fb\.com\/[a-zA-Z0-9.-]+\/?/;
    const twitter = /https?:\/\/(www\.)?twitter\.com\/[a-zA-Z0-9.-]+\/?/;
    const instagram = /https?:\/\/(www\.)?instagram\.com\/[a-zA-Z0-9.-]+\/?/;
    const whatsapp = /https?:\/\/(www\.)?wa\.me\/[a-zA-Z0-9.-]+\/?/;
    const youtube = /https?:\/\/(www\.)?youtube\.com\/[a-zA-Z0-9.-]+\/?/g;
    const ytShort = /https?:\/\/(www\.)?youtu\.be\/[a-zA-Z0-9.-]+\/?/g;
    const tiktok = /https?:\/\/(?:www\.)?tiktok\.com\/.*?/g;

    if (facebook.test(link)) {
      form.setFieldsValue({ redSocial: "Facebook" });
    } else if (twitter.test(link)) {
      form.setFieldsValue({ redSocial: "Twitter" });
    } else if (instagram.test(link)) {
      form.setFieldsValue({ redSocial: "Instagram" });
    } else if (whatsapp.test(link)) {
      form.setFieldsValue({ redSocial: "Whatsapp" });
    } else if (youtube.test(link) || ytShort.test(link)) {
      form.setFieldsValue({ redSocial: "YouTube" });
    } else if (tiktok.test(link)) {
      form.setFieldsValue({ redSocial: "TikTok" });
    } else {
      form.setFieldsValue({ redSocial: "Otro" });
    }
  };

  // Grupos
  useEffect(() => {
    try {
      onSnapshot(collection(firestore, "grupos"), (querySnapshot) => {
        const docs = [];
        querySnapshot.forEach((doc) => {
          if (doc.data()?.estatus) {
            docs.push({ ...doc.data(), id: doc.id });
          }
        });
        setGrupos(docs);
      });
    } catch (error) {
      console.log("error al cargar grupos de firebase: ", error);
    } finally {
      setCargandoGrupos(false);
    }
  }, []);

  // Limpiar imagen
  useEffect(() => {
    if (!selectedFile) {
      setPreviaImg(null);
    }
  }, [selectedFile]);

  // Obtener detalles del evento.
  useEffect(() => {
    let mounted = true;
    if (mounted && editando) {
      try {
        setTimeout(async () => {
          const docRef = doc(firestore, "eventos", id);
          const docSnap = await getDoc(docRef);
          setEvento(docSnap.data());
        }, 0);
      } catch (error) {
        console.log("error al obtener evento: ", error);
      } finally {
        setCargandoEvento(false);
      }
    }
    return () => (mounted = false);
  }, [editando, id]);

  useEffect(() => {
    let mounted = true;
    if (mounted && evento && editando) {
      setPreviaImg(evento?.pathFirebase);
      setSinFechaFin(evento?.sinFechaFin);
      setSelectedGrupos(evento?.grupos);
      form.setFieldsValue({
        ...evento,
        fechaFinal: moment(evento?.fechaFinal),
        fechaInicio: moment(evento?.fechaInicio),
      });
    }
    return () => (mounted = false);
  }, [editando, evento, form]);

  if (cargandoEvento && editando) return <ViewLoading />;

  return (
    <DefaultLayout multipleButtonData={multipleButtonData}>
      <Modal
        title="Agregar grupos"
        centered
        open={visible}
        onOk={() => setVisible(false)}
        onCancel={() => setVisible(false)}
        okText="Guardar"
        width={800}
      >
        <Search
          placeholder="Buscar..."
          enterButton="Buscar"
          size="large"
          style={{ width: "100%" }}
          onSearch={onSearch}
        />
        <Divider />
        <Table
          dataSource={searchInput?.length > 1 ? filteredResults : grupos}
          rowKey="id"
          pagination={{
            pageSize: 5,
          }}
          rowSelection={{
            type: "checkbox",
            selectedRowKeys: selectedGrupos,
            ...rowSelection,
          }}
          loading={cargandoGrupos}
          columns={columns}
          size="small"
          scroll={{ x: 700 }}
        />
      </Modal>
      <Form
        name="form"
        form={form}
        autoComplete="off"
        layout="vertical"
        onFinish={onFinish}
        onFinishFailed={onFinishFailed}
      >
        {/* Imagen - Nombre - Ciudad - Descripción - Url - Red social  */}
        <Row gutter={10}>
          {/* Columna 1  */}
          <Col
            className="gutter-row"
            xs={{ span: 24 }}
            sm={{ span: 24 }}
            md={{ span: 8 }}
            lg={{ span: 8 }}
          >
            <Row
              gutter={10}
              style={{
                display: "flex",
                flexDirection: "row",
                height: "100%",
              }}
            >
              <Col span={24}>
                <Form.Item
                  name="upload"
                  label="Imagen del evento"
                  valuePropName="fileList"
                  rules={[
                    { required: editando ? false : true, message: "Requerido" },
                  ]}
                  getValueFromEvent={normFile}
                  extra={editando && evento ? evento?.fotoEvento : null}
                >
                  <Upload
                    accept="image/gif, image/jpeg, image/png"
                    fileList={selectedFileList}
                    customRequest={dummyRequest}
                    onChange={onChangeFile}
                    name="fotoEvento"
                    multiple={false}
                    maxCount={1}
                  >
                    <Button icon={<UploadOutlined />}>Elegir imagen</Button>
                  </Upload>
                </Form.Item>
              </Col>

              <Col span={24}>
                {previaImg ? <img src={previaImg} width="100%" alt="" /> : null}
              </Col>

              <Col span={24} style={{ marginTop: 133 }}>
                <Button
                  block
                  type="dashed"
                  icon={<PlusCircleOutlined />}
                  onClick={() => setVisible(true)}
                >
                  Agregar grupos ({selectedGrupos?.length})
                </Button>
              </Col>
            </Row>
          </Col>

          {/* Columna 2  */}
          <Col
            className="gutter-row"
            xs={{ span: 24 }}
            sm={{ span: 24 }}
            md={{ span: 16 }}
            lg={{ span: 16 }}
          >
            {/* Nombre evento - Ciuad  */}
            <Row gutter={10}>
              <Col
                className="gutter-row"
                xs={{ span: 24 }}
                sm={{ span: 24 }}
                md={{ span: 12 }}
                lg={{ span: 12 }}
              >
                <Form.Item
                  label="Nombre del evento"
                  name="nombre"
                  rules={[{ required: true, message: "Requerido" }]}
                >
                  <Input />
                </Form.Item>
              </Col>
              <Col
                className="gutter-row"
                xs={{ span: 24 }}
                sm={{ span: 24 }}
                md={{ span: 12 }}
                lg={{ span: 12 }}
              >
                <Form.Item
                  label="Ciudad"
                  name="ciudad"
                  rules={[{ required: true, message: "Requerido" }]}
                >
                  <Input />
                </Form.Item>
              </Col>
            </Row>

            {/* Descripción */}
            <Row gutter={10}>
              <Col className="gutter-row" span={24}>
                <Form.Item
                  label="Descripción"
                  name="descripcion"
                  rules={[{ required: true, message: "Requerido" }]}
                >
                  <TextArea placeholder="Ingrese una descripción..." rows={4} />
                </Form.Item>
              </Col>
            </Row>
          </Col>
        </Row>

        {/* Fecha de inicio - Fecha fin - sin fecha - Accion  */}
        <Row gutter={10} style={{ marginTop: 30 }}>
          <Col
            className="gutter-row"
            xs={{ span: 24 }}
            sm={{ span: 24 }}
            md={{ span: 6 }}
            lg={{ span: 6 }}
          >
            <Form.Item
              rules={[{ required: true, message: "Requerido" }]}
              label="Fecha de inicio"
              name="fechaInicio"
            >
              <DatePicker
                format="YYYY-MM-DD HH:mm"
                style={{ width: "100%" }}
                locale={locale}
                showTime={{
                  defaultValue: moment("00:00", "HH:mm"),
                }}
              />
            </Form.Item>
          </Col>

          <Col
            className="gutter-row"
            xs={{ span: 24 }}
            sm={{ span: 24 }}
            md={{ span: 6 }}
            lg={{ span: 6 }}
          >
            <Form.Item
              rules={[{ required: !sinFechaFin, message: "Requerido" }]}
              label="Fecha de finalización"
              name="fechaFinal"
            >
              <DatePicker
                disabled={sinFechaFin}
                format="YYYY-MM-DD HH:mm"
                style={{ width: "100%" }}
                locale={locale}
                showTime={{
                  defaultValue: moment("00:00", "HH:mm"),
                }}
              />
            </Form.Item>
          </Col>

          <Col
            className="gutter-row"
            xs={{ span: 24 }}
            sm={{ span: 24 }}
            md={{ span: 6 }}
            lg={{ span: 6 }}
          >
            <Form.Item label="&nbsp;">
              <Checkbox
                checked={sinFechaFin}
                onChange={(e) => setSinFechaFin(e.target.checked)}
              >
                Sin fecha de finalización
              </Checkbox>
            </Form.Item>
          </Col>

          <Col
            className="gutter-row"
            xs={{ span: 24 }}
            sm={{ span: 24 }}
            md={{ span: 6 }}
            lg={{ span: 6 }}
          >
            <Form.Item label="Acción" name="accion">
              <Select
                mode="multiple"
                style={{ width: "100%" }}
                placeholder="Selecciona una o más opciones"
                optionLabelProp="label"
              >
                {acciones?.map((item) => (
                  <Option
                    value={item?.value}
                    label={item?.label}
                    key={item?.id}
                  >
                    <div className="demo-option-label-item">
                      <span role="img" aria-label={item?.label}>
                        {item?.icon}
                      </span>
                      {item?.label}
                    </div>
                  </Option>
                ))}
              </Select>
            </Form.Item>
          </Col>
        </Row>

        {/* URL - Red Social - Agregar [+] */}
        <Row gutter={10}>
          <Col
            className="gutter-row"
            xs={{ span: 24 }}
            sm={{ span: 24 }}
            md={{ span: 12 }}
            lg={{ span: 12 }}
          >
            <Form.Item label="URL" name="url">
              <Input onChange={(v) => leerLink(v)} />
            </Form.Item>
          </Col>

          <Col
            className="gutter-row"
            xs={{ span: 24 }}
            sm={{ span: 24 }}
            md={{ span: editando ? 12 : 9 }}
            lg={{ span: editando ? 12 : 9 }}
          >
            <Form.Item label="Red social" name="redSocial">
              <Select style={{ width: "100%" }} placeholder="Selecciona">
                {redesSociales?.map((item) => (
                  <Option key={item} value={item}>
                    {item}
                  </Option>
                ))}
              </Select>
            </Form.Item>
          </Col>

          {!editando && (
            <Col
              className="gutter-row"
              xs={{ span: 24 }}
              sm={{ span: 24 }}
              md={{ span: 3 }}
              lg={{ span: 3 }}
            >
              <Form.Item label="&nbsp;">
                <Button
                  type="primary"
                  icon={<PlusCircleOutlined />}
                  block
                  onClick={agregarRedSocial}
                />
              </Form.Item>
            </Col>
          )}
        </Row>

        {redes.map((item) => (
          <Row key={item.key} gutter={10}>
            <Col
              className="gutter-row"
              xs={{ span: 24 }}
              sm={{ span: 24 }}
              md={{ span: 12 }}
              lg={{ span: 12 }}
            >
              <Form.Item label="&nbsp;">
                <Input readOnly value={item?.url} />
              </Form.Item>
            </Col>

            <Col
              className="gutter-row"
              xs={{ span: 24 }}
              sm={{ span: 24 }}
              md={{ span: 9 }}
              lg={{ span: 9 }}
            >
              <Form.Item label="&nbsp;">
                <Input readOnly value={item?.redSocial} />
              </Form.Item>
            </Col>

            <Col
              className="gutter-row"
              xs={{ span: 24 }}
              sm={{ span: 24 }}
              md={{ span: 3 }}
              lg={{ span: 3 }}
            >
              <Form.Item label="&nbsp;">
                <Tooltip title="Remover">
                  <Button
                    type="danger"
                    icon={<MinusCircleOutlined />}
                    block
                    onClick={() => quitarRedSocial(item?.key)}
                  />
                </Tooltip>
              </Form.Item>
            </Col>
          </Row>
        ))}

        <Row gutter={10}>
          <Col
            xs={{ span: 24 }}
            sm={{ span: 24 }}
            md={{ span: 12 }}
            lg={{ span: 8 }}
          >
            <Button
              type="primary"
              htmlType="submit"
              icon={<SaveOutlined />}
              block
              size="large"
              loading={guadandoCargando}
            >
              Guardar
            </Button>
          </Col>
        </Row>
      </Form>
    </DefaultLayout>
  );
};

export default EventosDetalle;
