import { Id, Product, product_type_t } from "@/lib/product";
import { useState } from "react";
import {
  Button,
  FlatList,
  Pressable,
  StyleSheet,
  Text,
  TextInput,
  Touchable,
  TouchableHighlight,
  View,
} from "react-native";
import { ProductAttributeEditor } from "./ProductAttributeEditor";
import { Dropdown } from "react-native-element-dropdown";
import { Ionicons } from "@expo/vector-icons";
import { Length } from "convert";
import { dimensions_t } from "@/lib/dimensions";

export type ProductAddedFunc = () => any;
export type ProductDeletedFunc = (product_id: Id) => any;
export type AttributeAddedFunc = (product_id: Id) => any;
export type AttributeKeyUpdatedFunc = (
  product_id: Id,
  oldKey: string,
  newKey: string
) => any;
export type AttributeUpdatedFunc = (
  product_id: Id,
  attribute: string,
  value: string
) => any;
export type AttributeDeletedFunc = (product_id: Id, attribute: string) => any;
export type PriceUpdatedFunc = (product_id: Id, price: number) => any;
export type DimensionUpdatedFunc = (
  product_id: Id,
  dimension: dimensions_t
) => any;
export type ProductTypeChangedFunc = (
  product_id: Id,
  product_type: product_type_t
) => any;

export type ProductEditorItemProps = {
  product: Product;
  onProductAdded?: ProductAddedFunc;
  onProductDeleted?: ProductDeletedFunc;
  onAttributeAdded?: AttributeAddedFunc;
  onAttributeKeyChanged?: AttributeKeyUpdatedFunc;
  onAttributeUpdated?: AttributeUpdatedFunc;
  onAttributeDeleted?: AttributeDeletedFunc;
  onPriceUpdated?: PriceUpdatedFunc;
  onDimensionsUpdated?: DimensionUpdatedFunc;
  onProductTypeChanged?: ProductTypeChangedFunc;
};

