'use client';

import React, { useCallback, useEffect, useState } from 'react';
import { Button } from '@alga-psa/ui/components/Button';
import { Badge } from '@alga-psa/ui/components/Badge';
import { Label } from '@alga-psa/ui/components/Label';
import AsyncSearchableSelect, { type SelectOption } from '@alga-psa/ui/components/AsyncSearchableSelect';
import CustomSelect from '@alga-psa/ui/components/CustomSelect';
import { Input } from '@alga-psa/ui/components/Input';
import { withDataAutomationId } from '@alga-psa/ui/ui-reflection/withDataAutomationId';
import { ReflectionContainer } from '@alga-psa/ui/ui-reflection/ReflectionContainer';
import { Package, Plus, Loader2, Trash2 } from 'lucide-react';
import { toast } from 'react-hot-toast';
import { handleError } from '@alga-psa/ui/lib/errorHandling';
import type { IProjectMaterial, IServicePrice } from '@alga-psa/types';
import {
  listProjectMaterials,
  searchServiceCatalogForPicker,
  addProjectMaterial,
  getServicePrices,
  deleteProjectMaterial,
} from '../actions/materialCatalogActions';
import { formatCurrencyFromMinorUnits } from '@alga-psa/core';
import { useTranslation } from 'react-i18next';

interface ProjectMaterialsDrawerProps {
  id?: string;
  projectId: string;
  clientId?: string | null;
}

