import React, { Component } from "react";
import { styled } from "@mui/system";
import { Tabs as BaseTabs } from "@mui/base/Tabs";
import { Box, Button } from "@mui/material";
import BuildIcon from "@mui/icons-material/Build";
import { TabsList as BaseTabsList } from "@mui/base/TabsList";
import { TabPanel as BaseTabPanel } from "@mui/base/TabPanel";
import { Tab as BaseTab, tabClasses } from "@mui/base/Tab";
import { __ } from "@wordpress/i18n";
import DateAndTimeTab from "./components/DateAndTimeTab";
import ServiceTab from "./components/ServiceTab";
import UserInfoTab from "./components/UserInfoTab";
import PaymentsTab from "./components/PaymentsTab";
import ConfirmationTab from "./components/ConfirmationTab";
import { ThemeProvider, createTheme } from "@mui/material/styles";
import CssBaseline from "@mui/material/CssBaseline";
import currencies from "../currencies.json";
import Location from "./assets/location.png";
import Service from "./assets/service.png";
import Staff from "./assets/staff.png";
import Date from "./assets/date.png";
import Info from "./assets/info.png";
import Payment from "./assets/payment.png";
import Confirm from "./assets/confirm.png";
import { withBooking } from "../FormContext";

const ProLocationTab = typeof window !== "undefined" && window.LocationTab
    ? withBooking(["locationId", "locationName", "locations", "dataLoading"])(function ProLocationTabWithStore(props) {
        const { state, updateInput, ...rest } = props;
        const data = { locations: state.locations || [], dataLoading: state.dataLoading };
        return window.LocationTab ? <window.LocationTab {...rest} context={{ state, updateInput }} data={data} /> : null;
    })
    : null;

const ProStaffTab = typeof window !== "undefined" && window.StaffTab
    ? withBooking([
        "locationId",
        "serviceId",
        "staffId",
        "staffName",
        "servicePrice",
        "staffsByServices",
        "staffStopRerendering",
        "staffsByServiceLoading",
    ])(function ProStaffTabWithStore(props) {
        const { state, updateInput, ...rest } = props;
        return window.StaffTab ? <window.StaffTab {...rest} context={{ state, updateInput }} /> : null;
    })
    : null;

const DateAndTimeTabWithStore = withBooking([
    "weekStartsOn",
    "timeFormat",
    "slotsTimezone",
    "dataLoading",
    "serviceId",
    "staffId",
    "slot",
    "date",
    "servicePrice",
    "toggleLimitedBooking",
    "limitedBookingMonths",
    "zoomToggle",
    "gcalForCustomer",
    "ocalForCustomer",
    "daysOpen",
    "specialDate",
    "holidays",
    "slots",
    "multipleBooking",
    "timezone",
])(function DateAndTimeTabWithStore(props) {
    const { state, updateInput, ...rest } = props;
    return <DateAndTimeTab {...rest} state={state} data={state} updateInput={updateInput} />;
});

const ConfirmationTabWithStore = withBooking([
    "slot",
    "date",
    "timezone",
    "serviceName",
    "staffName",
    "firstName",
    "lastName",
    "email",
    "phone",
    "gateway",
    "total",
    "appointmentId",
    "currencySymbol",
    "currencyCode",
    "timeFormat",
    "gcalForCustomer",
    "ocalForCustomer",
])(function ConfirmationTabWithStore(props) {
    const { state, updateInput, ...rest } = props;
    return <ConfirmationTab {...rest} state={state} data={state} updateInput={updateInput} />;
});

const theme = createTheme({
    components: {
        MuiButtonBase: {
            defaultProps: {
                disableRipple: true
            },
        },
        MuiButton: {
            variants: [
                {
                    props: { variant: "wpbkHelpBtn" },
                    style: {
                        textTransform: "capitalize",
                        boxShadow: "none",
                        color: "#668888",
                        padding: "15px 0px",
                        fontWeight: 500,
                        maxWidth: "150px",
                        "&:hover": {
                            boxShadow: "none",
                        },
                        "& .MuiButton-startIcon": {
                            marginRight: "5px"
                        },
                    },
                },
            ],
        },
    },
});

class DefaultFrontendApp extends Component {

    tabListRef = React.createRef();
    indicatorRef = React.createRef();
    indicatorInitialized = false;
    lastIndicatorOffset = 0;

    state = {
        currentTab: 0,
    };

    handleChange = (event, newValue) => {
        this.setState({ currentTab: newValue });
    };

    setTab = (newValue) => {
        this.setState({ currentTab: newValue });
    };

    componentDidMount() {
        const { updateInput } = this.props;
        const LocationTab = window.LocationTab;

        updateInput({ dataLoading: true });

        const promises = [this.fetchSettings()];

        if ( LocationTab && wpbApp.locationsCount > 0 ) {
            promises.push( this.fetchLocations() );
        } else {
            promises.push( this.fetchServices() );
        }

        Promise.all( promises )
            .then(() => {
                updateInput({ dataLoading: false });
            })
            .catch((error) => {
                console.error( "Error fetching data:", error );
                updateInput({ dataLoading: false });
            });

        this.updateTabIndicator();
    }

