-- FUNCTION: public.udf_fetchProviderAvailabilityDatesNew(integer, integer, integer, text, text)

-- DROP FUNCTION IF EXISTS public."udf_fetchProviderAvailabilityDatesNew"(integer, integer, integer, text, text);

CREATE OR REPLACE FUNCTION public."udf_fetchProviderAvailabilityDatesNew"(
	providerid integer,
	locationid integer,
	specializationid integer,
	startdate text,
	enddate text)
    RETURNS TABLE("Date" date, "DateNumber" integer, "DayName" character varying, "Status" character) 
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE PARALLEL UNSAFE
    ROWS 1000

AS $BODY$
begin
return query
with TotalDates as (
SELECT DISTINCT generate_series( startDate::date,endDate::date, '1 day')::date "Dates" ,
	--generate_series(timestamp '2022-10-31', '2023-03-16', '1 day')::date AS "Dates",
	--generate_series(timestamp A."StartDate", A."EndDate", '1 day')::date AS "Dates",
	A."ProviderId",A."ProviderAvailabilityId",A."LocationId", A."StartDate", A."EndDate", A."LocationId", S."SpecializationId"
from "ProviderAvailability" A 
JOIN "Location" PL ON A."LocationId" = PL."LocationId" AND PL."Active" = TRUE
JOIN "Provider" PR on A."ProviderId" = PR."ProviderId" AND PR."Active" = TRUE
JOIN "Specialization" S on S."SpecializationId" = ANY(PR."Specializations") AND S."Active" IS TRUE
--JOIN "Practice" P ON P."PracticeId" = PL."PracticeId" AND P."Active" = TRUE
where A."ProviderId"=providerid AND A."LocationId" = locationId And S."SpecializationId" = specializationId And A."Active" IS TRUE

)
,Availability as (
select A."FreeFollowUpDays", A."AvailableDay", A."ProviderAvailabilityId"
	--A."ProviderId"
	--,A."ProviderLocationId"
	,A."LocationId", A."StartDate", A."EndDate", S."SpecializationId"
	--,json_array_elements(case when (A."Availability" is null or A."Availability"='') then '[]' else (A."Availability"::json)end) "Availability"
from "ProviderAvailability" A 
	--left join "ProviderAvailabilitySlot" PAS on PAS."ProviderAvailabilityId" = A."ProviderAvailabilityId"
	JOIN "Location" PL ON A."LocationId" = PL."LocationId" AND PL."Active" = TRUE
	JOIN "Provider" PR on A."ProviderId" = PR."ProviderId" AND PR."Active" = TRUE
	JOIN "Specialization" S on S."SpecializationId" = ANY(PR."Specializations") AND S."Active" IS TRUE
--JOIN "Location" PL ON A."LocationId" = PL."LocationId" AND PL."Active" = TRUE
--JOIN "Practice" P ON P."PracticeId" = PL."PracticeId" AND P."Active" = TRUE
	where A."ProviderId"=providerid AND A."LocationId" = locationId And S."SpecializationId" = specializationId And A."Active" IS TRUE 
	--and case when providerLocationId is null then 1=1 else A."ProviderLocationId"=providerLocationId end
)
,Avail as (
SELECT unnest(string_to_array(A."AvailableDay", ',')) AS "Day", A."ProviderAvailabilityId",A."LocationId", A."StartDate", A."EndDate", A."SpecializationId"
from Availability A
)

, LeaveAvailability as (
select A."ProviderId",A."LeaveDate",coalesce(A."ProviderAvailabilityId"::text,
(
	select string_agg(D."ProviderAvailabilityId"::text,',') "ProviderAvailabilityId" from "ProviderAvailability" D where D."ProviderId"= providerid and D."LocationId" = locationId
))
	"ProviderAvailabilityId" from "ProviderLeave" A where A."ProviderId"=providerid and A."LocationId" = locationId
)
,LeaveData as (
select A."ProviderId",A."LeaveDate",regexp_split_to_table(A."ProviderAvailabilityId",',') ::int "ProviderAvailabilityId" 
	from LeaveAvailability A
)

,FinalData as (
select DISTINCT C."LeaveDate", A."Dates" "Date", A."ProviderId",A."ProviderAvailabilityId",A."StartDate",A."EndDate"
	--,A."LocationId"
	,extract(ISODOW from "Dates")"DateNo", CASE
WHEN extract(ISODOW from "Dates") =1 THEN 'Monday'
WHEN extract(ISODOW from "Dates") =2 THEN 'Tuesday'
WHEN extract(ISODOW from "Dates")=3 THEN 'Wednesday'
WHEN extract(ISODOW from "Dates")=4 THEN 'Thursday'
WHEN extract(ISODOW from "Dates")=5 THEN 'Friday'
WHEN extract(ISODOW from "Dates")=6 THEN 'Saturday'
WHEN extract(ISODOW from "Dates")=7 THEN 'Sunday' end "Day" ,
case when C."LeaveDate" is not null then 'L' when B."Day" is not null then 'A' else '' end "Status"
from TotalDates A
left join Avail B on B."Day"::text::int = extract(ISODOW from A."Dates") and A."ProviderId"=A."ProviderId" and A."ProviderAvailabilityId"=B."ProviderAvailabilityId"
--and A."LocationId"=B."LocationId"
left join LeaveData C on C."LeaveDate"::date =A."Dates" and A."ProviderAvailabilityId"=C."ProviderAvailabilityId"

)

select DISTINCT A."Date",A."DateNo"::int,A."Day"::text::character varying(10),A."Status"::char
from FinalData A
where  
--A."Date"  >= A."StartDate"::Date or 
A."Date" <= A."EndDate"::Date 
order by A."Date";
end

$BODY$;

ALTER FUNCTION public."udf_fetchProviderAvailabilityDatesNew"(integer, integer, integer, text, text)
    OWNER TO postgres;