export default function ProjectMaterialsDrawer({
  id = 'project-materials-drawer',
  projectId,
  clientId,
}: ProjectMaterialsDrawerProps) {
  const { t } = useTranslation(['features/projects', 'common']);
  const materialsT = useCallback((key: string, fallback: string, options?: Record<string, unknown>) =>
    t(`materials.${key}`, { defaultValue: fallback, ...(options ?? {}) }), [t]);
  const [showAddForm, setShowAddForm] = useState(false);
  const [materials, setMaterials] = useState<IProjectMaterial[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [selectedProductId, setSelectedProductId] = useState<string>('');
  const [selectedProductLabel, setSelectedProductLabel] = useState<string>('');
  const [productPrices, setProductPrices] = useState<IServicePrice[]>([]);
  const [selectedCurrency, setSelectedCurrency] = useState<string>('');
  const [isLoadingPrices, setIsLoadingPrices] = useState(false);
  const [quantity, setQuantity] = useState<number>(1);
  const [description, setDescription] = useState<string>('');
  const [isAdding, setIsAdding] = useState(false);
  const [deletingId, setDeletingId] = useState<string | null>(null);

  const loadMaterials = useCallback(async () => {
    if (!projectId) return;
    setIsLoading(true);
    try {
      const data = await listProjectMaterials(projectId);
      setMaterials(data);
    } catch (error) {
      handleError(error, materialsT('loadFailed', 'Failed to load materials'));
    } finally {
      setIsLoading(false);
    }
  }, [projectId, materialsT]);

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

  // Server-side search for products via AsyncSearchableSelect
  const loadProductOptions = useCallback(
    async ({ search, page, limit }: { search: string; page: number; limit: number }) => {
      const result = await searchServiceCatalogForPicker({
        search,
        page,
        limit,
        item_kinds: ['product'],
        is_active: true,
      });

      const options: SelectOption[] = result.items.map((item) => ({
        value: item.service_id,
        label: item.sku ? `${item.service_name} (${item.sku})` : item.service_name,
      }));

      return { options, total: result.totalCount };
    },
    []
  );

  useEffect(() => {
    if (!selectedProductId) {
      setProductPrices([]);
      setSelectedCurrency('');
      return;
    }

    const loadPrices = async () => {
      setIsLoadingPrices(true);
      try {
        const prices = await getServicePrices(selectedProductId);
        setProductPrices(prices);
        if (prices.length > 0) {
          setSelectedCurrency(prices[0].currency_code);
        } else {
          setSelectedCurrency('');
        }
      } catch (error) {
        console.error('Error loading product prices:', error);
        setProductPrices([]);
        setSelectedCurrency('');
      } finally {
        setIsLoadingPrices(false);
      }
    };

    loadPrices();
  }, [selectedProductId]);

  const calculateTotal = (material: IProjectMaterial) => material.quantity * material.rate;

  const unbilledByCurrency = materials
    .filter((material) => !material.is_billed)
    .reduce((acc, material) => {
      const currency = material.currency_code || 'USD';
      if (!acc[currency]) acc[currency] = 0;
      acc[currency] += calculateTotal(material);
      return acc;
    }, {} as Record<string, number>);

  const selectedPrice = productPrices.find((price) => price.currency_code === selectedCurrency);

  const resetAddForm = () => {
    setShowAddForm(false);
    setSelectedProductId('');
    setSelectedProductLabel('');
    setProductPrices([]);
    setSelectedCurrency('');
    setQuantity(1);
    setDescription('');
  };

  const handleAddMaterial = async () => {
    if (!clientId || !selectedProductId) {
      toast.error(materialsT('selectProductError', 'Please select a product'));
      return;
    }

    if (!selectedPrice) {
      toast.error(materialsT('selectCurrencyError', 'Please select a currency'));
      return;
    }

    if (quantity < 1) {
      toast.error(materialsT('quantityMinError', 'Quantity must be at least 1'));
      return;
    }

    setIsAdding(true);
    try {
      await addProjectMaterial({
        project_id: projectId,
        client_id: clientId,
        service_id: selectedProductId,
        quantity,
        rate: selectedPrice.rate,
        currency_code: selectedPrice.currency_code,
        description: description.trim() || null,
      });

      toast.success(materialsT('addedSuccess', 'Material added'));
      resetAddForm();
      await loadMaterials();
    } catch (error) {
      handleError(error, materialsT('addFailed', 'Failed to add material'));
    } finally {
      setIsAdding(false);
    }
  };

  const handleDeleteMaterial = async (materialId: string) => {
    setDeletingId(materialId);
    // Optimistically remove from UI
    const previousMaterials = materials;
    setMaterials(prev => prev.filter(m => m.project_material_id !== materialId));
    try {
      await deleteProjectMaterial(materialId);
      toast.success(materialsT('removedSuccess', 'Material removed'));
    } catch (error) {
      // Revert on failure
      setMaterials(previousMaterials);
      handleError(error, materialsT('removeFailed', 'Failed to remove material'));
    } finally {
      setDeletingId(null);
    }
  };

  return (
    <ReflectionContainer id={id} label={materialsT('title', 'Project Materials')}>
      <div {...withDataAutomationId({ id })} className="space-y-4">
        <div className="flex items-center justify-between">
          <h2 className="text-lg font-semibold flex items-center gap-2">
            <Package className="w-5 h-5" />
            {materialsT('title', 'Project Materials')}
          </h2>
          {clientId && !showAddForm && (
            <Button
              {...withDataAutomationId({ id: `${id}-add-btn` })}
              variant="outline"
              size="sm"
              onClick={() => setShowAddForm(true)}
            >
              <Plus className="w-4 h-4 mr-1" />
              {t('common:actions.add', 'Add')}
            </Button>
          )}
        </div>

        {showAddForm && clientId && (
          <div className="border rounded-md p-4 space-y-4 bg-gray-50">
            <div className="space-y-2">
              <Label htmlFor="project-materials-product-select">{materialsT('product', 'Product')}</Label>
              <AsyncSearchableSelect
                id="project-materials-product-select"
                value={selectedProductId}
                selectedLabel={selectedProductLabel}
                onChange={(value, option) => {
                  setSelectedProductId(value);
                  setSelectedProductLabel(option?.label ?? '');
                  setSelectedCurrency('');
                }}
                loadOptions={loadProductOptions}
                limit={10}
                debounceMs={300}
                placeholder={materialsT('selectProductPlaceholder', 'Select a product...')}
                searchPlaceholder={materialsT('searchProductsPlaceholder', 'Search products...')}
                emptyMessage={materialsT('noProductsFound', 'No products found')}
                dropdownMode="overlay"
                maxListHeight="200px"
                showMoreIndicator
              />
            </div>

            {selectedProductId && (
              <div className="space-y-2">
                <Label htmlFor="project-materials-currency-select">{materialsT('price', 'Price')}</Label>
                {isLoadingPrices ? (
                  <div className="flex items-center text-sm text-gray-500">
                    <Loader2 className="w-4 h-4 mr-2 animate-spin" />
                    {materialsT('loadingPrices', 'Loading prices...')}
                  </div>
                ) : productPrices.length === 0 ? (
                  <div className="text-sm text-amber-600">
                    {materialsT('noPricesConfigured', 'No prices configured for this product')}
                  </div>
                ) : productPrices.length === 1 ? (
                  <div className="h-10 px-3 py-2 bg-white border rounded-md text-gray-700 flex items-center">
                    {formatCurrencyFromMinorUnits(
                      productPrices[0].rate,
                      'en-US',
                      productPrices[0].currency_code
                    )}
                  </div>
                ) : (
                  <CustomSelect
                    id="project-materials-currency-select"
                    options={productPrices.map((price) => ({
                      value: price.currency_code,
                      label: `${price.currency_code} - ${formatCurrencyFromMinorUnits(price.rate, 'en-US', price.currency_code)}`,
                    }))}
                    value={selectedCurrency}
                    onValueChange={setSelectedCurrency}
                    placeholder={materialsT('selectCurrencyPlaceholder', 'Select currency...')}
                  />
                )}
              </div>
            )}

            <div className="grid grid-cols-2 gap-4">
              <div className="space-y-2">
                <Label htmlFor="project-materials-quantity">{materialsT('quantity', 'Quantity')}</Label>
                <Input
                  {...withDataAutomationId({ id: `${id}-quantity` })}
                  id="project-materials-quantity"
                  type="number"
                  min={1}
                  value={quantity}
                  onChange={(event) => setQuantity(Math.max(1, parseInt(event.target.value) || 1))}
                />
              </div>
              <div className="space-y-2">
                <Label>{materialsT('total', 'Total')}</Label>
                <div className="h-10 px-3 py-2 bg-white border rounded-md text-gray-700 flex items-center">
                  {selectedPrice
                    ? formatCurrencyFromMinorUnits(
                        selectedPrice.rate * quantity,
                        'en-US',
                        selectedPrice.currency_code
                      )
                    : '-'}
                </div>
              </div>
            </div>

            <div className="space-y-2">
              <Label htmlFor="project-materials-description">{materialsT('descriptionOptional', 'Description (optional)')}</Label>
              <Input
                {...withDataAutomationId({ id: `${id}-description` })}
                id="project-materials-description"
                value={description}
                onChange={(event) => setDescription(event.target.value)}
                placeholder={materialsT('notesPlaceholder', 'Additional notes...')}
              />
            </div>

            <div className="flex justify-end space-x-2">
              <Button
                {...withDataAutomationId({ id: `${id}-cancel-add-btn` })}
                variant="outline"
                size="sm"
                onClick={resetAddForm}
              >
                {t('common:actions.cancel', 'Cancel')}
              </Button>
              <Button
                {...withDataAutomationId({ id: `${id}-save-add-btn` })}
                size="sm"
                onClick={handleAddMaterial}
                disabled={isAdding}
              >
                {isAdding ? (
                  <>
                    <Loader2 className="w-4 h-4 mr-1 animate-spin" />
                    {materialsT('adding', 'Adding...')}
                  </>
                ) : (
                  materialsT('addMaterial', 'Add Material')
                )}
              </Button>
            </div>
          </div>
        )}

        {isLoading ? (
          <div className="flex items-center justify-center py-6 text-gray-500">
            <Loader2 className="w-5 h-5 mr-2 animate-spin" />
            {materialsT('loadingMaterials', 'Loading materials...')}
          </div>
        ) : materials.length === 0 ? (
          <div className="text-center py-6 text-gray-500">
            {materialsT('noMaterials', 'No materials added to this project.')}
          </div>
        ) : (
          <div className="space-y-2">
            <div className="overflow-x-auto">
              <table className="w-full text-sm">
                <thead>
                  <tr className="border-b text-left">
                    <th className="pb-2 font-medium">{materialsT('productColumn', 'Product')}</th>
                    <th className="pb-2 font-medium text-right">{materialsT('qtyColumn', 'Qty')}</th>
                    <th className="pb-2 font-medium text-right">{materialsT('rateColumn', 'Rate')}</th>
                    <th className="pb-2 font-medium text-right">{materialsT('totalColumn', 'Total')}</th>
                    <th className="pb-2 font-medium text-center">{materialsT('statusColumn', 'Status')}</th>
                    <th className="pb-2 w-10"></th>
                  </tr>
                </thead>
                <tbody>
                  {materials.map((material) => (
                    <tr key={material.project_material_id} className="border-b last:border-0">
                      <td className="py-2">
                        <div>
                          <span className="font-medium">{material.service_name || materialsT('unknownProduct', 'Unknown Product')}</span>
                          {material.sku && (
                            <span className="text-gray-500 ml-1">({material.sku})</span>
                          )}
                        </div>
                        {material.description && (
                          <div className="text-xs text-gray-500">{material.description}</div>
                        )}
                      </td>
                      <td className="py-2 text-right">{material.quantity}</td>
                      <td className="py-2 text-right">
                        {formatCurrencyFromMinorUnits(material.rate, 'en-US', material.currency_code)}
                      </td>
                      <td className="py-2 text-right font-medium">
                        {formatCurrencyFromMinorUnits(calculateTotal(material), 'en-US', material.currency_code)}
                      </td>
                      <td className="py-2 text-center">
                        {material.is_billed ? (
                          <Badge variant="default">{materialsT('billed', 'Billed')}</Badge>
                        ) : (
                          <Badge variant="outline">{materialsT('pending', 'Pending')}</Badge>
                        )}
                      </td>
                      <td className="py-2 text-right">
                        {!material.is_billed && (
                          <Button
                            {...withDataAutomationId({ id: `${id}-delete-${material.project_material_id}` })}
                            variant="ghost"
                            size="sm"
                            onClick={() => handleDeleteMaterial(material.project_material_id)}
                            disabled={deletingId === material.project_material_id}
                            className="text-destructive hover:text-destructive hover:bg-destructive/10 p-1 h-auto"
                          >
                            {deletingId === material.project_material_id ? (
                              <Loader2 className="w-4 h-4 animate-spin" />
                            ) : (
                              <Trash2 className="w-4 h-4" />
                            )}
                          </Button>
                        )}
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            {Object.keys(unbilledByCurrency).length > 0 && (
              <div className="flex justify-end pt-2 border-t">
                <div className="text-sm space-y-1">
                  {Object.entries(unbilledByCurrency).map(([currency, total]) => (
                    <div key={currency} className="text-right">
                      <span className="text-gray-500">{materialsT('unbilledTotal', 'Unbilled ({{currency}}): ', { currency })}</span>
                      <span className="font-semibold">
                        {formatCurrencyFromMinorUnits(total, 'en-US', currency)}
                      </span>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>
        )}

        {!clientId && (
          <div className="text-center py-4 text-amber-600 text-sm">
            {materialsT('noClientAssigned', 'A client must be assigned to this project before materials can be added.')}
          </div>
        )}
      </div>
    </ReflectionContainer>
  );
}