    componentDidUpdate() {
        this.updateTabIndicator();
    }

    updateTabIndicator = () => {
        if (!this.tabListRef.current || !this.indicatorRef.current) {
            return;
        }

        const tabs = this.tabListRef.current.querySelectorAll('.bookify-nav-tab');
        const selectedTab = tabs[this.state.currentTab];

        if (selectedTab) {
            const { offsetTop } = selectedTab;
            const indicator = this.indicatorRef.current;
            const startOffset = this.indicatorInitialized ? this.lastIndicatorOffset : offsetTop;

            indicator.style.transition = 'none';
            indicator.style.transform = `translateY(${startOffset}px)`;
            void indicator.offsetHeight;

            indicator.style.transition = 'transform 0.25s ease';
            indicator.style.transform = `translateY(${offsetTop}px)`;

            this.indicatorInitialized = true;
            this.lastIndicatorOffset = offsetTop;
        }
    };

    fetchSettings() {
        const { updateInput } = this.props;

        return fetch(`${wpbApp.root}bookify/frontend/v1/settings`, {
            method: "GET",
            headers: {
                "Content-Type": "application/json",
                "X-WP-Nonce": wpbApp.nonce,
            }
        })
        .then((response) => response.json())
        .then((data) => {
            const matchedCurrency = Object.values(currencies).find(eachCurrency => eachCurrency.code === data.general.DefaultGeneralCurrencies);

            updateInput({
                currencySymbol: matchedCurrency?.symbol_native || "",
                currencyCode: matchedCurrency?.code || "USD",
                weekStartsOn: data.general.DefaultWeekStartOn,
                toggleLimitedBooking: data.general.DefaultPriorToBooking,
                limitedBookingMonths: data.general.PriorTimeToBooking,
                timeFormat: data.general.DefaultTimeFormat,
                slotsTimezone: data.general.slotsTimezone,
                supportLinkText: data.general.supportLinkText,
                supportLinkUrl: data.general.supportLinkUrl,
                showFormSupportLink: data.general.showFormSupportLink,
                gcalForCustomer: data.integration.gcalForCustomer,
                ocalForCustomer: data.integration.ocalForCustomer,
                zoomToggle: data.integration.ZoomToggle,
            });
        })
        .catch((error) => {
            console.error("Error fetching settings:", error);
        });
    
    }

    fetchServices() {
        const { updateInput } = this.props;

        return fetch(`${wpbApp.root}bookify/frontend/v1/get-services`, {
            method: "GET",
            headers: {
                "Content-Type": "application/json",
                "X-WP-Nonce": wpbApp.nonce,
		        "Services" : wpbApp.Services,
            }
        })
        .then((response) => response.json())
        .then((data) => {
            updateInput({ 
                categories: data.categories,
                services: data.services
            });
        })
        .catch((error) => {
            console.error("Error fetching services:", error);
        });
    }

    fetchLocations() {
        const { updateInput } = this.props;

        return fetch(`${wpbApp.root}bookify/v1/get-locations`, {
            method: "GET",
            headers: {
                "Content-Type": "application/json",
                "X-WP-Nonce": wpbApp.nonce,
		        "Locations" : wpbApp.Locations,
            }
        })
        .then((response) => response.json())
        .then((data) => {
            updateInput({ locations: data.locations });
        })
        .catch((error) => {
            console.error("Error fetching services:", error);
        });
    }

    handleSupportLink = () => {
        const { supportLinkUrl } = this.props.state;
        if ( supportLinkUrl ) {
            window.open(supportLinkUrl, "_blank");
        }
    }