export const ProductEditorItem = (props: ProductEditorItemProps) => {
  const [showAttributes, setShowAttributes] = useState(false);
  const product = props.product;

  function onProductTypeChange(id: Id, newProductType: product_type_t) {
    props.onProductTypeChanged &&
      props.onProductTypeChanged(product.id as Id, newProductType);
  }

  function onAttributeChanged(key: string, newValue: string) {
    props.onAttributeUpdated &&
      props.onAttributeUpdated(product.id as Id, key, newValue);
  }

  function onAttributeKeyChanged(oldKey: string, newKey: string) {
    props.onAttributeKeyChanged &&
      props.onAttributeKeyChanged(product.id as Id, oldKey, newKey);
  }

  function onAttributeDelete(key: string) {
    props.onAttributeDeleted && props.onAttributeDeleted(product.id as Id, key);
  }

  function onPricePerUnitChange(pricePerUnit: string) {
    props.onPriceUpdated &&
      props.onPriceUpdated(
        product.id as Id,
        parseFloat(pricePerUnit) || parseInt(pricePerUnit)
      );
  }

  function onUnitsChanged(newUnits: Length) {
    props.onDimensionsUpdated &&
      props.onDimensionsUpdated(product.id as Id, {
        ...(product.dimensions as dimensions_t),
        u: newUnits,
      });
  }

  function onChangeLength(len: string) {
    const l = parseFloat(len) || parseInt(len);
    props.onDimensionsUpdated &&
      props.onDimensionsUpdated(product.id as Id, {
        ...(product.dimensions as dimensions_t),
        l,
      });
  }

  function onChangeWidth(width: string) {
    const w = width.length == 0 ? null : parseFloat(width) || parseInt(width);
    props.onDimensionsUpdated &&
      props.onDimensionsUpdated(product.id as Id, {
        ...(product.dimensions as dimensions_t),
        ...(w ? { w } : {}),
      });
  }

  function onDeleteProduct() {
    props.onProductDeleted && props.onProductDeleted(product.id as Id);
  }

  const length = new String(
    product.dimensions.l || product.dimensions.l || "0"
  ) as string;
  const width = new String(product.dimensions.w || "") as string;
  const dimension = product.dimensions.u || product.dimensions.u || "foot";

  return (
    <View>
      <View style={styles.productListHeader}>
        <TouchableHighlight
          onPress={() => setShowAttributes(!showAttributes)}
          aria-label="Product Item"
          style={styles.productItemName}
        >
          {product.attributes && (
            <Text style={styles.productNameText}>
              {product.attributes.name || `Product ${product.id}`}
            </Text>
          )}
        </TouchableHighlight>
        <Pressable
          onPress={() => onDeleteProduct()}
          aria-label="delete product"
          style={styles.deleteProductHighlight}
        >
          <Ionicons style={styles.deleteProductButton} name="trash-outline" />
        </Pressable>
      </View>
      {showAttributes && (
        <View style={styles.detailsWrapper}>
          <View style={styles.priceSpecWrapper}>
            <Text style={styles.priceLabel}>$</Text>
            <TextInput
              inputMode="decimal"
              defaultValue={new String(product.pricePerUnit).valueOf()}
              aria-label="price per unit"
              onChangeText={onPricePerUnitChange}
              style={styles.priceInput}
            />
            <Text style={styles.per}>per</Text>
            <Dropdown
              data={[
                { label: "feet", value: "ft" },
                { label: "inches", value: "in" },
              ]}
              style={styles.unitsSelect}
              mode="modal"
              labelField="label"
              valueField="value"
              value={product.dimensions.u || "ft"}
              onChange={(item) => onUnitsChanged(item.value as Length)}
            />
            <TextInput
              inputMode="decimal"
              defaultValue={length}
              onChangeText={onChangeLength}
              style={styles.lengthInput}
              aria-label="length"
            />
            <Text style={{ flex: 1 }}>x</Text>
            <TextInput
              inputMode="decimal"
              defaultValue={width}
              onChangeText={onChangeWidth}
              style={styles.widthInput}
              aria-label="width"
            />
          </View>
          <Button
            title="+ Add Attribute"
            onPress={() =>
              props.onAttributeAdded && props.onAttributeAdded(product.id as Id)
            }
          />
          {product.attributes && (
            <FlatList
              style={styles.productAttributesList}
              data={Object.entries(product.attributes)}
              renderItem={({ item }) => (
                <ProductAttributeEditor
                  onProductTypeChange={onProductTypeChange}
                  attributeKey={item[0] || "some key"}
                  attributeValue={item[1]}
                  onChangeAttributeKey={onAttributeKeyChanged}
                  onChangeAttribute={onAttributeChanged}
                  onDelete={onAttributeDelete}
                />
              )}
              keyExtractor={(item, i) => `${product.id}-${i}`}
            />
          )}
        </View>
      )}
    </View>
  );
};

const styles = StyleSheet.create({
  deleteProductHighlight: {
    padding: 5,
    borderWidth: 1,
  },
  deleteProductButton: {
    fontSize: 20,
  },
  detailsWrapper: {},
  priceSpecWrapper: {
    flexDirection: "row",
  },
  priceLabel: {},
  priceInput: {
    flex: 1,
    borderWidth: 2,
    borderColor: "lightgrey",
    borderStyle: "solid",
  },
  per: {
    padding: 5,
  },
  unitsLabel: {},
  unitsSelect: {
    flex: 1,
    padding: 5,
  },
  lengthInput: {
    flex: 1,
    borderWidth: 2,
    borderColor: "lightgrey",
    borderStyle: "solid",
  },
  widthInput: {
    flex: 1,
    borderWidth: 2,
    borderColor: "lightgrey",
    borderStyle: "solid",
  },
  productListHeader: {
    flexDirection: "row",
    padding: 5,
  },
  productNameText: {
    paddingLeft: 10,
    paddingRight: 10,
  },
  productItemName: {
    flex: 1,
    backgroundColor: "lightgrey",
    padding: 4,
    margin: 4,
  },
  productAttributesList: {
    margin: 10,
    padding: 10,
    borderWidth: 1,
    borderStyle: "solid",
    borderColor: "black",
  },
});
