import React, { createContext, useContext, useState, useEffect } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useSelector } from "react-redux";

// Components
import ExpenseList from "../../components/Expenses/ExpenseList";
import ViewExpense from "../../components/Expenses/ViewExpense";
import Breadcrumb from "../../components/common/Breadcrumb";
import GlobalModel from "../../components/common/GlobalModel";
import PreviewDocument from "../../components/Expenses/PreviewDocument";
import ManageExpense from "../../components/Expenses/ManageExpense";
import ExpenseFilterPanel from "../../components/Expenses/ExpenseFilterPanel";

// Context & Hooks
import { useFab } from "../../Context/FabContext";
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import {
  CREATE_EXEPENSE,
  VIEW_ALL_EXPNESE,
  VIEW_SELF_EXPENSE,
} from "../../utils/constants";

// Schema & Defaults
import {
  defaultFilter,
  SearchSchema,
} from "../../components/Expenses/ExpenseSchema";

// Context
export const ExpenseContext = createContext();
export const useExpenseContext = () => {
  const context = useContext(ExpenseContext);
  if (!context) {
    throw new Error("useExpenseContext must be used within an ExpenseProvider");
  }
  return context;
};

const ExpensePage = () => {
  const selectedProjectId = useSelector(
    (store) => store.localVariables.projectId
  );

  const [filters, setFilter] = useState();
  const [groupBy, setGroupBy] = useState("transactionDate");
  const [searchText, setSearchText] = useState("");

  const [ManageExpenseModal, setManageExpenseModal] = useState({
    IsOpen: null,
    expenseId: null,
  });

  const [viewExpense, setViewExpense] = useState({
    expenseId: null,
    view: false,
  });

  const [ViewDocument, setDocumentView] = useState({
    IsOpen: false,
    Image: null,
  });

  const IsCreatedAble = useHasUserPermission(CREATE_EXEPENSE);
  const IsViewAll = useHasUserPermission(VIEW_ALL_EXPNESE);
  const IsViewSelf = useHasUserPermission(VIEW_SELF_EXPENSE);

  const { setOffcanvasContent, setShowTrigger } = useFab();

  const methods = useForm({
    resolver: zodResolver(SearchSchema),
    defaultValues: defaultFilter,
  });

  const { reset } = methods;

  const clearFilter = () => {
    setFilter(defaultFilter);
    reset();
  };

  useEffect(() => {
    setShowTrigger(true);
    setOffcanvasContent(
      "Expense Filters",
      <ExpenseFilterPanel
        onApply={setFilter}
        handleGroupBy={setGroupBy}
        clearFilter={clearFilter}
      />
    );

    return () => {
      setShowTrigger(false);
      setOffcanvasContent("", null);
    };
  }, []);

  const contextValue = {
    setViewExpense,
    setManageExpenseModal,
    setDocumentView,
  };

  return (
    <ExpenseContext.Provider value={contextValue}>
      <div className="container-fluid">
        <Breadcrumb data={[{ label: "Home", link: "/" }, { label: "Expense" }]} />

        {(IsViewAll || IsViewSelf) ? (
          <>
            <div className="card my-1">
              <div className="card-body py-2 px-3">
                <div className="row align-items-center">
                  <div className="col-sm-6 col-md-4">
                    <div className="d-flex align-items-center">

                      <input
                        type="search"
                        className="form-control form-control-sm w-auto"
                        placeholder="Search Expense"
                        aria-describedby="search-label"
                        value={searchText}
                        onChange={(e) => setSearchText(e.target.value)}
                      />
                    </div>
                  </div>

                  <div className="col-sm-6 col-md-8 text-end mt-2 mt-sm-0">
                    {IsCreatedAble && (
                      <button
                        type="button"
                        className="p-1 me-2 bg-primary rounded-circle"
                        title="Add New Expense"
                        onClick={() => setManageExpenseModal({ IsOpen: true, expenseId: null })}
                      >
                        <i className="bx bx-plus fs-4 text-white"></i>
                      </button>
                    )}
                  </div>
                </div>
              </div>
            </div>

            <ExpenseList filters={filters} groupBy={groupBy} searchText={searchText} />
          </>
        ) : (
          <div className="card text-center py-1">
            <i className="fa-solid fa-triangle-exclamation fs-5" />
            <p>Access Denied: You don't have permission to perform this action!</p>
          </div>
        )}

        {/* Modals */}
        {ManageExpenseModal.IsOpen && (
          <GlobalModel
            isOpen
            size="lg"
            closeModal={() => setManageExpenseModal({ IsOpen: null, expenseId: null })}
          >
            <ManageExpense
              key={ManageExpenseModal.expenseId ?? "new"}
              expenseToEdit={ManageExpenseModal.expenseId}
              closeModal={() => setManageExpenseModal({ IsOpen: null, expenseId: null })}
            />
          </GlobalModel>
        )}

        {viewExpense.view && (
          <GlobalModel
            isOpen
            size="lg"
            modalType="top"
            closeModal={() => setViewExpense({ expenseId: null, view: false })}
          >
            <ViewExpense ExpenseId={viewExpense.expenseId} />
          </GlobalModel>
        )}

        {ViewDocument.IsOpen && (
          <GlobalModel
            isOpen
            size="lg"
            key={ViewDocument.Image ?? "doc"}
            closeModal={() => setDocumentView({ IsOpen: false, Image: null })}
          >
            <PreviewDocument imageUrl={ViewDocument.Image} />
          </GlobalModel>
        )}
      </div>
    </ExpenseContext.Provider>
  );
};

export default ExpensePage;