    render() {
        const { currentTab } = this.state;
        const { state } = this.props;
        const LocationTab = window.LocationTab;
        const StaffTab = window.StaffTab;
        const HideServices = wpbApp.HideServices;
        const HideLocations = wpbApp.HideLocations;
        const HideStaffs = wpbApp.HideStaffs;
        
        const tabsConfig = [
            {
                id: "location",
                label: wp.hooks.applyFilters( 'bookify_location_tab_label', __('Location', 'bookify')),
                defaultIcon: <img src={Location} alt="Location Icon" style={{height:"30px"}} />,
                visible: LocationTab && HideLocations === "false" && wpbApp.locationsCount > 0,
                component: (props) => ProLocationTab && <ProLocationTab {...props} setTab={this.setTab} />
            },
            {
                id: "service",
                label: wp.hooks.applyFilters( 'bookify_service_tab_label', __('Service', 'bookify')),
                defaultIcon: <img src={Service} alt="Service Icon" style={{height:"30px"}} />,
                visible: HideServices === "false",
                component: (props) => <ServiceTab setTab={this.setTab} />
            },
            {
                id: "staff",
                label: wp.hooks.applyFilters( 'bookify_staff_tab_label', __('Staff', 'bookify')),
                defaultIcon: <img src={Staff} alt="Staff Icon" style={{height:"30px"}} />,
                visible: StaffTab && HideStaffs === "false",
                component: (props) => ProStaffTab && <ProStaffTab setTab={this.setTab} />
            },
            {
                id: "datetime",
                label: wp.hooks.applyFilters( 'bookify_datetime_tab_label', __('Date & Time', 'bookify')),
                defaultIcon: <img src={Date} alt="Date Icon" style={{height:"30px"}} />,
                visible: true,
                component: (props) => <DateAndTimeTabWithStore setTab={this.setTab} />
            },
            {
                id: "userinfo",
                label: wp.hooks.applyFilters( 'bookify_userinfo_tab_label', __('Your Information', 'bookify')),
                defaultIcon: <img src={Info} alt="Info Icon" style={{height:"30px"}} />,
                visible: true,
                component: (props) => <UserInfoTab setTab={this.setTab}/>
            },
            {
                id: "payments",
                label: wp.hooks.applyFilters( 'bookify_payment_tab_label', __('Payments', 'bookify')),
                defaultIcon: <img src={Payment} alt="Payment Icon" style={{height:"30px"}} />,
                visible: true,
                component: (props) => <PaymentsTab setTab={this.setTab} />
            },
            {
                id: "confirmation",
                label: wp.hooks.applyFilters( 'bookify_confirmation_tab_label', __('Confirmation', 'bookify')),
                defaultIcon: <img src={Confirm} alt="Confirm Icon" style={{height:"30px"}} />,
                visible: true,
                component: (props) => <ConfirmationTabWithStore setTab={this.setTab} />
            }
        ];

        const visibleTabs = tabsConfig.filter(tab => tab.visible);
        

        const Tab = styled(BaseTab)`
            font-family: "IBM Plex Sans", sans-serif;
            color: white;
            cursor: pointer;
            font-size: 0.875rem;
            font-weight: 500;
            background-color: transparent;
            width: 100%;
            padding: 8px 12px;
            border: none;
            border-radius: 7px;
            display: flex;
            justify-content: flex-start;
            align-items: center;
            gap: 5px;
            outline: none;

            & > svg {
                padding: 6px;
                background: #4D545A;
                color: #fff;
                border-radius: 100%;
            }

            &.${tabClasses.selected} > svg {
                background: #fff;
                color: #292d32;
            }
        `;

        const TabPanel = styled(BaseTabPanel)`
            width: 100%;
        `;

        const Tabs = styled(BaseTabs)`
            display: flex;
            width: 720px;
        `;

        const TabsList = styled(BaseTabsList)`
            min-width: 200px;
            max-width: 200px;
            height: 566px;
            background-color: #042626;
            display: flex;
            padding: 12px 6px;
            flex-direction: column;
            align-items: center;
            justify-content: space-between;
            align-content: space-between;
            border-top-left-radius: 8px;
            border-bottom-left-radius: 8px;
        `;

        return (
            <ThemeProvider theme={theme}>
                <CssBaseline />
                <Tabs orientation="vertical" value={currentTab} onChange={this.handleChange}>
                    <TabsList>
                        <Box style={{ position: "relative" }} ref={this.tabListRef}>
                            <div className="bookify-tab-indicator" ref={this.indicatorRef}/>
                            {visibleTabs.map((tab, index) => {
                                const isSelected = currentTab === index;

                                return (
                                    <Tab
                                        key={tab.id}
                                        disabled
                                        className={`bookify-nav-tab ${isSelected ? 'bookify-tab-selected' : ''}`}
                                    >
                                        {tab.defaultIcon}
                                        <span style={{
                                            marginLeft: "5px",
                                            lineHeight: "23px",
                                            color: isSelected ? "#FFFFFF" : "#96B8B8"
                                        }}>
                                            {tab.label}
                                        </span>
                                    </Tab>
                                );
                            })}
                        </Box>
                        {state.showFormSupportLink && 
                            <Button variant="wpbkHelpBtn" startIcon={<BuildIcon sx={{width:"17px", height:"17px"}}/>} onClick={this.handleSupportLink}>
                                {state.supportLinkText}
                            </Button>
                        }
                    </TabsList>
                    {visibleTabs.map((tab, index) => (
                        <TabPanel key={tab.id} value={index}>
                            <div className="bookify-tab-panel-animate" key={`${tab.id}-${currentTab}`}>
                                {tab.component && tab.component()}
                            </div>
                        </TabPanel>
                    ))}
                </Tabs>
            </ThemeProvider>
        );
    }
}

export default withBooking([
    "supportLinkText",
    "supportLinkUrl",
    "showFormSupportLink",
])(DefaultFrontendApp);
