import React, { useState, useEffect } from "react";
import axios from "axios";
import {
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  Switch,
  Typography,
  Paper,
  Snackbar,
  Alert,
  Box,
  CircularProgress,
  useMediaQuery,
  useTheme,
  Tab,
  Tabs,
  Card,
  CardContent,
} from "@mui/material";

interface Service {
  id: string;
  network: string;
  planType?: string;
  airtimeType?: string;
  available: boolean;
}

interface ServiceCategory {
  data: Service[];
  airtime: Service[];
}

interface FullServiceData {
  data: any[];
  airtime: any[];
}

const ServiceAvailability: React.FC = () => {
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
  const [loading, setLoading] = useState(true);
  const [fetching, setFetching] = useState(false);
  const [activeTab, setActiveTab] = useState(0);
  const [snackbar, setSnackbar] = useState({
    open: false,
    message: "",
    severity: "success" as "success" | "error" | "warning" | "info",
  });
  const [services, setServices] = useState<ServiceCategory>({
    data: [],
    airtime: [],
  });
  const [fullData, setFullData] = useState<FullServiceData>({
    data: [],
    airtime: [],
  });

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

  const fetchAllServices = async () => {
    setLoading(true);
    try {
      const [dataRes, airtimeRes] = await Promise.all([
        axios.get("/api/adminapi/data"),
        axios.get("/api/adminapi/airtime"),
      ]);

      // Store full data for bulk updates
      const dataPlans = Array.isArray(dataRes.data)
        ? dataRes.data
        : dataRes.data.data || [];
      const airtimePlans = airtimeRes.data.data || [];

      setFullData({
        data: dataPlans,
        airtime: airtimePlans,
      });

      // Get unique combinations for display
      const uniqueDataPlans = getUniqueServices(dataPlans, "planType");
      const uniqueAirtimePlans = getUniqueServices(airtimePlans, "airtimeType");

      setServices({
        data: uniqueDataPlans,
        airtime: uniqueAirtimePlans,
      });
    } catch (error) {
      console.error("Error fetching services:", error);
      setSnackbar({
        open: true,
        message: "Failed to load services. Please try again later.",
        severity: "error",
      });
    } finally {
      setLoading(false);
    }
  };

  // Helper function to get unique services by type
  const getUniqueServices = (services: any[], typeKey: string): Service[] => {
    const uniqueMap = new Map<string, Service>();

    services.forEach((service) => {
      const key = `${service.network}-${service[typeKey]}`;
      if (!uniqueMap.has(key)) {
        uniqueMap.set(key, {
          id: service._id,
          network: service.network,
          [typeKey]: service[typeKey],
          available: service.available,
        });
      }
    });

    return Array.from(uniqueMap.values());
  };

  const toggleAvailability = async (
    type: keyof ServiceCategory,
    service: Service
  ) => {
    setFetching(true);
    try {
      // Find all matching services in full data
      const matchingServices = fullData[type].filter(
        (item) =>
          item.network === service.network &&
          (type === "data"
            ? item.planType === service.planType
            : item.airtimeType === service.airtimeType)
      );

      if (matchingServices.length === 0) {
        throw new Error("No matching services found");
      }

      // Get all IDs to update
      const ids = matchingServices.map((item) => item._id);
      const newAvailability = !service.available;

      // Call bulk update endpoint
      await axios.put(`/api/adminapi/${type}/bulk-availability`, {
        ids,
        available: newAvailability,
      });

      // Update both full data and display data
      setFullData((prev) => ({
        ...prev,
        [type]: prev[type].map((item) =>
          ids.includes(item._id)
            ? { ...item, available: newAvailability }
            : item
        ),
      }));

      setServices((prev) => ({
        ...prev,
        [type]: prev[type].map((item) =>
          item.network === service.network &&
          (type === "data"
            ? item.planType === service.planType
            : item.airtimeType === service.airtimeType)
            ? { ...item, available: newAvailability }
            : item
        ),
      }));

      setSnackbar({
        open: true,
        message: `${matchingServices.length} ${type} plans updated successfully!`,
        severity: "success",
      });
    } catch (error) {
      console.error("Error updating availability:", error);
      setSnackbar({
        open: true,
        message: "Failed to update availability",
        severity: "error",
      });
    } finally {
      setFetching(false);
    }
  };

  const handleSnackbarClose = () => {
    setSnackbar({ ...snackbar, open: false });
  };

  const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
    setActiveTab(newValue);
  };

  const renderTable = (type: keyof ServiceCategory) => {
    const items = services[type];
    const headers = getHeaders(type);

    return (
      <Card sx={{ mt: 2 }}>
        <CardContent>
          <TableContainer>
            <Table size={isMobile ? "small" : "medium"}>
              <TableHead>
                <TableRow>
                  {headers.map((header) => (
                    <TableCell key={header}>{header}</TableCell>
                  ))}
                  <TableCell align="center">Status</TableCell>
                  <TableCell align="center">Count</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {items.length > 0 ? (
                  items.map((item) => {
                    const count = fullData[type].filter(
                      (fullItem) =>
                        fullItem.network === item.network &&
                        (type === "data"
                          ? fullItem.planType === item.planType
                          : fullItem.airtimeType === item.airtimeType)
                    ).length;

                    return (
                      <TableRow
                        key={`${item.network}-${
                          type === "data" ? item.planType : item.airtimeType
                        }`}
                        hover
                      >
                        {type === "data" && (
                          <>
                            <TableCell>{item.network}</TableCell>
                            <TableCell>{item.planType}</TableCell>
                          </>
                        )}
                        {type === "airtime" && (
                          <>
                            <TableCell>{item.network}</TableCell>
                            <TableCell>{item.airtimeType}</TableCell>
                          </>
                        )}
                        <TableCell align="center">
                          <Switch
                            checked={item.available}
                            onChange={() => toggleAvailability(type, item)}
                            color="primary"
                            disabled={fetching}
                          />
                        </TableCell>
                        <TableCell align="center">{count}</TableCell>
                      </TableRow>
                    );
                  })
                ) : (
                  <TableRow>
                    <TableCell colSpan={headers.length + 2} align="center">
                      {loading ? "Loading..." : "No services found"}
                    </TableCell>
                  </TableRow>
                )}
              </TableBody>
            </Table>
          </TableContainer>
        </CardContent>
      </Card>
    );
  };

  const getHeaders = (type: keyof ServiceCategory) => {
    switch (type) {
      case "data":
        return ["Network", "Plan Type"];
      case "airtime":
        return ["Network", "Airtime Type"];
      default:
        return [];
    }
  };

  const tabLabels = ["Data Plans", "Airtime"];

  return (
    <Box sx={{ p: isMobile ? 1 : 3 }}>
      <Typography variant="h5" gutterBottom sx={{ mb: 3 }}>
        Service Availability Management
      </Typography>

      <Snackbar
        open={snackbar.open}
        autoHideDuration={4000}
        onClose={handleSnackbarClose}
        anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
      >
        <Alert
          onClose={handleSnackbarClose}
          severity={snackbar.severity}
          variant="filled"
        >
          {snackbar.message}
        </Alert>
      </Snackbar>

      {loading ? (
        <Box sx={{ display: "flex", justifyContent: "center", mt: 4 }}>
          <CircularProgress />
        </Box>
      ) : (
        <>
          <Tabs
            value={activeTab}
            onChange={handleTabChange}
            variant={isMobile ? "scrollable" : "standard"}
            scrollButtons="auto"
            allowScrollButtonsMobile
            sx={{ mb: 2 }}
          >
            {tabLabels.map((label, index) => (
              <Tab key={index} label={label} />
            ))}
          </Tabs>

          {activeTab === 0 && renderTable("data")}
          {activeTab === 1 && renderTable("airtime")}
        </>
      )}
    </Box>
  );
};

export default ServiceAvailability;
