"use client";

import React, { useEffect, useState } from "react";
import Link from "next/link";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { getApiErrorMessage } from "@/lib/api-error";
import { uploadTenantImageFile } from "@/lib/upload-tenant-image";
import {
  useCreateTenantPropertyMutation,
  useUpdateTenantPropertyMutation,
} from "@/redux/api";
import { toast } from "sonner";
import type { ClientWorkspaceChildCtx } from "@/features/client/client-workspace-layout";
import type { PropertyRow } from "@/features/client/property-types";

const PROPERTY_USAGE_TYPES = ["commercial", "residential", "mixed", "other"] as const;
const SITE_TYPES = ["plaza", "town", "society", "other"] as const;

type PropertyUsage = (typeof PROPERTY_USAGE_TYPES)[number];
type SiteKind = (typeof SITE_TYPES)[number];

const emptyBasic = {
  name: "",
  type: "commercial" as PropertyUsage,
  siteType: "other" as SiteKind,
  street: "",
  city: "",
  area: "",
};

type Props = {
  ctx: ClientWorkspaceChildCtx;
  editing: PropertyRow | null;
  /** List URL for “Back to properties” (e.g. `/client/properties`). */
  listHref: string;
  /** Optional dedicated page URL for editing phases/floors and units. */
  layoutEditorHref?: string;
  /** In layout-only mode, the form only edits phases/floors & units. */
  mode?: "default" | "layout-only";
  onCancel: () => void;
  onSaved: () => void;
};

