"use client";

import {
  Box,
  Button,
  Card,
  CardContent,
  Stack,
  Typography,
  Alert,
  CircularProgress,
  Chip,
  Tabs,
  Tab,
  Select,
  MenuItem,
  FormControl,
  InputLabel,
} from "@mui/material";
import { useState, useMemo, useCallback, useEffect } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { useTranslation } from "react-i18next";
import SearchBox, { Criterion } from "../SearchBox";
import SearchResults, { Column } from "../SearchResults";
import { defaultPagingController } from "../SearchResults/SearchResults";
import { fetchAllShopsClient } from "@/app/api/shop/client";
import type { Shop, ShopAndTruck } from "@/app/api/shop/actions";
import TruckLane from "./TruckLane";

type ShopRow = Shop & { 
  actions?: string;
  truckLanceStatus?: "complete" | "missing" | "no-truck";
};

type SearchQuery = {
  id: string;
  name: string;
  code: string;
};

type SearchParamNames = keyof SearchQuery;

const Shop: React.FC = () => {
  const { t } = useTranslation("common");
  const router = useRouter();
  const searchParams = useSearchParams();
  const [activeTab, setActiveTab] = useState<number>(0);
  const [rows, setRows] = useState<ShopRow[]>([]);
  const [loading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<string | null>(null);
  const [filters, setFilters] = useState<Record<string, string>>({});
  const [statusFilter, setStatusFilter] = useState<string>("all");
  const [pagingController, setPagingController] = useState(defaultPagingController);

  // client-side filtered rows (contains-matching + status filter)
  const filteredRows = useMemo(() => {
    const fKeys = Object.keys(filters || {}).filter((k) => String((filters as any)[k]).trim() !== "");
    let normalized = (rows || []).filter((r) => {
      // apply contains matching for each active filter
      for (const k of fKeys) {
        const v = String((filters as any)[k] ?? "").trim();
        const rv = String((r as any)[k] ?? "").trim();
        // Use exact matching for id field, contains matching for others
        if (k === "id") {
          const numValue = Number(v);
          const rvNum = Number(rv);
          if (!isNaN(numValue) && !isNaN(rvNum)) {
            if (numValue !== rvNum) return false;
          } else {
            if (v !== rv) return false;
          }
        } else {
          if (!rv.toLowerCase().includes(v.toLowerCase())) return false;
        }
      }
      return true;
    });
    
    // Apply status filter
    if (statusFilter !== "all") {
      normalized = normalized.filter((r) => {
        return r.truckLanceStatus === statusFilter;
      });
    }
    
    return normalized;
  }, [rows, filters, statusFilter]);

  // Check if a shop has missing truckLanceCode data
  const checkTruckLanceStatus = useCallback((shopTrucks: ShopAndTruck[]): "complete" | "missing" | "no-truck" => {
    if (!shopTrucks || shopTrucks.length === 0) {
      return "no-truck";
    }

    // Check if shop has any actual truck lanes (not just null entries from LEFT JOIN)
    // A shop with no trucks will have entries with null truckLanceCode
    const hasAnyTruckLane = shopTrucks.some((truck) => {
      const truckLanceCode = (truck as any).truckLanceCode;
      return truckLanceCode != null && String(truckLanceCode).trim() !== "";
    });

    if (!hasAnyTruckLane) {
      return "no-truck";
    }

    // Check each truckLanceCode entry for missing data
    for (const truck of shopTrucks) {
      // Skip entries without truckLanceCode (they're from LEFT JOIN when no trucks exist)
      const truckLanceCode = (truck as any).truckLanceCode;
      if (!truckLanceCode || String(truckLanceCode).trim() === "") {
        continue; // Skip this entry, it's not a real truck lane
      }
      
      // Check truckLanceCode: must exist and not be empty (already validated above)
      const hasTruckLanceCode = truckLanceCode != null && String(truckLanceCode).trim() !== "";
      
      // Check departureTime: must exist and not be empty
      // Can be array format [hours, minutes] or string format
      const departureTime = (truck as any).departureTime || (truck as any).DepartureTime;
      let hasDepartureTime = false;
      if (departureTime != null) {
        if (Array.isArray(departureTime) && departureTime.length >= 2) {
          // Array format [hours, minutes]
          hasDepartureTime = true;
        } else {
          // String format
          const timeStr = String(departureTime).trim();
          hasDepartureTime = timeStr !== "" && timeStr !== "-";
        }
      }
      
      // Check loadingSequence: must exist and not be 0
      const loadingSeq = (truck as any).loadingSequence || (truck as any).LoadingSequence;
      const loadingSeqNum = loadingSeq != null && loadingSeq !== undefined ? Number(loadingSeq) : null;
      const hasLoadingSequence = loadingSeqNum !== null && !isNaN(loadingSeqNum) && loadingSeqNum !== 0;
      
      // Check districtReference: must exist and not be 0
      const districtRef = (truck as any).districtReference;
      const districtRefNum = districtRef != null && districtRef !== undefined ? Number(districtRef) : null;
      const hasDistrictReference = districtRefNum !== null && !isNaN(districtRefNum) && districtRefNum !== 0;
      
      // Check storeId: must exist and not be 0 (can be string "2F"/"4F" or number)
      // Actual field name in JSON is store_id (underscore, lowercase)
      const storeId = (truck as any).store_id || (truck as any).storeId || (truck as any).Store_id;
      let storeIdValid = false;
      if (storeId != null && storeId !== undefined && storeId !== "") {
        const storeIdStr = String(storeId).trim();
        // If it's "2F" or "4F", it's valid (not 0)
        if (storeIdStr === "2F" || storeIdStr === "4F") {
          storeIdValid = true;
        } else {
          const storeIdNum = Number(storeId);
          // If it's a valid number and not 0, it's valid
          if (!isNaN(storeIdNum) && storeIdNum !== 0) {
            storeIdValid = true;
          }
        }
      }

      // If any required field is missing or equals 0, return "missing"
      if (!hasTruckLanceCode || !hasDepartureTime || !hasLoadingSequence || !hasDistrictReference || !storeIdValid) {
        return "missing";
      }
    }

    return "complete";
  }, []);

  const fetchAllShops = async (params?: Record<string, string>) => {
    setLoading(true);
    setError(null);
    try {
      const data = await fetchAllShopsClient(params) as ShopAndTruck[];
      console.log("Fetched shops data:", data);
      
      // Group data by shop ID (one shop can have multiple TruckLanceCode entries)
      const shopMap = new Map<number, { shop: Shop; trucks: ShopAndTruck[] }>();
      
      (data || []).forEach((item: ShopAndTruck) => {
        const shopId = item.id;
        if (!shopMap.has(shopId)) {
          shopMap.set(shopId, {
            shop: {
              id: item.id,
              name: item.name,
              code: item.code,
              addr3: item.addr3 ?? "",
            },
            trucks: [],
          });
        }
        shopMap.get(shopId)!.trucks.push(item);
      });

      // Convert to ShopRow array with truckLanceStatus
      const mapped: ShopRow[] = Array.from(shopMap.values()).map(({ shop, trucks }) => ({
        ...shop,
        truckLanceStatus: checkTruckLanceStatus(trucks),
      }));

      setRows(mapped);
    } catch (err: any) {
      console.error("Failed to load shops:", err);
      setError(err?.message ?? String(err));
    } finally {
      setLoading(false);
    }
  };

  // SearchBox onSearch will call this
  const handleSearch = (inputs: Record<string, string>) => {
    setFilters(inputs);
    const params: Record<string, string> = {};
    Object.entries(inputs || {}).forEach(([k, v]) => {
      if (v != null && String(v).trim() !== "") params[k] = String(v).trim();
    });
    if (Object.keys(params).length === 0) fetchAllShops();
    else fetchAllShops(params);
  };

  const handleViewDetail = useCallback(
    (shop: ShopRow) => {
      router.push(`/settings/shop/detail?id=${shop.id}`);
    },
    [router]
  );

  const criteria: Criterion<SearchParamNames>[] = [
    { type: "text", label: t("id"), paramName: "id" },
    { type: "text", label: t("code"), paramName: "code" },
    { type: "text", label: t("Shop Name"), paramName: "name" },
  ];

  const columns: Column<ShopRow>[] = [
    {
      name: "id",
      label: t("id"),
      type: "integer",
      sx: { width: "100px", minWidth: "100px", maxWidth: "100px" },
      renderCell: (item) => String(item.id ?? ""),
    },
    {
      name: "code",
      label: t("Code"),
      sx: { width: "150px", minWidth: "150px", maxWidth: "150px" },
      renderCell: (item) => String(item.code ?? ""),
    },
    {
      name: "name",
      label: t("Name"),
      sx: { width: "200px", minWidth: "200px", maxWidth: "200px" },
      renderCell: (item) => String(item.name ?? ""),
    },
    {
      name: "addr3",
      label: t("Addr3"),
      sx: { width: "200px", minWidth: "200px", maxWidth: "200px" },
      renderCell: (item) => String((item as any).addr3 ?? ""),
    },
    {
      name: "truckLanceStatus",
      label: t("TruckLance Status"),
      align: "center",
      headerAlign: "center",
      sx: { width: "150px", minWidth: "150px", maxWidth: "150px" },
      renderCell: (item) => {
        const status = item.truckLanceStatus;
        if (status === "complete") {
          return <Chip label={t("Complete")} color="success" size="small" />;
        } else if (status === "missing") {
          return <Chip label={t("Missing Data")} color="warning" size="small" />;
        } else {
          return <Chip label={t("No TruckLance")} color="error" size="small" />;
        }
      },
    },
    {
      name: "actions",
      label: t("Actions"),
      align: "right",
      headerAlign: "right",
      sx: { width: "150px", minWidth: "150px", maxWidth: "150px" },
      renderCell: (item) => (
        <Button 
          size="small" 
          variant="outlined" 
          onClick={() => handleViewDetail(item)}
        >
          {t("View Detail")}
        </Button>
      ),
    },
  ];

  // Initialize activeTab from URL parameter
  useEffect(() => {
    const tabParam = searchParams.get("tab");
    if (tabParam !== null) {
      const tabIndex = parseInt(tabParam, 10);
      if (!isNaN(tabIndex) && (tabIndex === 0 || tabIndex === 1)) {
        setActiveTab(tabIndex);
      }
    }
  }, [searchParams]);

  const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
    setActiveTab(newValue);
    // Update URL to reflect the selected tab
    const url = new URL(window.location.href);
    url.searchParams.set("tab", String(newValue));
    router.push(url.pathname + url.search);
  };

  return (
    <Box>
      {/* Header section with title */}
      <Box sx={{ 
        p: 2,
        borderBottom: '1px solid #e0e0e0'
      }}>
        <Typography variant="h4">
          店鋪路線管理
        </Typography>
      </Box>

      {/* Tabs section */}
      <Box sx={{ 
        borderBottom: '1px solid #e0e0e0'
      }}>
        <Tabs 
          value={activeTab} 
          onChange={handleTabChange}
        >
          <Tab label={t("Shop")} />
          <Tab label={t("Truck Lane")} />
        </Tabs>
      </Box>

      {/* Content section */}
      <Box sx={{ p: 2 }}>
        {activeTab === 0 && (
          <>
            <Card sx={{ mb: 2 }}>
              <CardContent>
                <SearchBox
                  criteria={criteria as Criterion<string>[]}
                  onSearch={handleSearch}
                  onReset={() => {
                    setRows([]);
                    setFilters({});
                  }}
                />
              </CardContent>
            </Card>

            <Card>
              <CardContent>
                <Stack direction="row" justifyContent="space-between" alignItems="center" sx={{ mb: 2 }}>
                  <Typography variant="h6">{t("Shop")}</Typography>
                  <FormControl size="small" sx={{ minWidth: 200 }}>
                    <InputLabel>{t("Filter by Status")}</InputLabel>
                    <Select
                      value={statusFilter}
                      label={t("Filter by Status")}
                      onChange={(e) => setStatusFilter(e.target.value)}
                    >
                      <MenuItem value="all">{t("All")}</MenuItem>
                      <MenuItem value="complete">{t("Complete")}</MenuItem>
                      <MenuItem value="missing">{t("Missing Data")}</MenuItem>
                      <MenuItem value="no-truck">{t("No TruckLance")}</MenuItem>
                    </Select>
                  </FormControl>
                </Stack>
                {error && (
                  <Alert severity="error" sx={{ mb: 2 }}>
                    {error}
                  </Alert>
                )}

                {loading ? (
                  <Box sx={{ display: "flex", justifyContent: "center", p: 4 }}>
                    <CircularProgress />
                  </Box>
                ) : (
                  <SearchResults
                    items={filteredRows}
                    columns={columns}
                    pagingController={pagingController}
                    setPagingController={setPagingController}
                  />
                )}
              </CardContent>
            </Card>
          </>
        )}

        {activeTab === 1 && (
          <TruckLane />
        )}
      </Box>
    </Box>
  );
};

export default Shop;