"use client";

import {
  Box,
  Button,
  Card,
  CardContent,
  Stack,
  Typography,
  Alert,
  CircularProgress,
  Chip,
} from "@mui/material";
import { useState, useMemo, useCallback, useEffect } from "react";
import { useRouter } from "next/navigation";
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";

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 router = useRouter();
  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 [pagingController, setPagingController] = useState(defaultPagingController);

  // client-side filtered rows (contains-matching)
  const filteredRows = useMemo(() => {
    const fKeys = Object.keys(filters || {}).filter((k) => String((filters as any)[k]).trim() !== "");
    const 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;
    });
    return normalized;
  }, [rows, filters]);

  // 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 each truckLanceCode entry for missing data
    for (const truck of shopTrucks) {
      const hasTruckLanceCode = truck.truckLanceCode && String(truck.truckLanceCode).trim() !== "";
      const hasDepartureTime = truck.DepartureTime && String(truck.DepartureTime).trim() !== "";
      const hasLoadingSequence = truck.LoadingSequence !== null && truck.LoadingSequence !== undefined;
      const hasDistrictReference = truck.districtReference !== null && truck.districtReference !== undefined;
      const hasStoreId = truck.Store_id !== null && truck.Store_id !== undefined;

      // If any required field is missing, return "missing"
      if (!hasTruckLanceCode || !hasDepartureTime || !hasLoadingSequence || !hasDistrictReference || !hasStoreId) {
        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: "id", paramName: "id" },
    { type: "text", label: "code", paramName: "code" },
    { type: "text", label: "name", paramName: "name" },
  ];

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

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

  return (
    <Box>
      <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">Shop</Typography>
          </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>
    </Box>
  );
};

export default Shop;