export default function PropertyEditorForm({
  ctx,
  editing,
  listHref,
  layoutEditorHref,
  mode = "default",
  onCancel,
  onSaved,
}: Props) {
  const { tenantApiKey, tenantReady, isSuperAdmin } = ctx;
  const [basic, setBasic] = useState(emptyBasic);
  const [createTenantProperty] = useCreateTenantPropertyMutation();
  const [updateTenantProperty] = useUpdateTenantPropertyMutation();
  const [saving, setSaving] = useState(false);
  const [coverPhoto, setCoverPhoto] = useState("");
  const [coverUploading, setCoverUploading] = useState(false);

  const needsLayoutPage =
    basic.siteType === "plaza" || basic.siteType === "town" || basic.siteType === "society";

  const mergeImportedUnitsForFloor = useCallback((floorIndex: number, imported: UnitDraft[]) => {
    if (imported.length === 0) return;
    setFloors((prev) =>
      prev.map((f, i) => {
        if (i !== floorIndex) return f;
        const onlyBlankPlaceholder =
          f.units.length === 1 && !f.units[0].unitNumber.trim();
        return {
          ...f,
          units: onlyBlankPlaceholder ? imported : [...f.units, ...imported],
        };
      })
    );
  }, []);

  const onUnitsCsvSelected = useCallback(
    async (file: File, floorIndex: number) => {
      try {
        const text = await file.text();
        const rows = parseCsvToRows(text);
        const { units, warnings } = rowsToImportedUnits(rows, teamUsers as TenantUserOpt[]);
        if (units.length === 0) {
          toast.error(warnings[0] || "Nothing imported");
          return;
        }
        mergeImportedUnitsForFloor(floorIndex, units);
        toast.success(
          `Imported ${units.length} unit(s) into this ${isTown ? "phase" : "floor"} — click Save to persist`
        );
        if (warnings.length) {
          toast.warning(warnings.slice(0, 8).join(" · "));
        }
      } catch (e: unknown) {
        toast.error(getApiErrorMessage(e, "Could not import CSV"));
      }
    },
    [mergeImportedUnitsForFloor, teamUsers, isTown]
  );

  const onStructuresCsvSelected = useCallback(
    async (file: File) => {
      try {
        const text = await file.text();
        const rows = parseCsvToRows(text);
        const { structures, warnings } = rowsToImportedPhasesOrFloors(rows);
        if (structures.length === 0) {
          toast.error(warnings[0] || "Nothing imported");
          return;
        }
        setFloors((prev) => [...prev, ...structures]);
        toast.success(
          `Imported ${structures.length} ${isTown ? "phase(s)" : "floor(s)"} — click Save to persist`
        );
        if (warnings.length) toast.warning(warnings.slice(0, 8).join(" · "));
      } catch (e: unknown) {
        toast.error(getApiErrorMessage(e, "Could not import CSV"));
      }
    },
    [isTown]
  );

  useEffect(() => {
    if (!editing) {
      setBasic(emptyBasic);
      setCoverPhoto("");
      return;
    }
    const rawType = editing.type || "";
    const usageType: PropertyUsage = PROPERTY_USAGE_TYPES.includes(rawType as PropertyUsage)
      ? (rawType as PropertyUsage)
      : "commercial";
    const siteTypeResolved: SiteKind =
      editing.siteType && SITE_TYPES.includes(editing.siteType as SiteKind)
        ? (editing.siteType as SiteKind)
        : rawType === "plaza"
          ? "plaza"
          : "other";

    setBasic({
      name: editing.name,
      type: usageType,
      siteType: siteTypeResolved,
      street: editing.address?.street || "",
      city: editing.address?.city || "",
      area: editing.address?.area || "",
    });
    setCoverPhoto(editing.photo?.trim() || "");
  }, [editing]);

  const save = async () => {
    if (!tenantReady) {
      toast.error("Workspace not ready");
      return;
    }
    if (!layoutOnly && !basic.name.trim()) {
      toast.error("Property name is required");
      return;
    }

    setSaving(true);
    try {
      const body = {
        name: basic.name.trim(),
        type: basic.type,
        siteType: basic.siteType,
        address: {
          street: basic.street.trim(),
          city: basic.city.trim(),
          area: basic.area.trim(),
        },
        photo: coverPhoto.trim(),
      };

      if (editing) {
        await updateTenantProperty({
          tenantKey: tenantApiKey,
          propertyId: editing._id,
          body,
        }).unwrap();
        toast.success("Property updated");
      } else {
        await createTenantProperty({
          tenantKey: tenantApiKey,
          body: {
            ...body,
            maintenanceChargeMode: "fixed",
            maintenanceChargeValue: 0,
          },
        }).unwrap();
        toast.success("Property created");
      }

      onSaved();
    } catch (e: unknown) {
      toast.error(getApiErrorMessage(e, "Could not save property"));
    } finally {
      setSaving(false);
    }
  };

  return (
    <div className="min-w-0 overflow-hidden rounded-md border bg-white">
      <input
        ref={csvInputRef}
        type="file"
        accept=".csv,text/csv"
        className="hidden"
        aria-hidden
        onChange={(e) => {
          const file = e.target.files?.[0];
          e.target.value = "";
          const idx = csvImportFloorIndexRef.current;
          csvImportFloorIndexRef.current = null;
          if (!file || idx === null) return;
          void onUnitsCsvSelected(file, idx);
        }}
      />
      <input
        ref={structuresCsvInputRef}
        type="file"
        accept=".csv,text/csv"
        className="hidden"
        aria-hidden
        onChange={(e) => {
          const file = e.target.files?.[0];
          e.target.value = "";
          if (!file) return;
          void onStructuresCsvSelected(file);
        }}
      />
      <div className="border-b px-4 py-2 sm:px-6">
        <Button variant="link" className="h-auto p-0 text-sm font-normal" asChild>
          <Link href={listHref}>← Back to properties</Link>
        </Button>
      </div>

      <div className="overflow-x-hidden px-4 py-3 sm:px-6 sm:py-4">
        {isSuperAdmin && !editing && (
          <p className="mb-4 text-xs text-gray-500">
            Property is created for the client selected in the bar above.
          </p>
        )}
        {!isSuperAdmin && (
          <p className="mb-4 rounded-md bg-gray-50 p-2 text-xs text-gray-600">
            {editing ? "Editing" : "Creating"} a property for your organization.
          </p>
        )}

        <div className="space-y-4">
          <div className="grid gap-2">
            <Label htmlFor="pe-name">Property name</Label>
            <Input
              id="pe-name"
              value={basic.name}
              onChange={(e) => setBasic({ ...basic, name: e.target.value })}
            />
          </div>
          <div className="grid gap-2">
            <Label>Usage</Label>
            <Select
              value={basic.type}
              onValueChange={(v) => setBasic({ ...basic, type: v as PropertyUsage })}
            >
              <SelectTrigger className="min-w-0 max-w-full">
                <SelectValue className="truncate" />
              </SelectTrigger>
              <SelectContent>
                {PROPERTY_USAGE_TYPES.map((t) => (
                  <SelectItem key={t} value={t} className="text-left text-sm">
                    {t.charAt(0).toUpperCase() + t.slice(1)}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="grid gap-2">
            <Label>Site layout</Label>
            <Select
              value={basic.siteType}
              onValueChange={(v) => setBasic({ ...basic, siteType: v as SiteKind })}
            >
              <SelectTrigger className="min-w-0 max-w-full">
                <SelectValue className="truncate" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="plaza" className="text-left text-sm">
                  Plaza (floors & units)
                </SelectItem>
                <SelectItem value="town" className="text-left text-sm">
                  Town (blocks & plots)
                </SelectItem>
                <SelectItem value="society" className="text-left text-sm">
                  Society (floors & units)
                </SelectItem>
                <SelectItem value="other" className="text-left text-sm">
                  Other
                </SelectItem>
              </SelectContent>
            </Select>
          </div>
          <div className="grid gap-2">
            <Label htmlFor="pe-street">Address</Label>
            <Input
              id="pe-street"
              placeholder="Street, building, unit…"
              value={basic.street}
              onChange={(e) => setBasic({ ...basic, street: e.target.value })}
            />
          </div>
          <div className="grid gap-2">
            <Label>Property photo</Label>
            <div className="flex flex-col gap-2 sm:flex-row sm:items-center">
              {coverPhoto ? (
                // eslint-disable-next-line @next/next/no-img-element -- API URL, not bundled asset
                <img
                  src={coverPhoto}
                  alt=""
                  className="h-24 max-w-[200px] rounded-md border border-gray-200 object-cover"
                />
              ) : (
                <span className="text-xs text-gray-500">No image yet</span>
              )}
              <div className="flex flex-wrap items-center gap-2">
                <Input
                  type="file"
                  accept="image/png,image/jpeg,image/jpg,image/webp,image/gif"
                  className="max-w-full cursor-pointer text-sm file:mr-2"
                  disabled={coverUploading || !tenantReady}
                  onChange={(e) => {
                    const f = e.target.files?.[0];
                    e.target.value = "";
                    if (!f || !tenantReady) return;
                    setCoverUploading(true);
                    void (async () => {
                      try {
                        const url = await uploadTenantImageFile(tenantApiKey, f);
                        setCoverPhoto(url);
                        toast.success("Photo uploaded");
                      } catch (err: unknown) {
                        toast.error(getApiErrorMessage(err, "Could not upload photo"));
                      } finally {
                        setCoverUploading(false);
                      }
                    })();
                  }}
                />
                {coverPhoto ? (
                  <Button
                    type="button"
                    variant="outline"
                    size="sm"
                    disabled={coverUploading}
                    onClick={() => setCoverPhoto("")}
                  >
                    Remove
                  </Button>
                ) : null}
              </div>
            </div>
            {coverUploading ? <p className="text-xs text-gray-500">Uploading…</p> : null}
          </div>
          <div className="grid gap-2 sm:grid-cols-2">
            <div>
              <Label htmlFor="pe-city">City</Label>
              <Input
                id="pe-city"
                value={basic.city}
                onChange={(e) => setBasic({ ...basic, city: e.target.value })}
              />
            </div>
            <div>
              <Label htmlFor="pe-area">Area</Label>
              <Input
                id="pe-area"
                value={basic.area}
                onChange={(e) => setBasic({ ...basic, area: e.target.value })}
              />
            </div>
          </div>

          {needsLayoutPage && editing ? (
            <p className="rounded-md border border-blue-100 bg-blue-50 p-3 text-xs leading-relaxed text-blue-900 sm:text-sm">
              Edit floors, units, blocks, or plots from the properties list: open{" "}
              <strong>More details</strong> for this property.
            </p>
          ) : null}
          {needsLayoutPage && !editing ? (
            <p className="rounded-md border border-blue-100 bg-blue-50 p-3 text-xs leading-relaxed text-blue-900 sm:text-sm">
              After you create this property, use <strong>More details</strong> on the properties
              list to add floors, units, blocks, or plots.
            </p>
          ) : null}
        </div>
      </div>

      <div className="flex flex-col gap-2 border-t px-4 py-3 sm:flex-row sm:flex-wrap sm:px-6 sm:py-4">
        <Button
          variant="outline"
          className="w-full sm:w-auto"
          type="button"
          onClick={onCancel}
          disabled={saving}
        >
          Cancel
        </Button>
        <Button
          type="button"
          className="w-full sm:w-auto"
          onClick={() => void save()}
          disabled={saving || !tenantReady || !basic.name.trim()}
        >
          {saving ? "Saving…" : editing ? "Save" : "Create"}
        </Button>
      </div>
    </div>
  );
}
